Mélange foireux

Mélange foireux - C - Programmation

Marsh Posté le 19-01-2006 à 14:57:45    

Salut tout le monde,
 
J'ai un souci avec un bout de code qui doit mélanger un tableau. J'ai un résultat pas très convaincant : :sleep:  
 
http://a2sa2sin.free.fr/melangepourri.gif
 
Voilà le coupable :
 

Code :
  1. srand((int)time(NULL));
  2. for (i=0; i < 2; i++)
  3. {
  4. for (j=0; j < (NBCARTES * 4); j++)
  5. {
  6.  // on tire une carte au hasard      
  7.  val = (rand() % ((NBCARTES * 4)- j)) + j;
  8.  // on modifie son emplacement dans la suite des 52 cartes
  9.  permuter(&(tabCartes[j]), &(tabCartes[val]));
  10.  // on ajoute la carte au paquet
  11.  ajoutertete(&(jeu->paquet), tabCartes[j]);
  12. }
  13. }


 
tabCartes contient 52 éléments initialisé de la sorte : 1,2,..,12,13,1,2,..,12,13,1,2,..,12,13,1,2,..,12,13
 
Et je ne sais pas comment faire un mélange plus varié parce que là ça fait pitié :o  
 
Voilà, j'ai parcouru les forums en quête d'une réponse recevable, rien te tel, donc si vous avez des idées, faites-les moi savoir. :jap:  
 
Bonne journée. :hello:

Message cité 2 fois
Message édité par Inekman le 19-01-2006 à 14:59:10
Reply

Marsh Posté le 19-01-2006 à 14:57:45   

Reply

Marsh Posté le 19-01-2006 à 15:12:09    

Je ne comprends pas bien la question.
Est-ce que le problème est qu'il y a toujours du trèfle ? ou bien est-ce autre chose, et quoi ?
Quel résultat faut-il obtenir ?
Pourquoi multiplier par 4 ?
C'est pour quel jeu de carte ? Un solitaire ? Un bridge ? Une bataille ?
 
Pour faire avancer le schmlblick, voici ce que j'ai fait pour mon jeu de belote (freeware sur mon site) avec BorlandC qui utilise random au lieu de rand :

Code :
  1. // 3 players takes 8 cards (the last one takes what remains)
  2.    for (player = 1; player < 4; player++)
  3.       for (i = 0; i < MAX_CARDS/4; i++) {
  4.          for (;;) {
  5.             // get random card1
  6.             no = random(MAX_CARDS);
  7.             // check if it was not already drawned
  8.             if (card[no].owner == 0)
  9.                break;
  10.          }
  11.          card[no].owner = player;
  12.       }

Message cité 1 fois
Message édité par olivthill le 19-01-2006 à 15:14:49
Reply

Marsh Posté le 19-01-2006 à 15:14:10    

Inekman a écrit :

J'ai un souci avec un bout de code qui doit mélanger un tableau.
tabCartes contient 52 éléments initialisé de la sorte : 1,2,..,12,13,1,2,..,12,13,1,2,..,12,13,1,2,..,12,13


Problème de modélisation. Un jeu de carte, c'est pas un tableau à 2 dimensions. C'est un tableau de 52 cartes. Chaque carte est définie par un couple valeur/couleur. C'est donc un tableau de structures.
 
Pour le mélange, c'est simple. Remplir le tableau avec des valeurs uniques et triées (c'est le meilleur moyen de ne pas en oublier), puis mélanger (Internet ne manque pas d'algorithmes 'shuffle') : Tirer (pseudo-aléatoirement) un certain nombre (disons 10 fois le nombre de cartes, au minimum) de couples d'indices [0-51] differents i, j, et inverser les contenus du tableau à ces indices.
 
C'est surtout une question d'algo, le codage en C étant trivial...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 19-01-2006 à 15:24:22    

Je vais être plus clair ^^
 
Le jeu en question est le Spider Solitaire, qui se joue selon 3 niveaux (Facile = 1 couleur, Moyen = 2 couleurs, Difficile = 4 couleurs) où le but du jeu est de déplacer des cartes pour former des suites décroissantes, de même couleurs partant du Roi vers l'As. Pour l'exemple, j'ai utilisé le niveau Facile, d'où le fait qu'il n'y a qu'une seule couleur.
 

Citation :

Est-ce que le problème est qu'il y a toujours du trèfle ?

 
-> Nop, voir plus haut :)  
 

Citation :

ou bien est-ce autre chose, et quoi ?


-> Oui c'est autre chose, voir plus bas :D  
 

Citation :

Quel résultat faut-il obtenir ?


-> Un plateau de jeux avec des cartes vraiment différentes. Normalement les première lignes devraient être cachées (étoilées) seule la dernière sera visible. Au fur et à mesure du jeu, des déplacements, les cartes seront petit à petit visible. Donc si on imagine qu'on a ce plateau en ne voyant que la dernière ligne, on se tape 2 As, 2 Deux, 2 Trois, 2 Quatre, 1 Valet et 1 Dame. Vous allez me dire, "ben on peut jouer", oui mais c'est sûr mais v'la la gueule du plateau. Su un choix de 13 cartes on s'en tape 6 en doubles. Surtout que les cartes qui suivent (juste au dessus de la dernière ligne) ne sont pas franchement différentes de la dernière ligne...donc vous voyez un peu, c'est pas tip top :sweat:  
 

Citation :

Pourquoi multiplier par 4 ?


-> J'ai un tableau de 52 cartes. NBCARTES vaut 13, NBCARTES * 4 vaut 52. :)  
 

Citation :

C'est pour quel jeu de carte ? Un solitaire ? Un bridge ? Une bataille ?


-> Le Spider Solitaire  :)  
 
Voilà voilà. Je vais jeter un oeil à ton code. :jap:

Reply

Marsh Posté le 19-01-2006 à 15:26:57    

Inekman a écrit :

Salut tout le monde,
 
J'ai un souci avec un bout de code qui doit mélanger un tableau. J'ai un résultat pas très convaincant : :sleep:  
 
http://a2sa2sin.free.fr/melangepourri.gif
 
Voilà le coupable :
 

Code :
  1. srand((int)time(NULL));
  2. for (i=0; i < 2; i++)
  3. {
  4. for (j=0; j < (NBCARTES * 4); j++)
  5. {
  6.  // on tire une carte au hasard      
  7.  val = (rand() % ((NBCARTES * 4)- j)) + j;
  8.  // on modifie son emplacement dans la suite des 52 cartes
  9.  permuter(&(tabCartes[j]), &(tabCartes[val]));
  10.  // on ajoute la carte au paquet
  11.  ajoutertete(&(jeu->paquet), tabCartes[j]);
  12. }
  13. }


 
tabCartes contient 52 éléments initialisé de la sorte : 1,2,..,12,13,1,2,..,12,13,1,2,..,12,13,1,2,..,12,13
 
Et je ne sais pas comment faire un mélange plus varié parce que là ça fait pitié :o  
 
Voilà, j'ai parcouru les forums en quête d'une réponse recevable, rien te tel, donc si vous avez des idées, faites-les moi savoir. :jap:  
 
Bonne journée. :hello:


 
Bon, déjà "(NBCARTES * 4) - j" peut aussi bien s'écrire "NBCARTES * 4 - j". Ca allège la lecture d'éviter les parenthèses inutiles et la priorité de la soustraction par rapport à la multiplication est un sujet étudié au cm2.
 
Ensuite, pour avoir un aléa régulier entre "0" et "n", il vaut mieux utiliser
"(double)rand() / (RAND_MAX + 1) * n". Le nombre généré est mieux distribué que dans un simple "rand() % n". La démo est ici => http://dejean.benoit.free.fr/code/rand.c.html
 
Sinon, comme l'a dit Emmanuel, il serait bien de commencer par penser à la modélisation de ton jeu de cartes avant de vouloir le mélanger.

Reply

Marsh Posté le 19-01-2006 à 15:31:31    

Emmanuel Delahaye a écrit :

Problème de modélisation. Un jeu de carte, c'est pas un tableau à 2 dimensions.


-> Ce n'est pas ce que j'ai fait. Tu as mal comprendre ce que j'ai "essayé" de (mal) représenter. J'ai bien un tableau de 52 cartes, mais le tableau est remplie avec 4 jeux de cartes partant de 1 à 13, d'où mon truc bizarre qui fait pensé à une déclaration de tableau à plusieur dimensions à cause des ".." qui sépare les valeurs des cases de mon tableau :sleep:  
 

Emmanuel Delahaye a écrit :

C'est un tableau de 52 cartes. Chaque carte est définie par un couple valeur/couleur. C'est donc un tableau de structures.


-> Non non t'inquiètes, c'est bien ce que j'ai fait de mon côté, mais je ne vais pas mettre tout le code ici car c'est pas ça le problème. :)
 

Emmanuel Delahaye a écrit :

Pour le mélange, c'est simple. Remplir le tableau avec des valeurs uniques et triées (c'est le meilleur moyen de ne pas en oublier),


-> C'est ce que j'ai fait dans ma variable "tabCartes". C'est un tableau contenant 52 cartes triées.  
 

Emmanuel Delahaye a écrit :

puis mélanger (Internet ne manque pas d'algorithmes 'shuffle') : Tirer (pseudo-aléatoirement) un certain nombre (disons 10 fois le nombre de cartes, au minimum) de couples d'indices [0-51] differents i, j, et inverser les contenus du tableau à ces indices.


-> C'est le code que je vous ai soumis dans le premier post et qui est le sujet de la discussion :)  
 

Emmanuel Delahaye a écrit :

C'est surtout une question d'algo, le codage en C étant trivial...


-> D'accord avec toi :jap:


Message édité par Inekman le 19-01-2006 à 15:32:53
Reply

Marsh Posté le 19-01-2006 à 15:37:05    

Citation :


Bon, déjà "(NBCARTES * 4) - j" peut aussi bien s'écrire "NBCARTES * 4 - j".


-> soit.
 

Citation :

Ca allège la lecture d'éviter les parenthèses inutiles et la priorité de la soustraction par rapport à la multiplication est un sujet étudié au cm2.


-> ...
 

Citation :

Ensuite, pour avoir un aléa régulier entre "0" et "n", il vaut mieux utiliser
"(double)rand() / (RAND_MAX + 1) * n". Le nombre généré est mieux distribué que dans un simple "rand() % n". La démo est ici => http://dejean.benoit.free.fr/code/rand.c.html


-> je regarde ça :jap:  
 

Citation :

Sinon, comme l'a dit Emmanuel, il serait bien de commencer par penser à la modélisation de ton jeu de cartes avant de vouloir le mélanger.


-> cf. ma réponse à Emmanuel.


Message édité par Inekman le 19-01-2006 à 15:38:38
Reply

Marsh Posté le 19-01-2006 à 16:34:19    

olivthill a écrit :

Pour faire avancer le schmlblick, voici ce que j'ai fait pour mon jeu de belote (freeware sur mon site) avec BorlandC qui utilise random au lieu de rand :


http://mapage.noos.fr/emdel/clib/ed/inc/random.h


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 19-01-2006 à 16:45:52    

Autre chose qui pourra peut-être régler le problème.
 
Sachant que à la fin de la phase d'initialisation de la partie, j'ai une liste chaînée qui contient les 104 cartes (normalement) mélangées. Est-il mieux :
 
- de distribuer une carte du paquet successivement sur chaque pile ?
- ou de distribuer 6 cartes du paquet sur la pile 1 puis 6 cartes sur la pile 2 etc, pour les 8 autres piles ?
 
Est-ce que ça peut changer quelque chose selon vous ?

Reply

Marsh Posté le 19-01-2006 à 17:02:13    

Inekman a écrit :

Autre chose qui pourra peut-être régler le problème.
 
Sachant que à la fin de la phase d'initialisation de la partie, j'ai une liste chaînée qui contient les 104 cartes (normalement) mélangées. Est-il mieux :
 
- de distribuer une carte du paquet successivement sur chaque pile ?
- ou de distribuer 6 cartes du paquet sur la pile 1 puis 6 cartes sur la pile 2 etc, pour les 8 autres piles ?
 
Est-ce que ça peut changer quelque chose selon vous ?


Ca peut correspondre à une regle d'usage du jeu. (au poker, par exemple, on mélange peu et on distribue par série de 3 puis 2...)
 
C'est une question de spécification, pas d'implémentation...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 19-01-2006 à 17:02:13   

Reply

Marsh Posté le 19-01-2006 à 17:26:27    

on ne sait rien pour la phase d'initialisation par contre pendant le jeu lorsque on tire sur la pioche, 10 cartes sont distribuées sur le plateau, une sur chaque pile.
 
Donc l'étape d'initialisation restant à notre merci, je me posais cette question.

Reply

Marsh Posté le 20-01-2006 à 19:56:09    

Inekman a écrit :


 Est-il mieux :
- de distribuer une carte du paquet successivement sur chaque pile ?
- ou de distribuer 6 cartes du paquet sur la pile 1 puis 6 cartes sur la pile 2 etc, pour les 8 autres piles ?


 
Dans le solitaire que j'ai appris, le jeu est distribué une carte par pile... mais ça ne change rien. S'il n'est pas bien mélangé, tu auras des cartes qui se suivent dans les lignes au-lieu qu'elles se suivent dans la pile...
 
Je crois que, comme l'a dit Emmanuel, le mieux est de créer un tableau contenant ton jeu complet, puis permuter "n" (n > 1000) fois 52 indices deux à deux, chacun étant pris aléatoirement avec un petit test pour éviter de reprendre un indice déjà permuté.
Ensuite rien ne t'oblige à passer par une liste. Une liste n'est intéressante que si on veut y insérer ou supprimer des éléments intermédiaires en cours de traitement. Sinon le tableau est aussi bien voire mieux...


Message édité par Sve@r le 20-01-2006 à 20:03:46

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 20-01-2006 à 19:59:34    

Merci pour vos conseils, je vais garder le jeu tel qu'il est car je ne vois pas d'autres solutions.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed