Partage
  • Partager sur Facebook
  • Partager sur Twitter

TP - Pendu

Correction & commentaires

Sujet résolu
Anonyme
    28 mars 2017 à 17:30:55

    Bonjour OCR !

    Je travailles actuellement sur le TP du pendu. Je viens vers vous pour vous demander une correction, des commentaires, conseils... Avant d'aller plus loin dans le TP (choix du mot aléatoire dans un dictionnaire).

    En attendant vos réponses, je vais bosser sur:

    - allocation dynamique de la mémoire en fonction du mot entré par l'utilisateur

    - trouver la cause d"un bug; lorsque je joues la même lettre deux fois, le mot mystère ne s'affiche pas comme voulu



    Voici le premier jet du programme:

    main.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #include "main.h"
    
    int main()
    {
        char motATrouve[20] = {'0'}, lettresJouees[20] = {'0'}, motMystere[20] = {'0'};
        char c = 0;
        int maxCoups = 10, motTrouve = 0, nbCoupsJoues = 0, i = 0;
    
        printf("Bienvenue dans le jeu du pendu!\n");
        printf("Choisissez le mot mystere: ");
        scanf("%20s",&motATrouve);
        videBuffer();
        for(i=0;i<20;i++)
            motATrouve[i] = toupper(motATrouve[i]);
    
        do
        {
            printf("Quelle lettre ? ");
            c = lireCaractere();
            if(strchr(motATrouve,c) != NULL)
                lettresJouees[nbCoupsJoues] = c;
            afficherMot(motATrouve,motMystere,lettresJouees,20);
            if(strcmp(motATrouve,motMystere)==0)
                motTrouve = 1;
            nbCoupsJoues++;
        } while(nbCoupsJoues<maxCoups && motTrouve==0);
        if(motTrouve==1)
            printf("Bravo! Vous avez trouve le mot mystere en %d coup(s)!\n",nbCoupsJoues);
        else
            printf("Perdu!\n");
    
        return 0;
    }
    
    char lireCaractere()
    {
        char c=0;
        c=getchar();
        c=toupper(c);
        videBuffer();
        return c;
    }
    void videBuffer()
    {
        while(getchar()!='\n');
    }
    void afficherMot(char motATrouve[], char *motMystere, char lettresJouees[], int longueur)
    {
        int i=0;
        for(i=0;i<longueur;i++)
        {
            if(strchr(lettresJouees,motATrouve[i]) != NULL)
                *(motMystere+i) = motATrouve[i];
            else
                *(motMystere+i) = '*';
        }
        printf("%s\n",motMystere);
    }
    

    main.h

    char lireCaractere();
    void videBuffer();
    void afficherMot(char motATrouve[], char *motMystere, char coupsJoues[], int longueur);
    

    Merci de m'avoir lu :)

    -
    Edité par Anonyme 28 mars 2017 à 17:35:40

    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      30 mars 2017 à 15:32:50

      Progression dans le TP :

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <ctype.h>
      #include "main_v1.h"
      #include <time.h>
      
      #define TAILLE_MAX 100
      #define DICTIONNAIRE "dico.txt"
      #define MAX_COUPS 15
      
      int main(int argc, char *argv[])
      {
          char motATrouver[TAILLE_MAX] = {0}, lettresJouees[MAX_COUPS] = {0};
          int motTrouve = 0, nbCoupsJoues = 0;
          FILE* dico = NULL;
          srand(time(NULL));
      
          // choix du mot aléatoire
          if((dico = fopen(DICTIONNAIRE,"r")) != NULL)
          {
              choixMotDico(dico, motATrouver, TAILLE_MAX);
              fclose(dico);
          }
          else
          {
              printf("Pas de dictionnaire !");
              return EXIT_FAILURE;
          }
          //debut de la partie
          printf("Bienvenue dans le jeu du pendu v1!\n");
          do
          {
              printf("\nIl vous reste %d coup(s) a jouer...",(MAX_COUPS-nbCoupsJoues));
              afficherMot(motATrouver,lettresJouees,TAILLE_MAX);
              if(nbCoupsJoues>0)
                  afficherLettresJouees(motATrouver,lettresJouees,MAX_COUPS);
              printf("\nProposez une lettre: ");
              lettresJouees[nbCoupsJoues++] = lireCaractere();
              motTrouve = comparerMotTrouve(motATrouver,lettresJouees,TAILLE_MAX);
          } while(nbCoupsJoues<MAX_COUPS && motTrouve==0);
          if(motTrouve==1)
              printf("\nBravo! Vous avez trouve le mot mystere %s en %d coup(s)!",motATrouver,nbCoupsJoues);
          else
              printf("\nPerdu!");
          printf("\n");return 0;
      }
      char lireCaractere()
      {
          char c=0;
          c=toupper(getchar());
          while(getchar()!='\n');
          return c;
      }
      void afficherMot(char motATrouver[], char lettresJouees[], int tailleTabMotATrouver)
      {
          int i=0;
          printf("\nMot mystere: ");
          for(i=0;i<tailleTabMotATrouver;i++)
          {
              if(strchr(lettresJouees,motATrouver[i]) && motATrouver[i] !=0)
                  printf("%c",motATrouver[i]);
              else if(!strchr(lettresJouees,motATrouver[i]) && motATrouver[i] !=0)
                  printf("*");
          }
      }
      int comparerMotTrouve(char motATrouver[], char lettresJouees[], int tailleTabMotATrouver)
      {
          int i=0;
          for(i=0;i<tailleTabMotATrouver;i++)
          {
              if(!strchr(lettresJouees,motATrouver[i]))
                  return 0;
          }
          return 1;
      }
      void afficherLettresJouees(char motATrouver[], char lettresJouees[], int tailleTabLettresJouees)
      {
          int i=0;
          printf("\nLettres jouees: ");
          for(i=0;i<tailleTabLettresJouees;i++)
          {
              if(!strchr(motATrouver,lettresJouees[i]) && lettresJouees[i] !=0)
                  printf("%c",lettresJouees[i]);
          }
          for(i=0;i<tailleTabLettresJouees;i++)
          {
              if(strchr(motATrouver,lettresJouees[i]) && lettresJouees[i] !=0)
                  printf("(%c)",lettresJouees[i]);
          }
      }
      void choixMotDico(FILE* dico, char motATrouver[], int tailleTabMotATrouver)
      {
          int c = 0, motAleatoire = 0, nbMotDico = 0, i = 0, cpt = 0;
          //calcul du nombre de mots dans le dictionnaire
          do
          {
              if((c = fgetc(dico)) == '\n')
                  nbMotDico++;
          } while(c != EOF);
          motAleatoire = rand() % nbMotDico;
          rewind(dico);
          //deplacement du curseur dans le fichier au debut du mot aleatoire
          for(i=0;i<(motAleatoire-1);i++)
              while(fgetc(dico) != '\n');
          //majuscule
          while(((c = fgetc(dico)) != '\n') && cpt < tailleTabMotATrouver)
              *(motATrouver + cpt++) = toupper(c);
      }
      
      
      char lireCaractere();
      void afficherMot(char motATrouver[], char lettresJouees[], int tailleTabMotATrouver);
      int comparerMotTrouve(char motATrouver[], char lettresJouees[], int tailleTabMotATrouver);
      void afficherLettresJouees(char motATrouve[], char lettresJouees[], int tailleTabLettresJouees);
      void choixMotDico(FILE* dico, char motATrouver[], int tailleTabMotATrouver);
      
      



      - Auriez-vous des remarques à faire quant à une quelquonque optimisation de mon programme ?

      - Comment allouer dynamiquement la taille d'un tableau selon 1. ce que l'utilisateur aura saisi (clavier) 2. la longueur du mot dans le dictionnaire ?

      • Partager sur Facebook
      • Partager sur Twitter
        30 mars 2017 à 16:10:11

        Salut,

        Je n'ai pas regardé en détail le code, mais j'ai fait quelques parties  :

        Si tu perds, le jeu te dit que tu as gagné en 15 coups.

        Le compteur de coups ne doit pas diminuer lorsque l'on trouve une lettre juste (imagine qu'il reste 3 lettres à trouver, mais 1 seul coup à jouer ... zut !)

        J'ai remarqué en survolant la page que régulièrement tu transmettais en argument TAILLE_MAX, c'est un peu inutile puisque c'est un #define accessible partout.

        Kefka1988 a écrit:

        - Comment allouer dynamiquement la taille d'un tableau selon 1. ce que l'utilisateur aura saisi (clavier) 2. la longueur du mot dans le dictionnaire ?

        1) Si tu récupère une saisie dans une chaîne, alors tu peux mesurer la chaîne et allouer la mémoire nécessaire tout simplement

        2) Ben un peu pareil, tu comptes le nombre de lettres qui contient le mot puis malloc(nombre_lettres + 1);

        • Partager sur Facebook
        • Partager sur Twitter
          30 mars 2017 à 16:31:32

          Bonjour,

          Kefka1988 a écrit:

          - 1]Auriez-vous des remarques à faire quant à une quelquonque optimisation de mon programme ?

          - 2]Comment allouer dynamiquement la taille d'un tableau selon 1. ce que l'utilisateur aura saisi (clavier) 2. la longueur du mot dans le dictionnaire ?


          1]

          • Un problème flagrant d'optimisation, ce sont les commentaire:
            "Mé C PA de l'OPTI".
            Si j'aurai gagné du temps à lire ton code. Il y a très peu de cas ou l'otpimisation, au détriment de la lisibilité et de la modularité ,se font.
            Dit toi que le temps gagné à coder (en groupe) est aussi important que le temps passer à l’exécution.
          • Vérifie les entrée, de l'utilisateur tout le temps, (avec un strlen, et un isalapha) ça devrait suffire.
          • Dans la fonction void afficherMot tu recalcule à chaque tour toute les lettres, j'aurai fais autrement
            J'aurai eu 2 version du mot à trouvé, le mot en entier, et le mot dont les lettres on été découvertes, exemple:
            mot_a_trouver: Bonjour / mot_cache: B**j**r
            Dès que l'utilisateur rentre une lettre, je change mot_cache. Exemple je rentre 'o'
            mot_cache: Bo*jo*r.
            Comme ça tu affichera directement mot_cache.
          • Partager sur Facebook
          • Partager sur Twitter
          Anonyme
            30 mars 2017 à 16:34:28

            Gam' a écrit:

            - Si tu perds, le jeu te dit que tu as gagné en 15 coups.

            Comment ça ? Je comprends pas.

            - Le compteur de coups ne doit pas diminuer lorsque l'on trouve une lettre juste (imagine qu'il reste 3 lettres à trouver, mais 1 seul coup à jouer ... zut !)

            Oui, effectivement :D. Je vais corriger ça !

            - J'ai remarqué en survolant la page que régulièrement tu transmettais en argument TAILLE_MAX, c'est un peu inutile puisque c'est un #define accessible partout.

            Oui, je pourrais mettre ça directement dans les fonctions. Mais est-ce que c'est recommandé ?

            - 1) Si tu récupère une saisie dans une chaîne, alors tu peux mesurer la chaîne et allouer la mémoire nécessaire tout simplement

            Oui, j'y ai pensé mais il y aura toujours une borne maximale à définir... C'est un peu ça qui me dérange.:p

            Dans le cas de ce TP, je ne pense pas que la longueur d'un mot puisse poser problème. Mais si par exemple, dans un autre programme, je demande à l'utilisateur de saisir un texte dont je n'ai aucune idée de sa longueur, il faudra que je la définisse la borne maximale. Je supposes que c'est comme ça dans tous les programmes.

            - 2) Ben un peu pareil, tu comptes le nombre de lettres qui contient le mot puis malloc(nombre_lettres + 1);

            A la limite, je pourrais stocker ce que l'utilisateur saisi au clavier dans un fichier, et ensuite mesurer et allouer dynamiquement la taille du tableau.

            En tout cas, merci d'avoir répondu

            -
            Edité par Anonyme 30 mars 2017 à 16:36:43

            • Partager sur Facebook
            • Partager sur Twitter
              30 mars 2017 à 16:42:41

              Kefka1988 a écrit:

              Gam' a écrit:

              - Si tu perds, le jeu te dit que tu as gagné en 15 coups.

              Comment ça ? Je comprends pas.


              Si je mets que des z comme un bourrin par exemple : 

              Il vous reste 1 coup(s) a jouer...
              Mot mystere: *********
              Lettres jouees: ZZZZZZZZZZZZZZ
              Proposez une lettre: z
              
              Bravo! Vous avez trouve le mot mystere CONTINUER en 15 coup(s)!
              

              Trop facile ce jeu :ange:

              • Partager sur Facebook
              • Partager sur Twitter

              TP - 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