Jeux Libres
       
           

» Les Tutoriels » Apprenez à programmer en C++ ! » [TP] Le mot mystère

Note : Vous vous apprêtez à lire un tutoriel de M@teo21 et Nanoc initialement publié à cette adresse sous la licence Creative Commons BY-NC-SA 2.0.

[TP] Le mot mystère


Depuis le début de ce cours sur le C++, vous avez découvert de nombreuses notions : le compilateur, l'IDE, les variables, les fonctions, les conditions, les boucles... Vous avez pu voir des exemples d'utilisation de ces notions au fur et à mesure, mais est-ce que vous avez pris le temps de créer un vrai programme pour vous entraîner ? Non ? Eh bien c'est le moment de s'y mettre !

On trouve régulièrement des TP au milieu des cours du Site du Zéro. Celui-ci ne fait pas exception.
Le but ? Vous forcer à vous lancer "pour de vrai" dans la programmation. Parce que je sais bien qu'il y en a beaucoup parmi vous qui ont à peine ouvert leur IDE pour le moment, ce TP est l'occasion de vous y mettre vraiment. ;)

Le sujet de ce TP n'est pas très compliqué mais promet d'être amusant : nous allons mélanger les lettres d'un mot et demander à un joueur de retrouver le mot "mystère" qui se cache derrière ces lettres. :)






Chapitre précédent     Sommaire     Chapitre suivant


Préparatifs et conseils


Le jeu que nous voulons réaliser consiste à retrouver un mot dont les lettres ont été mélangées. C'est simple en apparence, mais il va nous falloir utiliser des notions que nous avons découvertes dans les chapitres précédents :

  • Les variables string
  • Les fonctions
  • Les structures de contrôle (boucles, conditions...)

N'hésitez pas à relire rapidement ces chapitres pour bien être dans le bain avant de commencer ce TP !

Principe du jeu "Le mot mystère"



Nous voulons réaliser un jeu qui se déroule de la façon suivante :

  • Le joueur 1 saisit un mot au clavier
  • L'ordinateur mélange les lettres du mot
  • Le joueur 2 essaie de deviner le mot d'origine à partir des lettres mélangées

Voici un exemple de partie du jeu que nous allons réaliser :
Saisissez un mot
MYSTERE

Quel est ce mot ? MSERETY
RESEMTY
Ce n'est pas le mot !

Quel est ce mot ? MSERETY
MYRESTE
Ce n'est pas le mot !

Quel est ce mot ? MSERETY
MYSTERE
Bravo !

  • Dans cette partie, le joueur 1 choisit "MYSTERE" comme mot à deviner.
  • L'ordinateur mélange les lettres et demande au joueur 2 de retrouver le mot qui se cache derrière "MSERETY".
  • Le joueur 2 essaie de trouver le mot. Ici, il y parvient au bout de 3 essais :
            1. RESEMTY : on lui dit que ce n'est pas ça
            2. MYRESTE : là non plus
            3. MYSTERE : là on lui dit bravo car il a trouvé, et le programme s'arrête. :)

Bien sûr, le joueur 2 peut actuellement facilement lire le mot saisi par le joueur 1. Nous verrons à la fin du TP comment nous pouvons améliorer ça.

Quelques conseils pour bien démarrer



Quand on lâche un débutant dans la nature la première fois, avec comme seule instruction "Allez, code-moi ça", il est en général assez désemparé.
"Par quoi dois-je commencer ?", "Qu'est-ce que je dois faire, qu'est-ce que je dois utiliser ?". Bref, il ne sait pas du tout s'y prendre, et c'est bien normal vu qu'il n'a jamais fait ça. ;)

Mais moi, je n'ai pas envie que vous vous perdiez ! Je vais donc vous donner une série de conseils pour que vous soyez le mieux préparés possible. Bien entendu, ce sont juste des conseils, vous en faites ce que vous voulez. :-°

Repérez les étapes du programme



Je vous ai décrit les 3 étapes du programme un peu plus tôt :

  • Saisie du mot à deviner
  • Mélange des lettres
  • Boucle qui se répète tant que le mot mystère n'a pas été trouvé

Ces étapes sont en fait assez indépendantes. Plutôt que d'essayer de réaliser tout le programme d'un coup, pourquoi vous n'essayez pas de faire chaque étape indépendamment des autres ?

  • L'étape 1 est très simple : l'utilisateur doit saisir un mot qu'on va stocker en mémoire (dans une string, car c'est le type adapté). Si vous connaissez cout et cin, vous ne mettrez pas plus de quelques minutes à écrire le code correspondant.
  • L'étape 2 est la plus complexe : vous avez une string qui contient un mot comme MYSTERE et vous voulez aléatoirement mélanger les lettres pour obtenir quelque chose comme MSERETY. Comment faire ? Je vais vous aider un peu pour ça car vous devez utiliser certaines choses que nous n'avons pas vues.
  • L'étape 3 est de difficulté moyenne : vous devez créer une boucle qui demande de saisir un mot et qui le compare au mot mystère. La boucle s'arrête dès que le mot saisi est identique au mot mystère.

Créez un canevas de code avec les étapes



Comme vous le savez, tous les programmes contiennent une fonction main(). Ecrivez dès maintenant des commentaires pour séparer les principales étapes du programme. Ca devrait donner quelque chose comme ça :
1
2
3
4
5
6
7
8
9
10
int main()
{    
   // 1 : On demande saisir un mot
 
   // 2 : On mlange les lettres du mot
 
   // 3 : On demande l'utilisateur quel est le mot mystre
 
   return 0;
}

A vous de réaliser les étapes ! Pour y aller en difficulté croissante, je vous conseille de faire d'abord l'étape 1, puis l'étape 3 et enfin l'étape 2.

Lorsque vous aurez réalisé les étapes 1 et 3, le programme vous demandera un mot et vous devrez le ressaisir. Ce ne sera pas très amusant mais comme ça vous pourrez valider que vous avez réussi les premières étapes ! N'hésitez donc pas à y aller pas à pas !

Ci-dessous un aperçu du programme "intermédiaire" avec seulement les étapes 1 et 3 réalisées :
Saisissez un mot
MYSTERE

Quel est ce mot ?
RESEMTY
Ce n'est pas le mot !

Quel est ce mot ?
MYRESTE
Ce n'est pas le mot !

Quel est ce mot ?
MYSTERE
Bravo !

Comme vous le voyez, le programme ne propose pas encore le mot avec les lettres mélangées, mais si vous arrivez déjà à faire ça vous avez fait 50% du travail ! :)

Un peu d'aide pour mélanger les lettres



L'étape de mélange des lettres est la plus "difficile" (si je puis dire !) de ce TP. Je vous donne quelques informations et conseils pour réaliser cette fameuse étape n°2.

Tirer un nombre au hasard



Pour que les lettres soient aléatoirement mélangées, vous allez devoir tirer un nombre au hasard. Nous n'avons pas appris à le faire auparavant, il faut donc que je vous explique comment ça fonctionne.

  • Vous devez inclure ctime et cstdlib au début de votre code source pour obtenir les fonctionnalités de nombres aléatoires.
  • Vous devez appeler la fonction srand(time(0)); une seule fois au début de votre programme (au début du main) pour initialiser la génération des nombres aléatoires.
  • Et enfin, pour générer un nombre compris entre 0 et 4 (par exemple), vous écrirez : nbAleatoire = rand() % 5; (on écrit 5 pour avoir un nombre entre 0 et 4, oui oui ;) ).

Un exemple qui génère un nombre entre 0 et 4 :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <ctime> // Obligatoire
#include <cstdlib> // Obligatoire
 
using namespace std;
 
int main()
{
   int nbAleatoire(0);
 
   srand(time(0));
 
   nbAleatoire = rand() % 5;    
 
   return 0;
}

Tirer une lettre au hasard



Tirer un nombre au hasard c'est bien, mais pour ce programme j'ai besoin de tirer une lettre au hasard pour mélanger les lettres !


Imaginons que vous ayez une string appelée motMystere qui contient le mot mystère. Vous avez appris que les string pouvaient être considérées comme des tableaux, souvenez-vous ! Ainsi, motMystere[0] correspond à la première lettre, motMystere[1] à la deuxième lettre, etc.

Il suffit de générer un nombre aléatoire entre 0 et le nombre de lettres du mot (qui nous est donné par motMystere.size()) pour tirer une lettre au hasard ! Une petite idée de code pour récupérer une lettre au hasard :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>
 
using namespace std;
 
int main()
{
   string motMystere("MYSTERE");
 
   
   srand(time(0));
   
   position = rand() % motMystere.size();
       
   cout << "Lettre au hasard :" << motMystere[position];
 
   return 0;
}

Retirer une lettre d'une string



Pour éviter de tirer 2 fois la même lettre d'un mot, je vous conseille de retirer au fur et à mesure les lettres qui ont été piochées. Pour ce faire, on va faire appel à erase() sur le mot mystère comme ceci :
1
motMystere.erase(4, 1); // Retire la lettre n5

Il y a 2 paramètres :

  • Le numéro de la lettre à retirer du mot (ici 4, ce qui correspond à la 5ème lettre car on commence à compter à partir de 0).
  • Le nombre de lettres à retirer (ici 1).

Créez des fonctions !



Ce n'est pas une obligation, mais plutôt que de tout mettre dans le main(), vous pourriez créer des fonctions qui ont des rôles spécifiques. Par exemple, l'étape 2 qui génère un mot dont les lettres ont été mélangées mériterait d'être faite dans une fonction.

Ainsi, on pourrait appeler la fonction comme ceci dans le main() :
1
motMelange = melangerLettres(motMystere);

On lui envoie le motMystere, elle nous retourne un motMelange. :)

Bien entendu, toute la difficulté consiste ensuite à coder cette fonction melangerLettres. Allez au boulot ! ;)


Correction


C'est l'heure de la correction !

Vous avez sûrement passé du temps à réfléchir à ce programme, ça n'a peut-être pas toujours été facile et vous n'avez pas forcément su tout faire. Ce n'est pas grave ! Ce qui compte, c'est d'avoir essayé : c'est comme ça que vous progressez le plus !

Normalement, les étapes 1 et 3 étaient assez faciles pour tout le monde. Seule l'étape 2 (mélange des lettres) demandait plus de réflexion : je l'ai isolée dans une fonction melangerLettres comme je vous l'ai suggéré plus tôt.

Le code



Sans plus attendre, voici la correction :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>
 
using namespace std;
 
string melangerLettres(string mot)
{
   string melange;
   int position(0);
 
   // Tant que nous n'avons pas extrait toutes les lettres du mot
   while (mot.size() != 0)
   {
       // On choisit un numro de lettre au hasard dans le mot
       position = rand() % mot.size();
       // On ajoute la lettre dans le mot mlang
       melange += mot[position];
       // On retire cette lettre du mot mystre pour ne pas la prendre une 2e fois
       mot.erase(position, 1);
   }
 
   // On renvoie le mot mlang
   return melange;
}
 
int main()
{
   string motMystere, motMelange, motUtilisateur;
 
   // Initialisation des nombres alatoires
   srand(time(0));
 
 
   // 1 : On demande saisir un mot
   cout << "Saisissez un mot" << endl;
   cin >> motMystere;
 
   // 2 : On rcupre le mot avec les lettre mlanges dans motMelange
   motMelange = melangerLettres(motMystere);
 
   // 3 : On demande l'utilisateur quel est le mot mystre
   do
   {
       cout << endl << "Quel est ce mot ? " << motMelange << endl;
       cin >> motUtilisateur;
 
       if (motUtilisateur == motMystere)
       {
           cout << "Bravo !" << endl;
       }
       else
       {
           cout << "Ce n'est pas le mot !" << endl;
       }
   }while (motUtilisateur != motMystere); // On recommence tant qu'il n'a pas trouv
 
   return 0;
}

Ne vous laissez pas surprendre par la "taille" du code (qui n'est d'ailleurs pas très gros) et soyez méthodiques en le lisant : commencez par lire le main() et non la fonction melangerLettres(). Regardez les différentes étapes du programme une par une : isolées, elles sont plus simples à comprendre.

Des explications



Voici quelques explications pour mieux comprendre le programme, étape par étape.

Etape 1 : saisir un mot



C'était, de loin, l'étape la plus simple : un cout pour afficher un message, un cin pour récupérer un mot que l'on stocke dans la variable motMystere. Facile !

Etape 2 : mélanger les lettres



Plus difficile, cette étape est réalisée en fait dans une fonction melangerLettres() (en haut du programme). Le main() appelle la fonction melangerLettres() en lui envoyant le mot mystère. Le but de la fonction est de retourner une version mélangée des lettres, que l'on stocke dans motMelange.

Analysons la fonction melangerLettres. Elle extrait une à une les lettres du mot aléatoirement et recommence tant qu'il reste des lettres à extraire dans le mot :
1
2
3
4
5
6
while (mot.size() != 0)
{
   position = rand() % mot.size();
   melange += mot[position];
   mot.erase(position, 1);
}

A chaque passage de boucle, on tire un nombre au hasard compris entre 0 et le nombre de lettres qu'il reste dans le mot. On ajoute ces lettres piochées aléatoirement dans une string melange et on retire les lettres du mot d'origine pour ne pas les piocher une deuxième fois.

Une fois toutes les lettres extraites, on sort de la boucle et on retourne la variable melange qui contient les lettres dans le désordre.

Etape 3 : demander à l'utilisateur le mot mystère



Cette étape prend la forme d'une boucle do ... while, qui nous permet de s'assurer qu'on demande bien au moins une fois quel est le mot mystère.

L'utilisateur saisit un mot grâce à cin, et on compare ce mot avec le motMystere qu'il faut trouver. On continue la boucle tant que le mot n'a pas été trouvé, d'où la condition :
1
}while (motUtilisateur != motMystere); // On recommence tant qu'il n'a pas trouv

On affiche un message différent selon si on a trouvé ou non le mot mystère. Le programme s'arrête dès qu'on est sorti de la boucle, donc dès qu'on a trouvé le mot mystère. ;)

Téléchargement



Vous pouvez télécharger le programme avec le lien suivant :


Le fichier ZIP contient :

  • main.cpp : le fichier source du programme (l'essentiel !)
  • mot_mystere.cbp : le fichier de projet Code::Blocks (facultatif, pour ceux qui utilisent cet IDE)

Vous pouvez ainsi tester le programme et éventuellement vous en servir comme base par la suite pour réaliser les améliorations que je vais vous proposer (si vous n'avez pas réussi à faire le programme vous-même bien entendu !).


Aller plus loin


Notre programme est terminé... mais on peut toujours l'améliorer. Je vais vous présenter une série de suggestions pour aller plus loin, ce qui vous donnera l'occasion de travailler un peu plus sur ce petit jeu. :)

Ces propositions sont de difficulté croissante :

  • Ajoutez des sauts de ligne au début : lorsque le premier joueur saisit le mot mystère la première fois, vous devriez créer plusieurs sauts de ligne pour que le joueur 2 ne voie pas le mot qui a été saisi, sinon c'est trop facile pour lui. ;)
    Utilisez plusieurs endl par exemple pour créer plusieurs retours à la ligne.
  • Proposez au joueur de faire une nouvelle partie. Actuellement, une fois le mot trouvé, le programme s'arrête. Et si vous demandiez "Voulez-vous faire une autre partie ? (o/n)". En fonction de la réponse saisie, vous reprenez au début du programme. Pour ce faire, il faudra créer une grosse boucle do...while qui englobe les 3 étapes du programme.
  • Fixez un nombre maximal de coups pour trouver le mot mystère. Vous pouvez par exemple indiquer "Il vous reste 5 essais" et lorsque les 5 essais sont écoulés, le programme s'arrête en affichant la solution.
  • Calculez le score moyen du joueur à la fin du programme : après plusieurs parties du joueur, affichez-lui son score. Ce score sera la moyenne des parties précédentes. Vous pouvez calculer le nombre de points comme vous le voulez.
    Vous devrez sûrement utiliser les tableaux dynamiques vector pour stocker les scores de chaque partie au fur et à mesure avant d'en faire la moyenne.
  • Piochez le mot dans un fichier-dictionnaire : pour que l'on puisse jouer seul, vous pourriez créer un fichier contenant une série de mots (un par ligne) dans lequel le programme va aller piocher aléatoirement à chaque fois. Voici un exemple de fichier-dictionnaire :
         
    1
    2
    3
    4
    5
    6
    MYSTERE
    XYLOPHONE
    ABEILLE
    PLUTON
    MAGIQUE
    AVERTISSEMENT

    Au lieu de demander le mot à deviner (étape 1) on va chercher dans un fichier comme celui-ci un mot aléatoirement. A vous d'utiliser les fonctionnalités de lecture de fichiers que vous avez apprises ! :)

    ... Allez, puisque vous m'êtes sympathiques, je vous propose même de télécharger un fichier-dictionnaire tout prêt avec des dizaines de milliers de mots ! Merci qui ?! :D


Si vous avez d'autres idées, n'hésitez pas à compléter encore ce programme ! Cela vous fera beaucoup progresser, vous verrez. :)




Je suis sûr que ce premier TP vous aura fait bien plus progresser que tous les chapitres précédents réunis. ;)

Ne vous arrêtez pas au seul sujet du TP : essayez de faire les améliorations proposées, trouvez d'autres améliorations à faire, et lancez-vous ! Si vous avez un problème et que vous avez besoin d'aide, n'oubliez pas que le forum C++ est à votre disposition. :)



Chapitre précédent     Sommaire     Chapitre suivant



Distribué et adapté par David
Consulté 7979 fois



Hébergeur du site : David
Version PHP : 5.4.45-0+deb7u2
Uptime : 300 jours 2 heures 57 minutes
Espace libre : 1519 Mo
Dernière sauvegarde : 19/09/2019
Taille de la sauvegarde : 1115 Mo


5507982 pages ont été consultées sur le site !
Dont 4481 pages pendant les 24 dernières heures.

Page générée en 1.18 secondes


Nos sites préférés
- Création d'un jeu de plateforme de A à Z avec SDL
- Zelda ROTH : Jeux amateurs sur le thème de Zelda
- Zeste de Savoir : la connaissance pour tous et sans pépins
- YunoHost : s'héberger soi-même en toute simplicité
- Site de Fvirtman : recueil de projets et de codes en C et C++
- Par ici la sortie : le site des idées de sorties


  © 2005-2019 linor.fr - Toute reproduction totale ou partielle du contenu de ce site est strictement interdite.