Partage
  • Partager sur Facebook
  • Partager sur Twitter

problème avec les TP du pendu

Sujet résolu
    26 juin 2007 à 19:12:49

    Bonjours :)
    Voilà, j'ai commencé tout à l'heure à faire le jeu du pendu (tp de la fin de la 2ème partie du cours sur le C de m@teo)... mais voilà, j'ai un bug avec mon code, que voici:

    /*Jeu du pendu
    par Squ@bad'
    projet commencé le: 26-07-2007
    dernière modification: le 26-06-2007*/


    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>


    int main(int argc, char *argv[])
    {

    //déclaration des variables du jeu:
    long coupRestant = 10;
    char lettre = 0;
    char* maLettre = NULL;
    char motSecret[] = "MARRON";
    int lettreTrouvee[6] = {0}; // Un tableau de booléens. Chaque case correspond à une lettre du mot secret. 0 = lettre non trouvée, 1 = lettre trouvée
    int i = 0;
        printf("Bonjours et bienvenue dans le jeu du pendu!\n\n");
       
        //boucle du jeu
        do
        {
              printf("Il vous reste %ld coups a jouer.\n", coupRestant);
              printf("Quel est le mot secret? ");
              //On affiche autant d'étoiles qu'il reste de lettres à trouver restantes
              do
              {
              if(lettreTrouvee[i] == 0)
              {
              printf("*");
              }
              else
              {
              printf("%c", motSecret[i]);
              }
              i++;
              }while(i<6);
              printf("\nProposez une lettre: ");
              scanf("%c", &lettre);
              char lireCaractere();
             
              //on recherche si la lettre tapée par le joueur est dans le mot secret
              maLettre = strchr(motSecret, lettre);
             
              //si la lettre tapée n'est pas dans le mot secret
              if(maLettre == NULL)
              {
                          //on enlève un coup à jouer
                          coupRestant--;
              }
              //si la lettre tapée est dans le mot secret
              else
              {
                  //on met à la case correspondant à la lettre la valeur 1 dans le tableau booléen lettreTrouvee pour qu'elle s'affiche à la place de l'étoile.
                  motSecret[lettre] = lettreTrouvee[lettre];
                  lettreTrouvee[lettre] = 1;
              }
             

        //le jeu continue tant qu'on a pas trouvé toutes les lettres ou qu'on a encore des coups restants
        }while(coupRestant != 0);
     
      getch();     
      return 0;
    }




    quand je l'exécute, la lettre que je tape (si elle est minuscule), qu'elle soit "bonne" ou "mauvaise", m'enlève des coups restants, de plus au lieu d'afficher ma lettre à la place d'une étoile lorsqu'elle devrait être bonne, rien ne se passe, et les étoiles disparaissent même o_O
    Pour finir ( :p ), lorsque je tape une lettre (toujours en minuscule), la boucle du jeu se fait deux fois (je sais pas si je suis clair là):
    Il vous reste 9 coups a jouer.
    Quel est le mot secret? 
    Proposez une lettre: Il vous reste 8 coups a jouer.
    Quel est le mot secret? 
    Proposez une lettre: 


    Si je mets une lettre en majuscule, windows interromp mon prog (rapport d'erreur etc.).
    Normalement, ma fonction
    char lireCaractere();
    devrait "transformer" une lettre minuscule en lettre majuscule, donc cela ne devrait pas entrer en compte dans mon programme.

    Bref, si quelqu'un peut m'aider, ce serait cool, et si j'ai pas été assez clair, demandez moi des précisions ;)
    Merci d'avance.
    • Partager sur Facebook
    • Partager sur Twitter
      26 juin 2007 à 20:01:33

      Bonjour ! :D

      Je pense que ta ligne

      motSecret[lettre] = lettreTrouvee[lettre];


      crée tout le problème (explication : tu assigne une valeur à ton mot secret qui doit rester inchangé)
      De plus, après ta boucle

      do
      {
           if(lettreTrouvee[i] == 0)
           {
                printf("*");
           }
           else
           {
                printf("%c", motSecret[i]);
           }
           i++;
      }while(i<6);


      il faut réinitialiser ton i.
      Personnellement, j'utiliserait une boucle for, ça éviterait d'avoir ce genre de problèmes.

      En espérant avoir aidé, ;)
      • Partager sur Facebook
      • Partager sur Twitter
        26 juin 2007 à 21:29:15

        ok merci, y a du mieux:

        si je rentre un caractère en majuscule 'X', le programme ne ferme plus (c'est toujours ça :-° ). Mais il me reste encore plusieurs problèmes: les * ne s'affichent pas, et de plus c'est toujours bizarre: si je tape une bonne lettre comme 'M', le programme m'affiche:

        Il vous reste 10 coups a jouer.
        Quel est le mot secret? 
        Proposez une lettre: M
        Il vous reste 10 coups a jouer.
        Quel est le mot secret? 
        Proposez une lettre: Il vous reste 9 coups a jouer.
        Quel est le mot secret? 
        Proposez une lettre:


        au lieu d'afficher si il marchait:

        Il vous reste 10 coups a jouer.
        Quel est le mot secret? ******
        Proposez une lettre: M
        Il vous reste 10 coups a jouer.
        Quel est le mot secret? M*****
        Proposez une lettre: 


        Voici mon code que j'ai changé avec tes conseils:
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
        #include <ctype.h>


        int main(int argc, char *argv[])
        {

        //déclaration des variables du jeu:
        long coupRestant = 10;
        char lettre = 0;
        char* maLettre = NULL;
        char motSecret[] = "MARRON";
        int lettreTrouvee[6] = {0}; // Un tableau de booléens. Chaque case correspond à une lettre du mot secret. 0 = lettre non trouvée, 1 = lettre trouvée
        int i = 0;
            printf("Bonjours et bienvenue dans le jeu du pendu!\n\n");
           
            //boucle du jeu
            do
            {
                  printf("Il vous reste %ld coups a jouer.\n", coupRestant);
                  printf("Quel est le mot secret? ");
                  //On affiche autant d'étoiles qu'il reste de lettres à trouver restantes
                  for(i=0; i++; i<6)
                  {
                  if(lettreTrouvee[i] == 0)
                  {
                  printf("*");
                  }
                  else
                  {
                  printf("%c", motSecret[i]);
                  }
                  }
                  printf("\nProposez une lettre: ");
                  scanf("%c", &lettre);
                  char lireCaractere();
                 
                  //on recherche si la lettre tapée par le joueur est dans le mot secret
                  maLettre = strchr(motSecret, lettre);
                 
                  //si la lettre tapée n'est pas dans le mot secret
                  if(maLettre == NULL)
                  {
                              //on enlève un coup à jouer
                              coupRestant--;
                  }
                  //si la lettre tapée est dans le mot secret
                  else
                  {
                      //on met à la case correspondant à la lettre la valeur 1 dans le tableau booléen lettreTrouvee pour qu'elle s'affiche à la place de l'étoile.
                      lettreTrouvee[i] = motSecret[lettre];
                      lettreTrouvee[i] = 1;
                  }
                 

            //le jeu continue tant qu'on a pas trouvé toutes les lettres ou qu'on a encore des coups restants
            }while(coupRestant != 0);
         
          getch();     
          return 0;
        }


        y a donc des améliorations comparé à tout à l'heure, mais y a encore pas mal de bugs... :euh:

        à au fait, je vous montre la fonction char lireCaractere(); :
        char lireCaractere()
        {
            char caractere = 0;

            caractere = getchar(); // On lit le premier caractère
            caractere = toupper(caractere); // On met la lettre en majuscule si elle ne l'est pas déjà

            // On lit les autres caractères mémorisés un à un jusqu'à l'\n (pour les effacer)
            while (getchar() != '\n') ;

            return caractere; // On retourne le premier caractère qu'on a lu
        }


        peut-être y a-t-il des problèmes aussi de ce côté là puisque cette fonction est censé, si l'utillisateur entre une lettre minuscule, mettre cette lettre en majuscule, or elle ne le fait apparement pas car si je rentre une lettre minuscule, mon programme réagit comme si c'étais une lettre qui n'étais pas dans le mit même si c'est un 'm'...
        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          27 juin 2007 à 1:34:01

          Hum pour ta fonction lireCaractere, pense a y envoyer quelque chose =D

          Edit: modification du nom de la fonction (respect de la casse toussa toussa)
          • Partager sur Facebook
          • Partager sur Twitter
            27 juin 2007 à 1:50:16

            en effet, merci ;)
            je l'ai modifiée:
            char lireCaractere(char lettre)


            et dans mon main.c :
            printf("\nProposez une lettre: ");
                      scanf("%c", &lettre);
                      lireCaractere(lettre);


            Bon, cela atténue des bugs qui restent cependants présents...
            déjà, quand je tape une lettre minuscule, elle n'est manifestement pas considérée comme une majuscule après avoir fait appel à la fonction lireCaractere :(
            Parcontre, un bug est résolu: maintenant quand je tape une lettre, la boucle du jeu ne s'effectue qu'une fois :D
            mais je ne comprends pas une chose: quand je tape mon caractere, je tape ensuite sur entrée (normal, pour le scanf), mais je doit ensuite réappuyer sur entrée pour que le programme continue, comme si il y avait un getch(); quelque part...
            De plus, les étoiles ne s'affichent toujours pas :(

            Enfin, merci quand même, petit à petit ça progresse :p
            • Partager sur Facebook
            • Partager sur Twitter
            Anonyme
              27 juin 2007 à 2:07:47

              Tu aurais pas des problèmes avec les pointeurs toi? ^^

              Je te conseil de relire la partie des pointeurs et comment les envoyer à une fonction

              Les pointeurs


              Citation : Squ@bad'

              déjà, quand je tape une lettre minuscule, elle n'est manifestement pas considérée comme une majuscule après avoir fait appel à la fonction lireCaractere



              C'est normal. Tu lui envois une variable, variable qui est supprimée a la fin de la fonction, donc ta variable dans main change pas... Enfin il me semble :p


              • Partager sur Facebook
              • Partager sur Twitter
                27 juin 2007 à 2:24:19

                oulàlà en effet, je commence à tout confondre... bon, j'ai bien repris le problème: cette fonction je l'ai eue dans les consignes donné par mateo pour ce TP... et en fait, je suis bête ^^ , il fallait mettre
                lettre = lireCaractere();
                à la place de
                scanf("%c", &lettre);
                ... j'avais fait un mix des deux donc forcément :-°
                Bref, bugs résolus:
                -quand je tape mon caractere, je tape ensuite sur entrée (normal, pour le scanf), mais je doit ensuite réappuyer sur entrée pour que le programme continue, comme si il y avait un getch(); quelque part... OK, ça marche normalement maintenant :)
                -quand je tape une lettre minuscule, elle n'est manifestement pas considérée comme une majuscule après avoir fait appel à la fonction lireCaractererésolu aussi :)

                Bugs restants:
                -Les étoiles ne s'affichent pas, et là je ne comprends vraiment pas pourquoi (j'espère que c'est pas une erreur aussi bête que la précédente...).

                Bon, et mon code n'est pas fini, loin de là, puisqu'il faut aussi que j'arrête la boucle du jeu si le joueur a trouvé toutes les lettres, et en plus faut aussi que je fasse en sorte que si le joueur tape une lettre qui est plusieurs fois dans le mot il n'ait qu'à la taper une fois et qu'elle apparaisse partout (comme ici le 'R')...
                Mais je préfère d'abord résoudre ces premiers bugs avant de m'attaquer à la suite...
                • Partager sur Facebook
                • Partager sur Twitter
                  27 juin 2007 à 2:33:00

                  perso, j'ai rien lu de ce qu'il y a marquer en haut (la flemme, il est trop tard, je suis à moitié mort en plus ^^), je sais que moi aussi ce tp m'a posé beaucoup de problèmes. Je te donnerais bien mon code mais je sais pas si ça serait un cadeau parce que je m'y perde complétement alors que je l'ai moi même fait... j'avais utilisé un fichier et plein de trucs qui me dépassent à moitié :p:lol:
                  • Partager sur Facebook
                  • Partager sur Twitter
                    27 juin 2007 à 2:37:08

                    merci pour ta proposition Bbar, mais je préfère ne pas avoir de solution entière directement (sinon je regarderai celle du cours ;) ), je préfère y arriver sans avoir déjà vu une solution toute faite... c'est pour cela d'ailleurs que je demande un peu d'aide sur le forum ;)
                    en fait, je veux mettre le paquet pour comprendre tout, absoluement tout ce que je fait dans ce TP pour acquérir toutes les bases enseignées dans le cour ;)
                    • Partager sur Facebook
                    • Partager sur Twitter
                    Anonyme
                      27 juin 2007 à 2:38:56

                      Une avancée du code source peut etre ? (2h 40 du mat pas envie de faire des c/c sur code blocks ^^ )
                      • Partager sur Facebook
                      • Partager sur Twitter
                        27 juin 2007 à 2:43:49

                        lol je te comprends ;)
                        moi j'aime bien programmer la nuit (et dormir le jour ^^ ), mais c'est vrai qu'il commence à faire sommeil ;)
                        là j'ai pas avancé le code source, j'ai fais une courte pause, mais j'y retourne ^^
                        dès que y a du neuf je posterai ou éditerai ce message ;)

                        EDIT: pour les étoiles, j'ai repris une boucle while, pour voir, et elles s'affichent... mais quand je tape une bonne lettre, elle ne va pas remplacer une étoile comme j'aimerai et comme je pensé avoir demandé que le programme le fasse:
                        i=0;
                                  printf("\nIl vous reste %ld coups a jouer.\n", coupRestant);
                                  printf("Quel est le mot secret? ");
                                  //On affiche autant d'étoiles qu'il reste de lettres à trouver restantes
                                  do
                                  {
                                  if(lettreTrouvee[i] == 0)
                                  {
                                  printf("*");
                                  }
                                  else
                                  {
                                  printf("%c", motSecret[i]);
                                  }
                                  i++;
                                  }while(i<6);
                                  printf("\nProposez une lettre: ");
                                  lettre = lireCaractere();
                                  //on recherche si la lettre tapée par le joueur est dans le mot secret
                                  maLettre = strchr(motSecret, lettre);
                                 
                                  //si la lettre tapée n'est pas dans le mot secret
                                  if(maLettre == NULL)
                                  {
                                              //on enlève un coup à jouer
                                              coupRestant--;
                                  }
                                  //si la lettre tapée est dans le mot secret
                                  else
                                  {
                                      //on met à la case correspondant à la lettre la valeur 1 dans le tableau booléen lettreTrouvee pour qu'elle s'affiche à la place de l'étoile.
                                      lettreTrouvee[i] = motSecret[lettre];
                                      lettreTrouvee[i] = 1;
                                  }
                                 
                        :(
                        • Partager sur Facebook
                        • Partager sur Twitter
                          27 juin 2007 à 10:15:00

                          Good morning, :p

                          Là, en fait le problème réside dans ta condition en dessous de ta boucle ou tu as écrit

                          if(maLettre == NULL)
                                    {
                                                //on enlève un coup à jouer
                                                coupRestant--;
                                    }
                                    //si la lettre tapée est dans le mot secret
                                    else
                                    {
                                        //on met à la case correspondant à la lettre la valeur 1 dans le tableau booléen lettreTrouvee pour qu'elle s'affiche à la place de l'étoile.
                                        lettreTrouvee[i] = motSecret[lettre];
                                        lettreTrouvee[i] = 1;
                                    }


                          Où, comme tu utilises des pointeurs, il faut écrire un plus complexe :

                          if(maLettre == NULL)
                                    {
                                                    //on enlève un coup à jouer
                                                    coupRestant--;
                                    }
                                    else
                                    {
                                        //on met à la case correspondant à la lettre la valeur 1 dans le tableau booléen lettreTrouvee pour qu'elle s'affiche à la place de l'étoile.
                                        lettreTrouvee[((long)maLettre) - ((long)motSecret)] = 1;
                                    }


                          dans lequel tu considère ton pointeur 'maLettre' comme ce qu'il est, c'est-à-dire le pointeur vers la première lettre du mot semblable à 'lettre', il faut donc soustraire le pointeur 'lettre' à celui 'maLettre' et diviser par 'sizeof(typeDuTableau)' pour trouver l'index de '*maLettre' dans le tableau 'lettre'.

                          ...ouffffff :p

                          Si tu n'as pas compris du premier coup, ce n'est pas grave (je ne l'ai pas écrit du premier coup ;) ), relis-le attentivement plusieurs fois et va voir le cours sur les pointeurs et tout ira bien.

                          Cordialement,
                          • Partager sur Facebook
                          • Partager sur Twitter
                            27 juin 2007 à 10:21:27

                            Citation : Squ@bad'

                            EDIT: pour les étoiles, j'ai repris une boucle while, pour voir, et elles s'affichent... mais quand je tape une bonne lettre, elle ne va pas remplacer une étoile comme j'aimerai et comme je pensé avoir demandé que le programme le fasse:

                            i=0;
                                      do
                                      {

                                      ...

                                      }while(i<6);

                                      ...

                                      if(maLettre == NULL)
                                      {
                                                  //on enlève un coup à jouer
                                                  coupRestant--;
                                      }
                                      //si la lettre tapée est dans le mot secret
                                      else
                                      {
                                          //on met à la case correspondant à la lettre la valeur 1 dans le tableau booléen lettreTrouvee pour qu'elle s'affiche à la place de l'étoile.
                                          lettreTrouvee[i] = <couleur nom="rouge">motSecret[lettre]</couleur>;
                                          lettreTrouvee[i] = 1;
                                      }
                                     


                            Alors déjà je te conseille fortement de remettre la boucle for, et je pense que le problème n'est pas dans le for mais dans ta syntaxe, tu n'a pas mis les argument dnas le bon ordre, le i++ est le 3ème paramètre et non pas le 2e

                            Pour la partie en rouge, tu veux la "lettre" ième case du tableau motSecret, or ton "lettre" correspond à la valeur ASCII de la lettre que tu a tapé, aucune raison qu'elle soit entre 0 et 5...
                            et puis de tte facon a quoi sert cette ligne puisque tu écrase la valeur que tu viens de mettre par "1".
                            En voyant ton code je me dit que tu voulait peut etre mettre "maLettre" puisque cette valeur contient la valeur de la premiere occurence de "lettre" dans "motSecret"

                            Enfin chose importante, Ã ce point du code, ta variable i vaut toujours, 5, tu dois donc mettre selon moi

                            lettreTrouvee[maLettre] = 1;


                            voila essai de corriger ca et dis nous ce que ca donne.

                            PS : ensuite n'oubli pas de changer ton code pour que tte les lettres identiques soit découverte en même temps.

                            Edit : en vérifiant la fonction de recherche d'un caractère je vois qu'elle renvoi effectivement un pointeur vers le 1ere caractere, donc comme le dit Raton Laveur tu dois comparer les pointeurs maLettre et motSecret pour avoir l'index de la lettre trouvé (motSecret correspondant a l'adresse du 1ere caractère du mot Secret et maLettre correspondant à l'adresse de la première occurence de la lettre tapée dans le mot secret), comme les case mémoire sont adjacente pour un tableau tu as direct l'index...
                            • Partager sur Facebook
                            • Partager sur Twitter
                              27 juin 2007 à 13:36:44

                              Merci beaucoup pour votre précieuse aide :D

                              @raton-laveur boiteux: je n'ai pas tout de suite compris mais ça commence à s'éclaircir, merci pour ton aide

                              @lody: merci, en effet il suffisait de changer les paramètres de la boucle for...

                              Bon, là mon code marche bien, il faut à présent que je fasse en sorte que toutes les lettres identiques soient découvertes en même temps, car là j'ai le premier R qui s'affiche bien, mais pas le second même si je retape 'R'... je vais donc plancer là dessus :)

                              Merci encore :)

                              EDIT: YES !!! :D:D
                              j'ai réussi à faire que toutes les lettres identiques soient découvertes en même temps :D
                              //si la lettre tapée est dans le mot secret
                                        else
                                        {
                                            //on met à la case correspondant à la lettre la valeur 1 dans le tableau booléen lettreTrouvee
                                            //pour qu'elle s'affiche à la place de l'étoile:
                                           
                                            /*tu considère ton pointeur 'maLettre' comme ce qu'il est, c'est-à-dire le pointeur vers la première lettre du mot
                                            semblable à 'lettre', il faut donc soustraire le pointeur 'lettre' à celui 'maLettre' et diviser par
                                            'sizeof(typeDuTableau)' pour trouver l'index de '*maLettre' dans le tableau 'lettre'. */

                                            lettreTrouvee[((long)maLettre) - ((long)motSecret)] = 1;
                                           
                                            //Toutes les lettres identiques doivent-être trouvées en même temps, au cas où on vérifie
                                            for(i=0; i<6; i++)
                                            {
                                           
                                            if(motSecret[i] == lettre)
                                            {
                                                  lettreTrouvee[i] = 1;         
                                            }
                                           
                                            }
                                        }


                              Maintenant je vais faire que si le joueur a découvert toutes les lettres du mots et qu'il lui reste des coups il a gagné :)
                              ensuite, j'intègrerai un dico etc. ^^
                              • Partager sur Facebook
                              • Partager sur Twitter

                              problème avec les TP du pendu

                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                              • Editeur
                              • Markdown