• Aucun résultat trouvé

Correction partiel de Programmation Modulaire

N/A
N/A
Protected

Academic year: 2022

Partager "Correction partiel de Programmation Modulaire"

Copied!
5
0
0

Texte intégral

(1)

Nom : Prénom : No étudiant :

Correction partiel de Programmation Modulaire

—Licence MI/IM/MNSI - Info 3—

Aucun document n’est autorisé à part la fiche résumé deC++, où vous pouviez consigner des notes manuscrites personnelles au verso. Tous les exercices sont indépendants. Même si l’on ne sait pas répondre à une question, on peut utiliser la réponse dans la suite de l’exercice.

Une grande importance sera accordée à la qualité de la rédaction (lisibilité, indentation,...).

Le barème est indicatif et pourra changer à la correction.

Durée : 2h00.

xExercice 1. (Question de cours) – sur 4 points –

1. Que peut-on faire comme opérations sur une variable de typestructsi l’on n’a surchargé aucun opérateur ?

- l’affectation de deux structures,

- l’accès à un champs par notation pointée, - le calcul de l’adresse (réponse non exigée).

2. Déclarer un type énuméré pour représenter les saisons (printemps été automne hiver).

enum struct Saison {printemps, ete, automne, hiver};

// Alternative

// enum class Saison {printemps, ete, automne, hiver};

3. On veut écrire une fonction suivante qui reçoit en paramètre une saison et qui retourne la saison suivante. On demande d’écriredeux fonctions, l’une utilisant l’instructionswitch, l’autre le codage des types énumérés avec les entiers.

Saison suivante(Saison s) { return Saison((int(s) + 1) % 4);

}

Saison suivanteSwitch(Saison s) { switch(s) {

case Saison::printemps : return Saison::ete;

case Saison::ete : return Saison::automne;

case Saison::automne : return Saison::hiver;

case Saison::hiver : return Saison::printemps;

} }

(2)

Le poker est un jeu de cartes qui se pratique à plusieurs joueurs avec un jeu généralement de cinquante-deux cartes et des jetons représentant les sommes misées. Le but du jeu est de remporter les jetons des adversaires en constituant la meilleure combinaison de cinq cartes ou en leur faisant abandonner le coup. Le poker est un jeu dont la structure impose la plupart du temps que le joueur débute avec une réserve de jetons de départ. Le tapis représente le nombre de jetons d’un joueur donné, sujet aux fluctuations des gains et des pertes. Dans la variante modélisé ici, chaque joueur à exactement 5 cartes.

On utilisera donc les déclarations suivantes pour représenter les cartes et joueurs : enum class Couleur {pique, coeur, carreau, trefle};

enum class Valeur { v2, v3, v4, v5, v6, v7, v8, v9, v10, Valet, Dame, Roi, As};

struct Carte { Couleur coul;

Valeur val;

};

struct Joueur {

string nom; // Nom du joueur

int tapis; // Nombre de jetons du joueur array<Carte, 5> main; // les 5 cartes du joueur };

On vous donne par ailleurs les initialisations suivantes que vous pouvez utiliser pour les tests : Joueur J1 = { "Joe", 15, {{ {Couleur::pique, Valeur::As}, ... }} };

Joueur J2 = { "William", 54, {{ ... }}};

Joueur J3 = { "Jack", 0, {{ ... }}};

Enfin, on rappelle ci-après quelques opérations applicables à un vecteur v :

— v.size(); retourne la taille de v

— v.push_back(c); ajoute c à la fin de v

— c = v.back(); c reçoit la valeur à la fin de v (sans modifier v)

— v.pop_back(); supprime la dernière case de v

1. Écrire une fonctionbool estEnJeu(Joueur j) qui retourne trueoufalse selon que le joueur ja encore des jetons ou non.

bool estEnJeu(Joueur j) { return j.tapis > 0;

}

2. Écrire une fonction bool mise(Joueur &j, int nb)qui effectue une mise : on retirenbjetons du tapis du joueurj, si le tapis le permet. Cette fonction retournetrueoufalseselon que cette mise est possible ou non.

bool mise(Joueur& j, int nb) { if (nb <= j.tapis) {

j.tapis -= nb;

return true;

}

return false;

}

3. Proposer avec l’infrastructuredoctestun cas de test comportant plusieurs tests pour la fonction mise. On fera attention à bien tester tous les aspects de la fonction.

TEST_CASE("mise") { Joueur j;

j = J1; CHECK(mise(j, 10)); CHECK(j.tapis == 5);

j = J1; CHECK_FALSE(mise(j, 40)); CHECK(j.tapis == 15);

j = J2; CHECK(mise(j, 40)); CHECK(j.tapis == 14);

j = J2; CHECK(mise(j, 54)); CHECK(j.tapis == 0);

}

(3)

Nom : Prénom :

int nbCarteValeur(Joueur j, Valeur v) { int res = 0;

for (int i=0; i < 5; i++) if (j.main[i].val == v) res++;

return res;

}

5. Écrire une fonction bool carre(Joueur j) qui retourne true oufalse selon que la main du joueurjcomporte exactement 4 cartes de la même valeur ou non.

bool carre(Joueur j) { for (int i=0; i<13; i++) {

Valeur v = Valeur(i);

if (nbCarteValeur(j, v) == 4) return true;

}

return false;

}

6. Définir la structure Tablepour représenter la table de jeu, qui comporte les champs suivants :

— potqui indique le nombre de jetons sur la table ;

— joueurs qui contient les joueurs qui participent au jeu et dont le nombre peut évoluer au cours de la partie ;

— donnequi contient les cartes qui n’ont pas encore été distribuées.

struct Table { int pot;

vector<Joueur> joueurs;

vector<Carte> donne;

};

7. Écrire une procédure void miseInitiale(Table &t) qui réalise la première mise : tous les joueurs autour de la table qui le peuvent, prennent10jetons dans leur tapis et les mettent dans le pot. Vous devez utiliser la fonction miseécrite précédemment.

const int nbMiseInitiale = 10;

void miseInitiale(Table &t) { t.pot = 0;

for (int i=0; i < t.joueurs.size(); i++) { if (mise(t.joueurs[i], nbMiseInitiale))

t.pot += nbMiseInitiale;

} }

8. Écrire une procédure void distribue(Table &t) qui distribue 5 cartes à chaque joueur de la table t: les cartes doivent être prises à la fin de la donne ; on donne d’abord une carte à chaque joueur avant d’en donner une deuxième. . .

void distribue(Table &t) { for (int i=0; i < 5; i++) {

for (int j=0; j < t.joueurs.size(); j++) { Carte c = t.donne.back();

t.donne.pop_back();

t.joueurs[j].main[i] = c;

} } }

(4)

On souhaite créer un type de données pour représenter des nombres réels avec 3 chiffres significatifs.

Par exemple, 312, 4210000, 3.14, 2.00, 0.0301 sont tous des nombres avec trois chiffres significatifs.

En revanche, 42310 et 0.04235 ont chacun quatre chiffres significatifs. Pour ceci, ces nombres seront représentés par un nombre entier nommémantissecomportant exactement 3 chiffres (donc entre100et 999) multiplié par une puissance de dix : voici quelques exemples :312 = 312×100,4210000 = 421×104, 3.14 = 314×10−2,2.00 = 200×10−2,0.0301 = 301×10−4. La représentation d’un tel nombre sera dite normalisée.

On ne représentera que desnombres positifs.

Enfin, le nombre 0 est une exception, car il ne peut pas être représenté avec une mantisse à trois chiffres significatifs. On le représentera par une mantisse et un exposant nuls. On utilisera donc les déclarations suivantes :

struct Reel {

int mant; // mantisse entre 100 et 999, ou 0 int exp; // exposant de la puissance de 10 };

const Reel zero = {0, 0}; // 0.00 const Reel pi = {314, -2}; // 3.14

1. Écrire une fonctionestNormalisequi prend en paramètre un réelret qui renvoietrueoufalse selon que rest normalisé où non. Par exemple, le réel{3140, -3}n’est pas normalisé.

bool estNormalise(Reel r) { if (r.mant == 0)

return r.exp == 0;

return 100 <= r.mant and r.mant < 1000;

}

Dans toute la suite de ce problème, quand une fonction ou un opérateur reçoit un Reel, on pourra supposer qu’il est normalisé. De plus, quand une fonction ou un opérateur renvoie un Reel, il doit toujours être normalisé.

2. Surcharger l’opérateur <<pour le typeReel. Le nombre{0, 0}devra être affiché par «0» et le nombre{421, 4}devra être affiché par «421x10^4»

std::ostream &operator<<(std::ostream &out, Reel r) { if (r.mant == 0)

out << 0;

else

out << r.mant << "x10^" << r.exp;

return out;

}

3. Surcharger l’opérateur <=pour le typeReel.

bool operator<=(Reel a, Reel b) { if (a == zero) return true;

if (b == zero) return a == zero;

if (a.exp != b.exp) return a.exp < b.exp;

else

return a.mant <= b.mant;

}

4. Écrire 4tests pour l’opérateur<=.

!

(5)

Nom : Prénom :

CHECK(Reel{123, 1} <= Reel{123, 1});

CHECK(zero <= Reel{142, 4});

CHECK_FALSE(Reel{142, 4} <= zero);

CHECK(Reel{142, 4} <= Reel{242, 4});

CHECK_FALSE(Reel{242, 4} <= Reel{142, 4});

5. Écrire une fonctionReel normalise(int m, int e);qui retourne la représentation correcte du nombrem×10e. En normalisant, on peut perdre certains chiffres si l’utilisateur en a trop donné.

Ainsi, les tests suivants devront passer : CHECK(normalise(0, 10) == zero);

CHECK(normalise(31, 2) == Reel {310, 1});

CHECK(normalise(31430, 0) == Reel {314, 2});

Reel normalise(int m, int e) { Reel r = {m, e};

if (r.mant == 0) { r.exp = 0; return r;

}

while (r.mant > 999) { r.mant = r.mant / 10;

r.exp += 1;

}

while (r.mant < 100) { r.mant = r.mant * 10;

r.exp -= 1;

}

return r;

}

6. Surcharger l’opérateur*pour le typeReel. On rappelle que la fonction doit renvoyer un nombre normalisé. Pour ceci, on pourra utiliser la fonctionnormalise.

Reel operator*(Reel a, Reel b) {

return normalise(a.mant * b.mant, a.exp + b.exp);

}

7. Surcharger l’opérateur +pour le typeReel. On prendra garde au cas particulier du nombre0.

Reel operator+(Reel a, Reel b) { if (a == zero) return b;

if (b == zero) return a;

while (b.exp < a.exp) { b.mant = b.mant / 10;

b.exp += 1;

}

while (a.exp < b.exp) { a.mant = a.mant / 10;

a.exp += 1;

}

return normalise(a.mant + b.mant, a.exp);

}

Références

Documents relatifs

À chaque fois qu'on appuiera sur un bouton, quel qu'il soit, on rentrera dans la même méthode, et on exécutera donc le même code… C'est pas très pratique, si nous avons un

Pour ce faire, on attribue à chaque adhérent un numéro d’adhérent auquel on associe son nom, son adresse, ainsi que la liste des exemplaires empruntés, avec pour chaque exemplaire,

En Suisse, notre cadre légal stipule que le MPR peut prescrire six à douze séances de consultation diététique, prises en charge par l’assurance dans le cadre de sept

Immunisée : vaccinée à 2 doses ou antécédents documentés de rougeole Réceptive : pas d’antécédent documenté de vaccination ou de rougeole.. Risque de

Dépenses de consommation (novembre) – La croissance de la consommation réelle a causé la surprise en octobre avec un gain de 0,7 %, alors que la hausse des prix a été très vive..

Certains dangers représentent un réel risque pour la santé des professionnels, tant par leur fréquence que par leur gravité, alors que certains seront minimes et ne seront

Faire connaître le PAT et ses actions aux acteurs économiques locaux (enjeux et besoins identifiés sur le territoire, plans d’actions envisagés). Pour initier les

Pour décrire la façon dont l’eau peut s’écouler à l’intérieur d’un filtre de café, au sein d’une roche poreuse ou pour comprendre comment se propage une maladie