Partage
  • Partager sur Facebook
  • Partager sur Twitter

Jeu C

Sujet résolu
    28 octobre 2019 à 19:36:48

    Bonjour, dans le cadre d'un TP je dois faire un jeu du pendu. J'ai écrit tout le code mais ça ne fonctionne pas et j'aimerai donc un avis extérieur pour me dire où est l'erreur. Pour information, je lance l’exécution du programme et le problème intervient à partir du moment où je dois choisir entre une donner une lettre ou un mot, dans les deux cas il a un soucis. Pour la lettre: je donne une lettre, je fais entrée mais rien ne se passe. Pour un mot: ça ne me demande même pas un mot, ça me met perdu directement.

    Maintenant voici le code:

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #define N 10
    
    int enreg_secr (char mot_secret[]){
      int lg ;
      printf ("donner le mot secret : ");
      if (fgets(mot_secret, N, stdin)!= NULL){
        lg = strlen (mot_secret) ;
        return (lg-1) ;
      }
      else exit(EXIT_FAILURE);
    }
    
    void aff_tab(char t[], int n){
      int i;
      for (i=0; i<n; i++){
        printf("%c ", t[i]);
      }
    }
    
    void poser_lettre(char c, char mot_secret[], int lg, char tab[]){
      int ro=0;
      for (lg=0; lg<N; lg++){
        if (c==mot_secret[lg]){
          tab[lg]=c;
        }
        else{
          ro+=1;
        }
      }
      if (ro==0){
        printf("Lettre absente ! \n");
      }
    }
    
    
    void essai_mot(char mot_secret[]){
      char prop[N];
      printf("Proposition: ");
      fgets(prop, N, stdin);
      if (strcmp(prop, mot_secret)==0){
        printf("Gagné ! \n");
        exit(EXIT_SUCCESS);
      }
      else{
        printf("Perdu !\n");
      }
    }
    
    void essai_lettre (char mot_secret[], int lg, char tab[]){
      char prop;
      printf("Votre lettre: \n");
      prop=getchar();
        for (lg=0; lg<N; lg++){
          if (prop==mot_secret[lg]){
    	poser_lettre(prop, mot_secret, lg, tab);
    	  }
      }
    }
    
    
    int main(){
      char mot_secret[N];
      char tab[N];
      int rep, i, lg, cp=20;
      lg=enreg_secr(mot_secret);
      printf("Le mot secret à %d lettres \n", lg);
      for (i=0; i<lg; i++){
        tab[i]='_';
      }
      for (i=0; i<cp; i++){
        printf("Contenu du tableau : ");
        aff_tab(tab, lg);
        printf("\n Nombre de coup restant: %d", cp);
        cp--;
        printf("\n Que voulez-vous proposer ? 1: Un mot, 2: Une lettre \n");
        if (scanf("%d", &rep)!=1){
          printf("Erreur de saisie \n");
          exit(EXIT_FAILURE);
        }
        else {
          if (rep==1){
    	essai_mot(mot_secret);
          }
          if (rep==2){
    	essai_lettre(mot_secret, lg, tab);
          }
          if (rep!=1 && rep!=2){
    	printf("Ce n'est ni 1 ni 2");
    	exit(EXIT_FAILURE);
          }
        }
      }
      exit(EXIT_SUCCESS);
    }

    Merci de votre aide.

    • Partager sur Facebook
    • Partager sur Twitter
      28 octobre 2019 à 21:08:07

      Bonjour, quelques soucis en effet.

      ta fonction poser_lettre ne sert a rien (à part faire des erreurs).

      Tes tests de fin de boucle for sont erronés la plupart du temps (tu vas trop loin).

      L'utilisation de fgets est problématique, car quand tu saisie une chaine, il prend en compte le retour chariot comme étant un élément de la chaine.

      Voici une version modifié de ton code:

      #include <stdlib.h>
      #include <stdio.h>
      #include <string.h>
      #define N 10
      
      int enreg_secr(char mot_secret[]) {
          int lg;
          printf("donner le mot secret : ");
          if (fgets(mot_secret, N, stdin) != NULL) {
              lg = strlen(mot_secret);
              mot_secret[lg-1]='\0';  // car fgets recupere le \n du retour chariot
              return (lg - 1);
          } else exit(EXIT_FAILURE);
      }
      
      void aff_tab(char t[], int n) {
          int i;
          for (i = 0; i < n; i++) {
              printf("%c ", t[i]);
          }
      }
      
      
      
      void essai_mot(char mot_secret[]) {
          char prop[N];
          printf("Proposition: ");
          //fgets(prop, N, stdin);
          scanf("%s",prop);
          if (strcmp(prop, mot_secret) == 0) {
              printf("Gagné ! \n");
              exit(EXIT_SUCCESS);
          } else {
              printf("Perdu !\n");
          }
      }
      
      void essai_lettre(char mot_secret[], int lg, char tab[]) {
          char prop;
          int i;
          int ro=0;
          printf("Votre lettre: \n");
          scanf(" %c",&prop);
          for (i = 0; i < lg; i++) {
              if (prop == mot_secret[i]) {
                  tab[i]=prop;
                  ro=1;
              }
          }
          if (ro == 0) {
              printf("Lettre absente ! \n");
          }
      }
      
      int main() {
          char mot_secret[N];
          char tab[N];
          int rep, i, lg, cp = 20;
          lg = enreg_secr(mot_secret);
          printf("Le mot secret à %d lettres \n", lg);
          for (i = 0; i < lg; i++) {
              tab[i] = '_';
          }
          for (i = 0; i < cp; i++) {
              printf("Contenu du tableau : ");
              aff_tab(tab, lg);
              printf("\n Nombre de coup restant: %d", cp);
              cp--;
              printf("\n Que voulez-vous proposer ? 1: Un mot, 2: Une lettre \n");
              if (scanf("%d", &rep) != 1) {
                  printf("Erreur de saisie \n");
                  exit(EXIT_FAILURE);
              } else {
                  if (rep == 1) {
                      essai_mot(mot_secret);
                  }
                  if (rep == 2) {
                      essai_lettre(mot_secret, lg, tab);
                  }
                  if (rep != 1 && rep != 2) {
                      printf("Ce n'est ni 1 ni 2");
                      exit(EXIT_FAILURE);
                  }
              }
          }
          exit(EXIT_SUCCESS);
      }

      Je n'ai pas tout testé, mais ça devrait fonctionner un peu mieux.

      • Partager sur Facebook
      • Partager sur Twitter
        28 octobre 2019 à 21:27:13

        Tout d'abord merci pour l'aide ! J'ai essayé le code, il y a quelques erreurs si l'on compile avec le niveau maximum de détection mais rien de grave, le programme fonctionne presque parfaitement !

        Néanmoins, ma consigne m'oblige à utiliser la fonction poser_lettre & à utiliser fgets() pour la fonction essai_mot. Si tu as une idée de comment faire je suis preneur. J'essayerai de mon côté demain matin.

        • Partager sur Facebook
        • Partager sur Twitter
          28 octobre 2019 à 22:40:21

          Ben donnes l'ensemble des consignes, parceque là...

          Les prototypes des fonctions sont egalement imposés?

          • Partager sur Facebook
          • Partager sur Twitter
            28 octobre 2019 à 22:47:20

            Effectivement c'est peut-être mieux:

            J'avais la fonction enreg_secr que j'ai légèrement modifié

            -->

            int enreg_secr (char mot_secret[]){

            int lg ;

            printf ("donner le mot secret : ");

            fgets (mot_secret, N, stdin) ;

            lg = strlen (mot_secret) ;

            return (lg-1) ;

            }
             Ecrivez une fonction void poser lettre (char c, char mot secret[], int lg, char tab[]) qui parcourt les lg cases du tableau mot secret, et qui, pour chaque case de mot secret qui contient le caractère c, ´écrit c dans la case correspondante de tab. Cette fonction affiche ensuite le contenu de tab. Si la lettre n’a pas d’occurrence dans le mot secret, on affiche la réponse “lettre absente!” `a l’´ecran.

             Ecrivez une fonction void essai mot(char mot secret[]) qui demande a` l’utilisateur de proposer un mot, et qui donne la réponse a` cette proposition : soit “gagné!”, soit “perdu!”. Pour cela, utilisez la fonction fgets(); comme dans la fonction enreg secr();, et la fonction strcmp();.

            Ecrivez une fonction void essai lettre (char mot secret[], int lg, char tab[]); qui demande `a l’utilisateur de proposer une lettre, puis appelle la fonction poser lettre.

            Le reste consistant à organiser dans le main.

            • Partager sur Facebook
            • Partager sur Twitter
              29 octobre 2019 à 9:22:32

              Ha ben oui, avec les consignes c'est mieux, et surtout, tu ne les a pas suivis!!!

              Voici une solution, tu remarqueras que j'ai ajouté une fonction vider_buffer qui permet de vider la buffer d'entrée et d'éviter des désagrément liés au fait que \n est toujours dans le buffer d'entrée, et peut pertuber le fgets(stdin).

              #include <stdlib.h>
              #include <stdio.h>
              #include <string.h>
              #define N 10
              
              int enreg_secr(char mot_secret[]) {
                  int lg;
                  printf("donner le mot secret : ");
                  if (fgets(mot_secret, N, stdin) != NULL) {
                      lg = strlen(mot_secret);
                      mot_secret[lg - 1] = '\0'; // car fgets recupere le \n du retour chariot
                      return (lg - 1);
                  } else exit(EXIT_FAILURE);
              }
              
              void aff_tab(char t[], int n) {
                  int i;
                  for (i = 0; i < n; i++) {
                      printf("%c ", t[i]);
                  }
              }
              
              void vider_buffer() {
                  int c = 0;
                  while (c != '\n' && c != EOF) {
                      c = getchar();
                  }
              }
              
              void essai_mot(char mot_secret[]) {
                  char prop[N];
              
                  printf("Proposition: ");
                  vider_buffer(); // vider le buffer clavier (pour virer les eventuels \n)
                  fgets(prop, N, stdin);
                  prop[strlen(prop) - 1] = '\0'; // car fgets recupere le \n du retour chariot, on le remplace par \0
                  if (strcmp(prop, mot_secret) == 0) {
                      printf("Gagné ! \n");
                      exit(EXIT_SUCCESS);
                  } else {
                      printf("Perdu !\n");
                  }
              }
              
              void poser_lettre(char c, char mot_secret[], int lg, char tab[]) {
                  int i;
                  int ro = 0;
                  for (i = 0; i < lg; i++) {
                      if (c == mot_secret[i]) {
                          tab[i] = c;
                          ro = 1;
                      }
                  }
                  if (ro == 0) {
                      printf("Lettre absente ! \n");
                  }
              }
              
              void essai_lettre(char mot_secret[], int lg, char tab[]) {
                  char prop;
              
                  printf("Votre lettre: \n");
                  scanf(" %c", &prop);
                  poser_lettre(prop, mot_secret, lg, tab);
              
              }
              
              int main() {
                  char mot_secret[N];
                  char tab[N];
                  int rep, i, lg, cp = 20;
                  lg = enreg_secr(mot_secret);
                  printf("Le mot secret à %d lettres \n", lg);
                  for (i = 0; i < lg; i++) {
                      tab[i] = '_';
                  }
                  for (i = 0; i < cp; i++) {
                      printf("Contenu du tableau : ");
                      aff_tab(tab, lg);
                      printf("\n Nombre de coup restant: %d", cp);
                      cp--;
                      printf("\n Que voulez-vous proposer ? 1: Un mot, 2: Une lettre \n");
                      if (scanf("%d", &rep) != 1) {
                          printf("Erreur de saisie \n");
                          exit(EXIT_FAILURE);
                      } else {
                          if (rep == 1) {
                              essai_mot(mot_secret);
                          }
                          if (rep == 2) {
                              essai_lettre(mot_secret, lg, tab);
                          }
                          if (rep != 1 && rep != 2) {
                              printf("Ce n'est ni 1 ni 2");
                              exit(EXIT_FAILURE);
                          }
                      }
                  }
                  exit(EXIT_SUCCESS);
              }



              • Partager sur Facebook
              • Partager sur Twitter
                29 octobre 2019 à 13:21:54

                C'est parfait merci ! Maintenant je dois modifier la fonction enreg_secr pour que le mot soit choisit aléatoirement dans un fichier texte, j'ai une idée assez vague de comment faire, je reviendrais sur ce topic si jamais je n'y arrive pas ;)
                • Partager sur Facebook
                • Partager sur Twitter
                  30 octobre 2019 à 13:52:23

                  Rebonjour :D J'ai encore un problème avec ce satané jeu :/

                  Comme dit précédemment, je dois choisir un mot aléatoirement dans un fichier texte (Chaque mot est séparé par un retour à la ligne) mais lorsque j’exécute mon programme j'ai le plus souvent une erreur de segmentation (Je ne me leurre pas, je suis quasiment certain que mon code est faux à chaque fois). Je pense que je ne m'y prends pas de la bonne manière, ma connaissance avec tout ce qui est fichier en C est limitée.

                  Je dois uniquement changer la fonction enreg_secr & la fonction main pour organiser tout ça.

                  Voici le code:

                  int enreg_secr(char mot_secret[]){
                      int lg, i;
                      char mot[N];
                      FILE *f1=NULL;
                      srand(time(NULL)); // Initialisation de time
                      f1=fopen("mots_secrets.txt", "r+"); // J'ouvre le fichier
                      if (f1 == NULL){                                       // Je vérifie s'il est vide
                          printf("Vous tentez d'accéder à un fichier inexistant \n");
                          exit(EXIT_FAILURE);
                      }
                      if (fgets(mot_secret, TAILLE_MAX, f1) != NULL) {
                          i=rand()%strlen(mot_secret)+1;
                          mot[i]=mot_secret[i]; // De mémoire ça ne marche pas mais je n'ai pas trouvé la solution
                          lg=strlen(mot);
                          return (lg - 1);
                      } else 
                          exit(EXIT_FAILURE);
                      fclose(f1);
                  }

                  Merci de votre aide !
                   

                  (J'ai compilé ce programme, j'ai corrigé les erreurs "basiques" mais ça me met que le fichier est inexistant)

                  -
                  Edité par MystKun 30 octobre 2019 à 17:39:57

                  • Partager sur Facebook
                  • Partager sur Twitter
                    30 octobre 2019 à 18:41:06

                    Bonjour,

                    si tu veux le ième mot du fichier c'est mal barré.

                    Combien de mots comporte le fichier?

                    tu as bien conscience que mot[i] correspond à la ième lettre dans la chaine (ou tableau de caractères) mot.

                    Si tu veux le ième mot du fichier, tu dois d'abord lire les i-1 mots précédent, c'est un accès séquentiel.

                    • Partager sur Facebook
                    • Partager sur Twitter
                      30 octobre 2019 à 19:09:24

                      Hum je vois ce que tu veux dire ! J'ai refais le code en m'inspirant d'un code de pendu disponible sur OpenClassroom et ça me donne ça:

                      int enreg_secret(char mot_secret[]){
                          FILE *f1=NULL;
                          int nbrMots, num, carac, lg;
                          nbrMots=0;
                          num=0;
                          carac=0;
                          srand(time(NULL));
                          f1=fopen("mots-secrets.txt", "r");
                          if (f1 == NULL){
                              printf("Fichier vide \n");
                              exit(EXIT_FAILURE);
                          }
                          while (carac!=EOF){
                              carac=fgetc(f1);
                              if (carac=="\n"){
                                  nbrMots+=nbrMots;
                              }
                          }
                          num=rand()% nbrMots+1;
                          rewind(f1) /* Pour retourner au début du fichier */ 
                          do{
                              carac=fgetc(f1);
                              if (carac=='\n'){
                                  num-=1;
                              }
                          } while (num > 0)
                          fgets(mot_secret, 100, f1); /* On estimera que le fichier ne fera pas plus de 100 lignes */
                          lg = strlen(mot_secret);
                          mot_secret[lg- 1] = '\0'; /* car fgets recupere le \n du retour chariot */
                          return (lg-1);
                      }

                      Voici l'erreur que cela cause:


                      ex2.c:21:18: warning: comparison between pointer and integer
                               if (carac=="\n"){
                                        ^

                      Le problème étant que lorsque je lance le programme ça me met que le fichier est toujours vide :/


                      -
                      Edité par MystKun 30 octobre 2019 à 19:12:16

                      • Partager sur Facebook
                      • Partager sur Twitter
                        30 octobre 2019 à 19:20:14

                        le warning est explicite, la fonction fgetc lit un caractère, or tu as déclaré carac comme étant un entier.

                        De plus "\n" c'est une chaine de caractère!! attention "\n" n'est pas la même chose que '\n'

                        Le test de tes retour de fonction liées au fichier est trop impréci.

                        Inclu les bibliothèque errno.h et string.h et modifie ainsi:

                        f1=fopen("mots-secrets.txt", "r");
                        if (f1 == NULL){
                                printf("pb ouverture fichier : %s \n", strerror(errno));
                                exit(EXIT_FAILURE);
                            }


                        Regarde les docs pour plus d'infos : http://www.cplusplus.com/reference/cstring/strerror/

                        • Partager sur Facebook
                        • Partager sur Twitter
                          30 octobre 2019 à 19:45:04

                          J'ai apporté les corrections indiquées et j'ai lu le doc (Intéressant comme fonctionnalité d'ailleurs) mais j'ai toujours le problème de fichier inexistant ! Est-ce que ça peut être lier au fait que je suis connecté sur mon PC via X2GO  ? Même en mettant l'adresse exact du fichier le problème persiste.
                          • Partager sur Facebook
                          • Partager sur Twitter
                            30 octobre 2019 à 22:58:47

                            C'est quoi le message d'erreur exact?

                            Ton fichier de mots est-il au même en endroit que ton executable?

                            ton executable se lance sur le serveur si je comprend bien.

                            peux tu mettre ton fichier de mots dans le répertoire /tmp du serveur et faire fopen("/tmp/mots-secrets.txt", "r")

                            • Partager sur Facebook
                            • Partager sur Twitter
                              31 octobre 2019 à 19:46:24

                              Sans savoir pourquoi la fonction marche maintenant juste en mettant le nom du fichier !

                              Désormais je dois demander à l'utilisateur s'il souhaite rajouter des mots, il est donc nécessaire d'utiliser fputs mais dans les paramètres est-ce que c'est possible de mettre une variable ? Genre faire un scanf et toutes les valeurs stockées dedans seront mises dans le fichier ou ça ne se fait pas comme ça ?

                              Et je dois aussi demander à l'utilisateur s'il veut refaire une partie lorsqu'il a terminé, j'ai lu qu'on ne pouvait pas faire d'appel récursif de fonction en C mais dans un autre exercice j'ai écrit "main()" en plein milieu du code et ça marchait, est-ce que c'est comme ça que l'on fait ?

                              • Partager sur Facebook
                              • Partager sur Twitter
                                31 octobre 2019 à 22:29:12

                                pour fputs, comme d'habitude, je propose de regarder la doc:

                                http://www.cplusplus.com/reference/cstdio/fputs/

                                ça répondra déjà à ta première question.

                                après je ne comprend pas trop ce que tu entends par " faire un scanf et toutes les valeurs stockées dedans".

                                Heu non, JAMAIS, on ne fait appel à main dans main!!!

                                si tu dois répéter les instructions du main, il te suffit de faire un do{...}while(condition de maintiens);

                                dans ton main, où ... représente le code que tu dois répéter.

                                ça donne un truc du genre:

                                int main(){
                                char choix;
                                ...
                                do
                                {
                                   //code de mon jeu
                                
                                   printf("voulez vous rejouer (o/n)");
                                   scanf(" %c",&choix);
                                }while(choix=='o');
                                printf("A bientot\n");
                                
                                return 0;
                                }



                                • Partager sur Facebook
                                • Partager sur Twitter
                                  1 novembre 2019 à 11:46:25

                                  3e EDIT: Finalement j'ai résolu tous mes problèmes ! Merci pour l'aide que tu m'as apporté, je n'y serais surement pas arriver sans toi ;)

                                  -
                                  Edité par MystKun 2 novembre 2019 à 10:46:26

                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  Jeu C

                                  × 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