Jeu de code mystère en C
Résolu/Fermémamiemando Messages postés 33459 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 8 janvier 2025 - 13 janv. 2023 à 03:19
- Jeu de code mystère en C
- Le code ascii en informatique - Guide
- Code puk bloqué - Guide
- Code de déverrouillage oublié - Guide
- Code activation windows 10 - Guide
- Jeu zuma - Télécharger - Jeux vidéo
3 réponses
Je ne suis pas spécialiste en c, mais tout de même ton compilateur doit bien t'indiquer ce qui cloche non ?
do{ if (nombreJuste==tab[i]) { tab[i]='+'; } }while(!quitter);
D'où sort le i ? Où est-il initialisé ? où est l'incrémentation ?
Où est effectué l'affectation d'une valeur à nombreJuste ?
tab est un tableau d'entier, pourquoi veux-tu y stocker un caractère ? Il te faudra forcément un autre tableau pour stocker ces +, -, ~
De plus tu ne sortira jamais de ta boucle puisque jamais tu ne donnes une valeur à quitter permettant de sortir du while, pourquoi un while d'abord, et pourquoi la condition est la valeur de quitter ?
Tant de choses ne vont pas, que c'est mal barré pour ce soir XD
#include <stdio.h> #include <stdlib.h> #include <time.h> #define LANCER 5 int main(void) { int tab[10]; srand(time(NULL)); int quitter = 0, nombreJuste,i, nombreBienPlaces, nombreEssais=0; char bien1=; do { printf("Menu ...\n"); for(int i = 0; i < 10; i++) tab[i] = i; for(int i = 0; i < LANCER; i++) { int j = rand() % 10; int temp = tab[i]; tab[i] = tab[j]; tab[j] = temp; } for(int i = 0; i < LANCER; i++) printf("%d ", tab[i]); printf("\n"); int fini = 0; printf("Vous allez dès à présent deviner les chiffres. Si le chiffre est bien placé, ('+'), présent mais mal placé ('∼') et s'il n'est pas présent, ('-'). \n"); printf("Donner moi un nombre entre 0 et 9\n"); do{ nombreBienPlaces=0; nombreEssais++; scanf("%d", &nombreJuste); if (nombreJuste==tab[i] || nombreJuste==tab[i+1]) { tab[i]=bien1; printf("%d\n", tab[i]); nombreBienPlaces=nombreBienPlaces+1; } }while(nombreBienPlaces==5); do { // Jusqu'à ce que ça soit fini ... fini = 1; // Je décide que c'est fini ... } while(!fini); printf("Voulez-vous quitter? (0 = non, 1 = oui) "); scanf("%d", &quitter); } while(!quitter); return 0; }
J'ai fais déjà des modifications mais effectivement je ne vois pas comment faire pour transformer la valeur du tableau [i] en +
Modifié le 12 janv. 2023 à 01:53
Bonjour,
Tout d'abord, pardon de répondre alors que la date butoir est passée, mais j'espère que ma réponse t'aidera à progresser.
- Concernant le tirage : il n'est pas stipulé que les nombres du code secret doivent être distincts. Tu t'es donc un peu compliqué la vie.
- Concernant la compilation : il manque quelque chose ligne 9
- Concernant l'indentation : tu as, vu l'indentation, sûrement oublier de mettre une accolade ouvrante à la fin de la ligne 19 et une accolade fermante entre les ligne 21 et 22
- Concernant la structure du code : il aurait sans doute été une bonne idée de faire des fonctions pour rendre le code plus lisible et plus modulaire.
- Concernant ta question : il suffit de créer un tableau auxiliaire que j'ai appelé code_reponse de type char[] dans lequel tu vas écrire les caractères associés à chaque chiffre proposé. Après, tu peux même te passer de ce tableau auxiliaire et afficher directement les caractères au fur et à mesure de la comparaison entre le code secret et le code saisi.
Quelques remarques préalables pour comprendre ce qui suit :
- Comme on travaille avec des entiers positifs dans tout le code, j'ai utilisé le type size_t partout au lieu de int (et son format correspondant, %zu au lieu de %d).
- Pour nos fonctions, on a besoin de passer des tableaux en paramètre.
- En C, cela revient à passer l'adresse du début du tableau (tab). Comme cette adresse ne véhicule pas la taille du tableau, il faut donc également la passer en paramètre (n).
- Pour rappel, la notation tab[i] signifie lire la i-ème valeur (conformément au type de "case" associé au tableau) en lisant la valeur qui se trouve à l'adresse tab + i fois la taille d'une case.
- Dit autrement, il n'y a pas réellement de notion de tableau en C, c'est juste un jeu d'écriture, mais fondamentalement, il n'est question que d'adresses mémoires.
Voici à quoi peut ressembler ton code une fois modifié :
- n correspond au nombre de chiffres impliqués dans le code
- k correspond à la valeur maximale que peut prendre un chiffre du code secret
#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <time.h> void creer_code(size_t * code, size_t n, size_t k) { for (size_t i = 0; i < n; i++) { code[i] = rand() % (k + 1); } } void afficher_code(const size_t * code, size_t n) { for (size_t i = 0; i < n; i++) { printf("%zu ", code[i]); } printf("\n"); } void afficher_code_reponse(const char * code_reponse, size_t n) { for (size_t i = 0; i < n; i++) { printf("%c ", code_reponse[i]); } printf("\n"); } void saisir_code(size_t * code, size_t n, size_t k) { int ret; for (size_t i = 0; i < n; i++) { do { printf("Saisir le chiffre %zu / %zu: ", i + 1, n); ret = scanf("%zu", &code[i]); } while (ret != 1 || code[i] >= k || code[i] <= 0); } printf("Code saisi : "); afficher_code(code, n); } bool code_contient(const size_t * code, size_t n, size_t chiffre) { for (size_t i = 0; i < n; i++) { if (code[i] == chiffre) { return true; } } return false; } size_t comparer_codes( const size_t * code_secret, const size_t * code_saisi, char * code_reponse, size_t n ) { size_t num_corrects = 0; for (size_t i = 0; i < n; i++) { size_t chiffre = code_saisi[i]; if (chiffre == code_secret[i]) { code_reponse[i] = '+'; num_corrects++; } else if (code_contient(code_secret, n, chiffre)) { code_reponse[i] = '~'; } else { code_reponse[i] = '-'; } } afficher_code_reponse(code_reponse, n); return num_corrects; } int lancer_partie(const size_t * code_secret, size_t n, size_t k, size_t max_essais) { size_t code_saisi[n]; char code_reponse[n]; size_t num_corrects; for (size_t essai = 0; essai < max_essais; essai++) { printf("Essai %zu / %zu\n", essai + 1, max_essais); saisir_code(code_saisi, n, k); num_corrects = comparer_codes(code_secret, code_saisi, code_reponse, n); if (num_corrects == n) { return 1; // Victoire } } return 0; // Défaite } int main() { size_t code_secret[5]; srand(time(NULL)); size_t quitter = 0, n = 5, k = 9, max_essais = 10; do { creer_code(code_secret, n, k); printf("Code secret : "); afficher_code(code_secret, n); lancer_partie(code_secret, n, k, max_essais); printf("Voulez-vous quitter? (0 = non, 1 = oui) "); scanf("%d", &quitter); } while(!quitter); return 0; }
Résultat :
(mando@aldur) (~) $ gcc toto.c
(mando@aldur) (~) $ ./a.out
Code secret : 1 3 2 5 5
Essai 1 / 10
Saisir le chiffre 1 / 5: 1
Saisir le chiffre 2 / 5: 2
Saisir le chiffre 3 / 5: 3
Saisir le chiffre 4 / 5: 4
Saisir le chiffre 5 / 5: 5
Code saisi : 1 2 3 4 5
+ ~ ~ - +
Essai 2 / 10
Saisir le chiffre 1 / 5: 1
Saisir le chiffre 2 / 5: 3
Saisir le chiffre 3 / 5: 2
Saisir le chiffre 4 / 5: 5
Saisir le chiffre 5 / 5: 5
Code saisi : 1 3 2 5 5
+ + + + +
Voulez-vous quitter? (0 = non, 1 = oui) 1
Bonne chance
12 janv. 2023 à 19:06
@mamiemando StatutModérateur
Ton code est très bien.
J'aurais juste, en ligne 65, retiré cette ligne "afficher_code_reponse(code_reponse, n);" de la fonction comparer_codes() et je l'aurais intégrée à la fonction lancer_partie() qui gère une partie et à laquelle on peut laisser la responsabilité de lancer l'affichage de code_reponse.
Ainsi, la fonction de comparaison est dissociée de celle gérant l'affichage.
Cela présente aussi l'avantage, pour comparer_codes(), de pouvoir être testée indépendamment, sans que les tests ne génèrent des affichages inutiles.
On peut alors écrire :
#include <string.h> #include <assert.h> int main(void) { { const size_t code_secret[] = { 1, 3, 2, 5, 5 }; size_t code_saisi[] = { 1, 2, 3, 4, 5 }; char code_reponse[5]; size_t num_corrects = comparer_codes(code_secret, code_saisi, code_reponse, 5); char code_reponse_attendu[5] = { '+', '~', '~', '-', '+' }; assert(memcmp(code_reponse, code_reponse_attendu, 5) == 0 && "trouvés 1er et dernier, mal placés 2ème et 3ème et 4ème inexistant"); assert(num_corrects == 2); } return 0; }
13 janv. 2023 à 03:19
Tu as entièrement raison, c'est un oubli de couper coller. Merci pour ta remarque.