Partage
  • Partager sur Facebook
  • Partager sur Twitter

Jeu du Mastermind

    20 février 2023 à 19:33:46

    Bonjour

    J'apprends actuellement le C et lors d'un exercice, je me heurte à une difficulté que je n'arrive pas à résoudre.

    Voici mon code:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        printf("TP7: Les tableaux\n");
    
        // constantes
        const int MAX_TENTATIVES = 3;
        const int NOMBRE_COULEUR = 5;
        const char COULEURS[] = {'R', 'V', 'B', 'J', 'O' };
        const int TAILLE_CODE = 4;
    
        // variables
        char code_secret[] = { 'R', 'V', 'B', 'J' };
        char saisie_utilisateur[TAILLE_CODE];
    
        for(int nb_tentatives=1; nb_tentatives <= MAX_TENTATIVES; nb_tentatives++)
        {
            // lecture saisie utiolisateur
            printf("Donnez un code de 4 couleurs parmis {'R', 'V', 'B', 'J', 'O'}\n");
            fflush(stdin);
    
            // utilisation des pointeurs pour le tableau
            scanf("%c%c%c%c", saisie_utilisateur,(saisie_utilisateur+1), (saisie_utilisateur+2), (saisie_utilisateur+3));
    
            printf("/%c/%c/%c/%c/\n", saisie_utilisateur[0], saisie_utilisateur[1], saisie_utilisateur[2], saisie_utilisateur[3]);
    
            // init des compteurs
            int nb_couleur_place = 0;
    
            // comparaison du code secret et de la saisie utilisateur
            for(int i= 0; i <TAILLE_CODE; i++)
            {
                if(code_secret[i] == saisie_utilisateur[i])
                {
                    nb_couleur_place++;
                }
            }
    
            // gestion fin de partie
            if(nb_couleur_place == TAILLE_CODE)
            {
                printf("Bravo! vous avez trouve le code secret en %d tentatives\n", nb_tentatives);
            }
            else if(nb_tentatives >= MAX_TENTATIVES)
            {
                printf("Dommage! vous avez depasse le nombre maximun de tentatives");
                printf("Le bon code est %c%c%c%c", code_secret[0], code_secret[1], code_secret[2], code_secret[3]);
            }
            else
            {
                printf("\t Tentative %d/%d\n", nb_tentatives, MAX_TENTATIVES);
                printf("Couleurs bien placees: %d\n\n", nb_couleur_place);
            }
    
        }
    
    
        return 0;
    }

    et voici ce que j'obtiens dans la console :

    Merci de votre aide

    -
    Edité par philduweb 20 février 2023 à 19:34:06

    • Partager sur Facebook
    • Partager sur Twitter
      21 février 2023 à 1:31:09

      Tu ne dis pas ce que tu attends.
      Ta boucle sur le nombre de tentatives n'est pas appropriée.
      Je verrais des boucles  do ... while
      do {
          initialiser nombre d'essai
          (on pourrait initialiser ici le code mystère)
          do {
              on lit le code de l'utilisateur
              on vérifie le nombre de couleurs bien placées
              nombre essais++
              On affiche le nombre d'essais et le nombre de couleurs bien placées.
          } while(nombre essais < maximum && nombre couleurs != nombre couleurs en place);
          On donne le résultat
          On demande si on veut rejouer
      } while(continuer);
      • Partager sur Facebook
      • Partager sur Twitter

      Le Tout est souvent plus grand que la somme de ses parties.

        21 février 2023 à 8:23:46

        Quand l'utilisateur saisit sa première réponse, il tape un saut de ligne à la fin.

        Ce caractère n'est pas consommé par le premier scanf, il est gardé pour  plus tard. On le voit parasiter la seconde réponse (le / tout seul à la 2ieme ligne de la boîte 2ieme saisie)

        Plusieurs solutions possibles, dont :  saisir un "mot"  dans une chaîne avec format %s,  plutôt que des caractères. Ou une ligne complète par fgets /readline / ....

        -
        Edité par michelbillaud 21 février 2023 à 8:28:03

        • Partager sur Facebook
        • Partager sur Twitter
          21 février 2023 à 8:39:22

          Ajouter un espace au début de la chaine de format du scanf permet de 'consommer' un caractère résiduel éventuel,

          scanf(" %c%c%c%c", ...

          mais les solutions données plus haut sont à privilégier.

          -
          Edité par magma 21 février 2023 à 8:44:53

          • Partager sur Facebook
          • Partager sur Twitter
            21 février 2023 à 10:21:58

            Merci pour votre aide

            Je croyais que le fflush() servait justement à "purger" d'éventuels caractères en trop.

            Je viens de trouver ça aussi:

            #define FFLUSH_MY_STDIN() {int _c_; while ((_c_ = getchar()) != '\n' && _c_ != EOF){}}

            à utiliser après mon scanf(...)

            scanf("%c%c%c%c", saisie_utilisateur,(saisie_utilisateur+1), (saisie_utilisateur+2), (saisie_utilisateur+3));
            FFLUSH_MY_STDIN();

            Un avis ?


            -
            Edité par philduweb 21 février 2023 à 10:48:50

            • Partager sur Facebook
            • Partager sur Twitter
              21 février 2023 à 11:33:34

              > Un avis ?

              Si on commence à mélanger les scanf, les getchar, etc, ça sent le bricolage maladroit.

              Une autre possibilité

              • l'utilisateur cause avec le programme en tapant des LIGNES
              • le programme regarde si la ligne tapée contient ce qu'on veut
              Exemple
              #define _POSIX_C_SOURCE 200809L
              
              #include <stdio.h>
              #include <stdlib.h>
              #include <stdbool.h>
              
              #include <ctype.h>
              
              
              void process_line(char * line)
              { 
                char letters[4 + 1];
                int nb_letters = 0;
                for (int i = 0; line[i]; i++) {
              	  if (isalpha(line[i])) {
              		  if(nb_letters < 4) {
              			  letters[nb_letters++] = line[i];
              		  } else {
              			  printf("!!! Trop de lettres\n");
              				   return;
              		  };
              	  }
                }
                if (nb_letters < 4) {
              	  printf("!!! Pas assez de lettres\n");
              	  return;
                }
                letters[4] = '\0';
                printf("==> Lettres lues = %s\n", letters); 
              }
              
              
              int main() {
                  char *line = NULL;
              	ssize_t size = 0;
              
              	for(;;) {		
              	   printf("tapez 4 caractères\n");
              	   if (getline(& line, &size, stdin) < 0) {
              		   break;
              	   }
              	   process_line(line);
              	}
              	free(line);
              }
              
              
              En utilisant getline, qui [re]-alloue un tampon assez grand pour y mettre la ligne complète, sans s'enquiquiner à gérer les problèles avec les lignes trop longues de fegets et cie.
              getline() est une fonction standard Posix depuis 2008, facile à remplacer si on programme sur un OS à la con qui n'a pas ça.
              Compilation + Exécution
              $ make lire-4-caracteres
              cc     lire-4-caracteres.c   -o lire-4-caracteres
              
              $ ./lire-4-caracteres 
              apez 4 caractères
              abcde
              !!! Trop de lettres
              tapez 4 caractères
              xyz
              !!! Pas assez de lettres
              tapez 4 caractères
              abcd
              ==> Lettres lues = abcd
              tapez 4 caractères
               a     b     c    d 
              ==> Lettres lues = abcd
              tapez 4 caractères
              [ctrl-D]
              $
              



              -
              Edité par michelbillaud 21 février 2023 à 11:38:39

              • Partager sur Facebook
              • Partager sur Twitter

              Jeu du Mastermind

              × 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