A voir également:
- "Changer taille tableau de chaine de caractère en C"
- Changer dns - Guide
- Caractère ascii - Guide
- Tableau croisé dynamique - Guide
- Comment réduire la taille d'un fichier - Guide
- Tableau word - Guide
4 réponses
yg_be
Messages postés
23405
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
20 décembre 2024
Ambassadeur
1 557
4 janv. 2022 à 19:42
4 janv. 2022 à 19:42
bonjour,
peux-tu partager la source de ton programme?
merci d'utiliser les balises de code: https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code
Pour empêcher une duplication, ne suffit-il pas de réduire le choix au moment de tirer un nombre aléatoire?
Je suis surpris que la carte tirée ne se mette pas au début du tableau 2: est-ce intentionnel?
peux-tu partager la source de ton programme?
merci d'utiliser les balises de code: https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code
Pour empêcher une duplication, ne suffit-il pas de réduire le choix au moment de tirer un nombre aléatoire?
Je suis surpris que la carte tirée ne se mette pas au début du tableau 2: est-ce intentionnel?
Dalfab
Messages postés
706
Date d'inscription
dimanche 7 février 2016
Statut
Membre
Dernière intervention
2 novembre 2023
101
4 janv. 2022 à 20:37
4 janv. 2022 à 20:37
Bonjour,
Ta méthode n'est pas la plus simple.
En tout cas, il semble que ton
Ta méthode n'est pas la plus simple.
En tout cas, il semble que ton
memmove()n'a pas les bons paramètres.
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
Modifié le 4 janv. 2022 à 23:19
Modifié le 4 janv. 2022 à 23:19
Salut loki9678,
Comme le dit Dalfab, ta méthode est compliquée... en fait, c'est une usine à gaz :-)
Pour mélanger tes cartes et les tirer une à une, fais comme avec un vrai paquet de cartes :
1. tu mélanges le paquet : fais un shuffle du tableau de 16 éléments, ton tableau contient maintenant tes cartes dans un ordre aléatoire
2. la carte du dessus est : carte_courante = 0
3. tu prends la carte du dessus : tableau[carte_courante]
4. tu incrémentes carte_courante tant qu'il y a des cartes restant à tirer et tu boucles sur 3
Tu fais tout ceci avec un seul tableau et sans avoir à décaler quoi que ce soit ou faire quoi que ce soit d'autre qu'incrémenter l'index après avoir mélangé le contenu du tableau.
Pour faire un bon shuffle renseigne toi sur le mélange Fisher-Yates. Outre la méthode de mélange, tu peux aussi envisager d'utiliser un générateur de nombres aléatoires plus performant que rand() si tu veux un mélange évitant les biais de la fonction standard.
Dal
Comme le dit Dalfab, ta méthode est compliquée... en fait, c'est une usine à gaz :-)
Pour mélanger tes cartes et les tirer une à une, fais comme avec un vrai paquet de cartes :
1. tu mélanges le paquet : fais un shuffle du tableau de 16 éléments, ton tableau contient maintenant tes cartes dans un ordre aléatoire
2. la carte du dessus est : carte_courante = 0
3. tu prends la carte du dessus : tableau[carte_courante]
4. tu incrémentes carte_courante tant qu'il y a des cartes restant à tirer et tu boucles sur 3
Tu fais tout ceci avec un seul tableau et sans avoir à décaler quoi que ce soit ou faire quoi que ce soit d'autre qu'incrémenter l'index après avoir mélangé le contenu du tableau.
Pour faire un bon shuffle renseigne toi sur le mélange Fisher-Yates. Outre la méthode de mélange, tu peux aussi envisager d'utiliser un générateur de nombres aléatoires plus performant que rand() si tu veux un mélange évitant les biais de la fonction standard.
Dal
Bonjour Dal,
Merci de votre réponse.
Si j'ai bien compris vous me conseillez de créer un tableau de 16 cartes. Ensuite de mélanger ce tableau avec un shuffle que je devrais potentiellement faire avec la méthode de Fisher-Yates. Et ensuite de tirer les cartes 1 par 1 et dans l'ordre du nouveau tableau mélangé ? Peut-être avec une boucle for je pense
Loki9678
Merci de votre réponse.
Si j'ai bien compris vous me conseillez de créer un tableau de 16 cartes. Ensuite de mélanger ce tableau avec un shuffle que je devrais potentiellement faire avec la méthode de Fisher-Yates. Et ensuite de tirer les cartes 1 par 1 et dans l'ordre du nouveau tableau mélangé ? Peut-être avec une boucle for je pense
Loki9678
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
>
loki9678
Modifié le 5 janv. 2022 à 12:41
Modifié le 5 janv. 2022 à 12:41
Oui, c'est cela.
Pour tirer les cartes, il suffit de parcourir le tableau des cartes après mélange, et tu es sûr qu'il n'y a pas de répétitions.
Pour le mélange, tu peux utiliser la méthode que tu veux, mais celle de Fisher-Yates est fiable et simple.
Pour tirer les cartes, il suffit de parcourir le tableau des cartes après mélange, et tu es sûr qu'il n'y a pas de répétitions.
Pour le mélange, tu peux utiliser la méthode que tu veux, mais celle de Fisher-Yates est fiable et simple.
loki9678
>
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
5 janv. 2022 à 16:09
5 janv. 2022 à 16:09
J'ai essayé alors la méthode de Fisher-Yates cependant je crois que le fait que mon tableau soit composé de chaine de caractère empêche le bon fonctionnement du programme.
Voici le nouveau code:
Et voici ce qui ce passe quand j'essaye d'afficher la pioche mélangée:
carte 1
carte 2
carte 3
carte 4
carte 5
carte 6
carte 7
carte 8
carte 9
carte 10
carte 11
carte 12
carte 13
carte 14
carte 15
carte 16
Entrez 0 pour piocher:
0
Process returned -1073741819 (0xC0000005) execution time : 7.086 s
Press any key to continue.
Sauriez vous quelle est l'erreur? Sans vouloir pomper votre temps :)
Merci
Voici le nouveau code:
int main() { int nombreAuSort1, entree,i,j; char tampon[10]; char pioche1[16][10] = {"carte 1","carte 2","carte 3","carte 4","carte 5","carte 6","carte 7","carte 8", "carte 9","carte 10","carte 11","carte 12","carte 13","carte 14","carte 15","carte 16" }; srand(time(NULL)); while(pioche1[6]!='\0') { for(i=0; i<16; i++) { printf("%s\n",pioche1[i]); } printf("Entrez 0 pour piocher:\n"); scanf("%d",&entree); while(entree!=0) { getchar(); printf("Entrez 0 pour piocher(vous n'avez pas selectionne 0):\n"); scanf("%d",&entree); } if(entree==0) { for(i=15; i>=0; i--) { j=rand()%(i); strcpy(tampon[0],pioche1[i]); strcpy(pioche1[i],pioche1[j]); strcpy(pioche1[j],tampon[0]); } printf("Votre carte est :%s", pioche1[0]); for(i=0; i<16; i++) { printf("%s\n",pioche1[i]); printf("%s\n",pioche1[i]); } } } }
Et voici ce qui ce passe quand j'essaye d'afficher la pioche mélangée:
carte 1
carte 2
carte 3
carte 4
carte 5
carte 6
carte 7
carte 8
carte 9
carte 10
carte 11
carte 12
carte 13
carte 14
carte 15
carte 16
Entrez 0 pour piocher:
0
Process returned -1073741819 (0xC0000005) execution time : 7.086 s
Press any key to continue.
Sauriez vous quelle est l'erreur? Sans vouloir pomper votre temps :)
Merci
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
>
loki9678
Modifié le 5 janv. 2022 à 18:00
Modifié le 5 janv. 2022 à 18:00
- tu dois mélanger ton tableau de chaînes avant de faire tes "tirages"
- un "tirage" est ensuite le passage d'un indice à un autre du tableau, tu n'utilises plus rand()
- la partie du code en lignes 26 à 32 qui semble faire le mélange ne suit pas exactement l'algorithme :
Pour mélanger un tableau a de n éléments (indicés de 0 à n-1), l'algorithme est le suivant.
Pour i allant de n − 1 à 1 faire :
j ← entier aléatoire entre 0 et i
échanger a[j] et a[i]
https://fr.wikipedia.org/wiki/M%C3%A9lange_de_Fisher-Yates
Je vais voir si je peux te faire un exemple simplifié.
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
Modifié le 5 janv. 2022 à 18:57
Modifié le 5 janv. 2022 à 18:57
Voilà un exemple fonctionnel :
Dal
Edit : correction de la boucle for pour traiter la dernière permutation
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> int main(void) { char tampon[10]; char pioche[16][10] = { "carte 1","carte 2","carte 3","carte 4", "carte 5","carte 6","carte 7","carte 8", "carte 9","carte 10","carte 11","carte 12", "carte 13","carte 14","carte 15","carte 16" }; srand(time(NULL)); /* mélange de Fisher-Yates de la pioche * cf. https://fr.wikipedia.org/wiki/M%C3%A9lange_de_Fisher-Yates */ for (int i = 15; i > 0; i--) { int j = rand() % i; strcpy(tampon, pioche[i]); strcpy(pioche[i], pioche[j]); strcpy(pioche[j], tampon); } /* tirage de cartes */ int carte_courante = 0; while (1) { printf("Tapez n'importe qu'elle touche pour piocher " "(ou 'q' pour quitter)\n"); int ch = getchar(); if (ch == 'q') break; printf("Tirage n°%d - vous avez pioché : %s\n", carte_courante + 1, pioche[carte_courante]); carte_courante++; if (carte_courante > 15) { printf("Vous avez tiré toutes les cartes du paquet\n"); break; } } return 0; }
Dal
Edit : correction de la boucle for pour traiter la dernière permutation
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
>
loki9678
Modifié le 5 janv. 2022 à 19:13
Modifié le 5 janv. 2022 à 19:13
Si tu tapes juste Entrée, tu ne devrais pas voir cela.
C'est effectivement "normal", car si tu tapes un caractère (autre que 'q' qui fait sortir de la boucle) et Entrée, tu as en fait tapé 2 char qui sont consommés successivement par 2 appels à getchar() ... et si tu tapes "toto, titi et tata + Entrée" parce que tu es un rebelle tu auras tapé 19 char et cela fera autant de tirages.
Tu pourrais modifier le code pour purger stdin avant de boucler pour éviter ce genre de choses.
Tu peux modifier cet exemple comme tu veux, mais c'est un peu bizarre de demander à quelqu'un de taper 0 pour faire quelque chose.
C'est juste un exemple rapide. La gestion de la saisie ou intéraction avec l'utilisateur au clavier en C n'est pas quelque chose de trivial si tu veux faire quelque chose de robuste.
C'est effectivement "normal", car si tu tapes un caractère (autre que 'q' qui fait sortir de la boucle) et Entrée, tu as en fait tapé 2 char qui sont consommés successivement par 2 appels à getchar() ... et si tu tapes "toto, titi et tata + Entrée" parce que tu es un rebelle tu auras tapé 19 char et cela fera autant de tirages.
Tu pourrais modifier le code pour purger stdin avant de boucler pour éviter ce genre de choses.
Tu peux modifier cet exemple comme tu veux, mais c'est un peu bizarre de demander à quelqu'un de taper 0 pour faire quelque chose.
C'est juste un exemple rapide. La gestion de la saisie ou intéraction avec l'utilisateur au clavier en C n'est pas quelque chose de trivial si tu veux faire quelque chose de robuste.
loki9678
>
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
5 janv. 2022 à 19:21
5 janv. 2022 à 19:21
Merci beaucoup.
J'ai enfin compris et je vais juste essayer de faire en sorte que la carte tirée se place à la "fin du paquet".
Enfaite je fais un UNO dans lequel il y a un tirage de carte donc j'ai choisi temporairement la touche 0 pour tirer mais je la changerais plus tard.
Et durant le jeu avec une certaine condition il pourra tirer dans la pioche et donc je devrais afficher quelque chose qui lui permettra de tirer. Je trouvais cela plus facile.
J'ai enfin compris et je vais juste essayer de faire en sorte que la carte tirée se place à la "fin du paquet".
Enfaite je fais un UNO dans lequel il y a un tirage de carte donc j'ai choisi temporairement la touche 0 pour tirer mais je la changerais plus tard.
Et durant le jeu avec une certaine condition il pourra tirer dans la pioche et donc je devrais afficher quelque chose qui lui permettra de tirer. Je trouvais cela plus facile.
5 janv. 2022 à 10:59
Voici mon code:
Je l'ai un peu modifié depuis hier et comme ca il affiche plus de double. Cependant étant donné que avec la fonction memmove je "décale" les nombres dans le tableau ce dernier affiche donc des cases vides et mon programmes tire du vide a partir de quelques tirages.
Et le fait que la carte ne se mettent pas au début du tableau n'est pas réellement intentionnel je lui ai juste affecté la même place dans le tableau 2. Mais l'ordre importe peu étant donné que c'est une pioche.
Modifié le 5 janv. 2022 à 11:34
1) en ligne 22, tu continues à piocher parmi les 16 premières cartes, au lieu de tenir compte du nombre de cartes restantes.
2) en ligne 28, tu décales beaucoup trop de cartes.