Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
992 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Melange aleatoire

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Melange aleatoire

n°1273939
Skullfisch
Posté le 28-12-2005 à 04:50:31  profilanswer
 

Bonjour, :hello:  
Je voudrais savoir si quelqu'un peut m'aider. J'ai un jeu de carte complet a faire en C mais je n'arrive pas a faire un programme ou une fonction qui me permettrait un melange aleatoire d'un jeu de carte. J'ai trouvé ca http://www.cppfrance.com/codes/MEL [...] 18593.aspx mais je comprend pas tout alors si quelqu'un peut corriger, faire plus simple ou m'expliquer ca serait cool... J'hesite aussi sur la facon dont je doit m'y prendre pour representer les cartes (structure,tableau d'entier ou de charactere...) alors si quelqu'un a une bonne idée elle sera la bien venue. :??:  
 
Merci

mood
Publicité
Posté le 28-12-2005 à 04:50:31  profilanswer
 

n°1274074
theshockwa​ve
I work at a firm named Koslow
Posté le 28-12-2005 à 14:29:17  profilanswer
 

les solutions proposées sur la page que tu proposes sont vraiment contestables ...
 
tu dois juste mélanger les cartes ou tu devras aussi faire un jeu avec par la suite ?

n°1274169
Skullfisch
Posté le 28-12-2005 à 18:40:28  profilanswer
 

Je dois melanger les cartes et effectivement aprés je dois faire un jeu avec. Le spider solitaire de Win XP. Mais juste avec les bases de la programmation en C. Sans interface graphique evolué.  

n°1274173
theshockwa​ve
I work at a firm named Koslow
Posté le 28-12-2005 à 19:05:04  profilanswer
 

pour représenter les cartes, j'imagine que tu préfèreras avoir une structure contenant les infos de la carte (valeur / couleur, éventuellement un nom pour l'affichage) afin de faciliter les traitements ultérieurs.
 
Pour le conteneur lui-même, c'est suivant ce que tu comptes en faire. Mais j'imagine que ce qui sera le plus pratique pour ton usage sera soit la liste chaînée, soit le tableau.
La liste étant plus flexible si tu veux redimensionner ton ensemble, le tableau étant plus intuitif à manipuler (et directement présent dans le langage)
 
Edit : En tout cas, il te faudra probablement un système de pile, si je me souviens bien du jeu ... Or, à partir du moment où tu as fait une pile, faire une liste n'est pas beaucoup plus compliqué

Message cité 1 fois
Message édité par theshockwave le 28-12-2005 à 19:05:53
n°1274214
Sve@r
Posté le 28-12-2005 à 21:06:26  profilanswer
 

theshockwave a écrit :

pour représenter les cartes, j'imagine que tu préfèreras avoir une structure contenant les infos de la carte (valeur / couleur, éventuellement un nom pour l'affichage) afin de faciliter les traitements ultérieurs.
 
Pour le conteneur lui-même, c'est suivant ce que tu comptes en faire. Mais j'imagine que ce qui sera le plus pratique pour ton usage sera soit la liste chaînée, soit le tableau.
La liste étant plus flexible si tu veux redimensionner ton ensemble, le tableau étant plus intuitif à manipuler (et directement présent dans le langage)
 
Edit : En tout cas, il te faudra probablement un système de pile, si je me souviens bien du jeu ... Or, à partir du moment où tu as fait une pile, faire une liste n'est pas beaucoup plus compliqué


 
Etant donné que la liste est déjà établie (52 cartes) et qu'il n'y a aucun redimensionnement à faire, le tableau me semble le plus pratique à traiter. Au pire, si on ne doit pas utiliser toutes les cartes pour une raison x ou y, on intègre dans le conteneur un flag permettant d'invalider les cartes choisies...
 
Sinon j'ai lu l'algo présenté sur la page citée mais j'ai aucune idée sur sa valeur. Juste un truc concernant l'aléa qui a déjà été dit sur ce forum ici:
http://forum.hardware.fr/hardwaref [...] 9316-1.htm : pour choisir un nombre entre 0 et N, vaut mieux utiliser la formule "rand() * N / (RAND_MAX + 1)" car le nombre sorti est plus uniformément aléatoire qu'un simple "rand() % N" => démo ici: http://dejean.benoit.free.fr/code/rand.c.html


Message édité par Sve@r le 28-12-2005 à 21:15:45
n°1274273
Skullfisch
Posté le 29-12-2005 à 01:24:12  profilanswer
 

Bon voila en fait je vais representer une carte comme ca:
struct {
       int couleur; //(1,2,3,4)
       int valeur; //(1,2,3,4,5,6,7,8,9,10,11,12,13)
       int affichage; //(0,1)
       }carte;
C'est correct?
 
En tout il y a 10 piles de cartes et 1 pioche alors je pense que je vais faire un tableau avec un grand nombre de case pour chacun vu que de toute facon dans le jeu il y un nombre defini de 104 cartes. (2 jeu de 52 mais les couleurs dependent du niveau)
Pour le melange aleatoire je vais me pencher sur le programme dans ton lien ca m'a l'air pas mal.
 Merci


Message édité par Skullfisch le 29-12-2005 à 01:25:32
n°1274277
Skullfisch
Posté le 29-12-2005 à 01:42:26  profilanswer
 

int main()  
{  
   int nb,i,j;
     
   srand(time(NULL));  
   for(i=0;i<20;i++)  
   {  
       
     nb = rand() % 20;  
     printf("%d\n",nb);  
   
   }  
   scanf("%d",&j);
     
}  
 
Bon voila alors admettons que je range toutes mes cartes de mon jeu dans un tableau. Je vais utiliser un programme dans ce genre la pour melanger chaque case de mon tableau mais le probleme c'est qu'une valeur peut etre prise plusieurs fois, or il me faut un tirage aleatoire sans repetition. Et la il y a des repetitions. J'ai mis 20 pour que se soit plus court a verifier mais il me faut 104 valeurs entre 0 et 103 en fait si je ne me trompe pas pour un tableau.
Alors qu'est qu'il faut que je change pour que ca marche?
En fait il faudrait que j'introduise un  
do (nb = rand() % 20)
while (nb = un des nb saisis avant)
mais je sais pas comment verifier avec tous les nb saisis avant.
Une meilleur idée???

Message cité 1 fois
Message édité par Skullfisch le 29-12-2005 à 01:56:48
n°1274301
blackgodde​ss
vive le troll !
Posté le 29-12-2005 à 09:51:58  profilanswer
 

tu fais X permutations aléatoires dans ton tableau


---------------
-( BlackGoddess )-
n°1274395
Sve@r
Posté le 29-12-2005 à 13:08:25  profilanswer
 

Skullfisch a écrit :

int main()  
{  
   int nb,i,j;
     
   srand(time(NULL));  
   for(i=0;i<20;i++)  
   {  
       
     nb = rand() % 20;  
     printf("%d\n",nb);  
   
   }  
   scanf("%d",&j);
     
}  
 
Bon voila alors admettons que je range toutes mes cartes de mon jeu dans un tableau. Je vais utiliser un programme dans ce genre la pour melanger chaque case de mon tableau mais le probleme c'est qu'une valeur peut etre prise plusieurs fois, or il me faut un tirage aleatoire sans repetition. Et la il y a des repetitions. J'ai mis 20 pour que se soit plus court a verifier mais il me faut 104 valeurs entre 0 et 103 en fait si je ne me trompe pas pour un tableau.
Alors qu'est qu'il faut que je change pour que ca marche?
En fait il faudrait que j'introduise un  
do (nb = rand() % 20)
while (nb = un des nb saisis avant)
mais je sais pas comment verifier avec tous les nb saisis avant.
Une meilleur idée???


 
L'ides de BlackGoddess est pas mal (mais "X" doit être aux alentours de "100* nb_elements" minimum).
 
Sinon pour ta culture perso, si tu veux vérifier que ton nb sorti n'a pas déjà été sorti, alors tu définis un tableau de 20 int et dès que tu as un "nb=rand()", tu vas voir si "tab[nb]" vaut "1". Si oui, alors tu recherches un nouveau "nb" sinon tu le mets à "1" et tu passes au "i" suivant. Et tu peux même te passer de ce tableau si t'intègres un flag supplémentaire style "int tire" dans ta structure "carte" que tu mets à "1" pour chaque "carte[nb]"
 
PS: Il est plus lisible de nommer ses structures "s_qqchose". On s'y retrouve mieux ensuite quand il faut trouver des noms pour les variables...

Message cité 1 fois
Message édité par Sve@r le 29-12-2005 à 13:14:50
n°1274401
Tamahome
⭐⭐⭐⭐⭐
Posté le 29-12-2005 à 13:38:12  profilanswer
 

google : shuffle

mood
Publicité
Posté le 29-12-2005 à 13:38:12  profilanswer
 

n°1274425
theshockwa​ve
I work at a firm named Koslow
Posté le 29-12-2005 à 14:16:10  profilanswer
 

Sve@r a écrit :

tu définis un tableau de 20 int et dès que tu as un "nb=rand()", tu vas voir si "tab[nb]" vaut "1". Si oui, alors tu recherches un nouveau "nb" sinon tu le mets à "1" et tu passes au "i" suivant. Et tu peux même te passer de ce tableau si t'intègres un flag supplémentaire style "int tire" dans ta structure "carte" que tu mets à "1" pour chaque "carte[nb]"


et c'est comme ca qu'on se retrouve avec un tirage de cartes qui prend des plombes parce que lorsqu'il ne reste plus que quelques éléments, il faut faire des centaines de tirages pour tomber dessus :o
c'est sur qu'avec un tableau, le coup des permutations est ce qui semble le plus tentant. Avec un autre structure de données, on a moyen de faire des mélanges un peu plus "jolis" (moyennant la construction d'une deuxième structure et le vidage de la première)

n°1274444
Arjuna
Aircraft Ident.: F-MBSD
Posté le 29-12-2005 à 14:54:50  profilanswer
 

Moi, j'ai un truc simple à proposer...
 
Tu crée une structure avec deux fields :
- float
- carte
 
Tu remplis un tableau de 52 lignes avec, en mettant tes cartes dans l'ordre dans le field.
 
Tu génères 52 nombres aléatoires avec la fonction rand() et tu les met dans le field float des structures de ton array.
 
Puis tu fais un quicksort sur ce nombre afin de trier les cartes dans un ordre aléatoire.
 
Ca me semble suffisament aléatoire pour un jeu de carte, et pas loin de ce qu'on peut faire de plus rapide (52 nombres aléatoires générés, et un seul tri simple dans un tableau sans trou ni doublon)

Message cité 1 fois
Message édité par Arjuna le 29-12-2005 à 14:56:40
n°1274449
Arjuna
Aircraft Ident.: F-MBSD
Posté le 29-12-2005 à 14:58:33  profilanswer
 

Quand je lis vos post, je trouve que vous avez l'esprit bien tordu pour un résultat plutôt pas convainquant :D

n°1274456
theshockwa​ve
I work at a firm named Koslow
Posté le 29-12-2005 à 15:07:14  profilanswer
 

Arjuna a écrit :

Quand je lis vos post, je trouve que vous avez l'esprit bien tordu pour un résultat plutôt pas convainquant :D


 
J'aime bien ta solution, mais j'avoue que j'aurais préféré ne pas avoir à l'admettre publiquement :o
 
:whistle:
Edit : cependant, je ne vois pas pourquoi tu veux que le champ supplémentaire soit un float plutôt qu'un entier


Message édité par theshockwave le 29-12-2005 à 15:07:45
n°1274477
Arjuna
Aircraft Ident.: F-MBSD
Posté le 29-12-2005 à 15:33:23  profilanswer
 

parceque rand retourne un float et que j'imagine qu'un tri sur des float ça reste plus rapide qu'un cast en int puis un tri sur des int, mais je peux me tromper ;)


Message édité par Arjuna le 29-12-2005 à 15:33:30
n°1274498
theshockwa​ve
I work at a firm named Koslow
Posté le 29-12-2005 à 15:57:04  profilanswer
 

en C, rand retourne un int :o

n°1274536
0x90
Posté le 29-12-2005 à 16:59:58  profilanswer
 

Une idée d'algo de mélange d'un tableau "sur place" , le principe est d'avancer dans le tableau, avec la partie de tab[0] à tab[i] mélangée, et la partie de tab[i+1] à tab[51] pas encore mélangée dans laquelle on pioche une carte qu'on met à la fin de la partie mélangée.

Code :
  1. for (i=0;i<51;i++)
  2.  {
  3.     /* On choisit un entier au pif entre i et 51; */
  4.     randval = (rand() % (52-i)) + i;
  5.     /* On permute tab[i] et tab[randval] */
  6.     tmp = tab[i];
  7.     tab[i] = tab[randval];
  8.     tab[randval] = tmp;
  9.  }


PS : jvient d'improviser donc c'est ptêtre tout foireux, mais si jme trompe pas, ca fait kkchose ne necessitant pas de tri et avec un minimum de rand, quand à la qualité du mélange, d'instinct je dirait correct vu qu'on prends consécutivement une carte au hasard dans les triées, en pratique je garanti rien.
PS² : evidement le modulo dans le rand() c'est histoire de faire un code lisible, à remplacer par le truc a base de division si necessaire. ( encore que pour un jeu de carte je me demande si la qualité du rand est si importante ... )
 
[edit]
Testé et corrigé le % doit être 52 et pas 51 dans le code, sinon la dernière carte n'est jamais mélangée.
Donc visiblement ca fonctionne, si un expert du random peut donner son avis sur la qualité du mélange je dis pas non cela dit.


Message édité par 0x90 le 29-12-2005 à 17:13:58

---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
n°1274705
Skullfisch
Posté le 29-12-2005 à 23:05:48  profilanswer
 

Bon j'ai pas encore testé mais j'ai fais un melange comm ca:
 
   int a,b,temp,compt,k;
   compt=0;
     
   srand(time(NULL));
     
   do {
      a = rand() % 104;  
      do {  
         b = rand() % 104;
         }
      while (b==a);
           
      /*tabjeu [temp] = tabjeu [a]
      tabjeu [a] = tabjeu [b]
      tabjeu [b] = tabjeu [temp]*/
   
      compt = compt+1;
      }
   while (compt<100);
       
   scanf("%d",&k);
   }  
 
ca me fais un bon melange c'est pas grave si tout n'est pas melangé aprés je peux rajouter encore des permutations et en mettre plus de 100.
Par contre maintenant il faut que j'arrive a le faire foncctionner sur tabjeu qui est un tableau de 104 cartes. (2 jeu de 52).

n°1274715
0x90
Posté le 29-12-2005 à 23:19:13  profilanswer
 
n°1274718
Sve@r
Posté le 29-12-2005 à 23:32:03  profilanswer
 

Arjuna a écrit :

Moi, j'ai un truc simple à proposer...
 
Tu crée une structure avec deux fields :
- float
- carte
 
Tu remplis un tableau de 52 lignes avec, en mettant tes cartes dans l'ordre dans le field.
 
Tu génères 52 nombres aléatoires avec la fonction rand() et tu les met dans le field float des structures de ton array.
 
Puis tu fais un quicksort sur ce nombre afin de trier les cartes dans un ordre aléatoire.
 
Ca me semble suffisament aléatoire pour un jeu de carte, et pas loin de ce qu'on peut faire de plus rapide (52 nombres aléatoires générés, et un seul tri simple dans un tableau sans trou ni doublon)


 
Et pourquoi ne pas intégrer l'aléa directement dans la fonction qui sert à comparer 2 éléments (celle dont on passe le pointeur en 4° paramètre de qsort) ???

n°1274770
Skullfisch
Posté le 30-12-2005 à 01:51:50  profilanswer
 

Le probleme c'est qu'il y a des fonctions genre qsort que j'ai pas encore vu en cours donc j'ai pas encore le droit de les uitiliser.

n°1274772
0x90
Posté le 30-12-2005 à 01:59:44  profilanswer
 

T'as un peu regardé ce que j'ai fait ou même pas ?


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
n°1274779
Skullfisch
Posté le 30-12-2005 à 02:32:02  profilanswer
 

OUi je viens de regarder. L'avantage effectivement c'est que tout est melangé et que c'est plus court.
par contre j'ai un peu de mal a comprendre la ligne la si tu peux m'expliquer:  
randval = (rand() % (52-i)) + i;

n°1274780
0x90
Posté le 30-12-2005 à 02:37:58  profilanswer
 

rand() % x , c'est une valeur entre 0 et x-1.
rand() % (52-i) c'est une valeur entre 0 et 51-i
(rand() % (52-i)) + i c'est une valeur entre i et 51.
voila c'est tout [:spamafote]


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
n°1274789
Skullfisch
Posté le 30-12-2005 à 03:09:28  profilanswer
 

OK merci c cool ben je vais prendre ca.

n°1274790
Skullfisch
Posté le 30-12-2005 à 03:21:04  profilanswer
 

J'ai apporté une petite modif pour simplifier:
for (i=0;i<52;i++)  {      
    /* On choisit un entier au pif entre 0 et 51; */      
    randval = (rand() % 51);
    printf("%d : %d\n",i,randval);    
    /* On permute tab[i] et tab[randval] */      
    tmp = tab[i];      
    tab[i] = tab[randval];      
    tab[randval] = tmp;  }
     scanf("%d",&k);
}  
Comme ca on est sur que toutes les cartes sont melangées n'importe ou.
Mais est ce que ca pose probleme si i=randval?


Message édité par Skullfisch le 30-12-2005 à 03:31:11
n°1274859
Tamahome
⭐⭐⭐⭐⭐
Posté le 30-12-2005 à 11:30:04  profilanswer
 

sinon, le shuffle c'est bieng aussi

n°1274926
Sve@r
Posté le 30-12-2005 à 12:32:33  profilanswer
 

0x90 a écrit :

rand() % x , c'est une valeur entre 0 et x-1.


 
"rand() % x" c'est moyennement aléatoire
"rand() / (RAND_MAX + 1.0) * x" c'est un meilleur aléa => http://dejean.benoit.free.fr/code/rand.c.html

Message cité 1 fois
Message édité par Sve@r le 30-12-2005 à 12:33:53
n°1274935
0x90
Posté le 30-12-2005 à 12:48:39  profilanswer
 

Sve@r a écrit :

"rand() % x" c'est moyennement aléatoire
"rand() / (RAND_MAX + 1.0) * x" c'est un meilleur aléa => http://dejean.benoit.free.fr/code/rand.c.html


 
Je sais et j'ai déja expliqué plus haut pkoi j'ai mis rand() % x
( au passage son test du rand me semble vachement foireux mais bon ... )
Et pour être précis ca dépends des plateformes, sous un linux pas trop vieux, rand est aussi bon sur les bits de poids faible que sur les bits de poids fort.


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
n°1274959
Sve@r
Posté le 30-12-2005 à 13:56:13  profilanswer
 

0x90 a écrit :

Je sais et j'ai déja expliqué plus haut pkoi j'ai mis rand() % x


oups... désolé j'avais pas tout lu  :jap:  

0x90 a écrit :

Et pour être précis ca dépends des plateformes, sous un linux pas trop vieux, rand est aussi bon sur les bits de poids faible que sur les bits de poids fort.


Ah ben sur Linux autant aller taper directement dans "/dev/random"  :sol:  

n°1274967
0x90
Posté le 30-12-2005 à 14:31:35  profilanswer
 

Sve@r a écrit :


Ah ben sur Linux autant aller taper directement dans "/dev/random"  :sol:


Ouais mais c'est frustrant de voir un programme freezer ... jusqu'a ce qu'on bouge la souris  [:0x90]  


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
n°1274992
Sve@r
Posté le 30-12-2005 à 15:45:22  profilanswer
 

0x90 a écrit :

Ouais mais c'est frustrant de voir un programme freezer ... jusqu'a ce qu'on bouge la souris  [:0x90]


 
Mais non, on crée un processus fils avec "fork()" et le fils fait des system("find" ) en boucle infinie pour faire bouger le disque !!!  :D  :D  

n°1274993
0x90
Posté le 30-12-2005 à 15:49:32  profilanswer
 

Sve@r a écrit :

Mais non, on crée un processus fils avec "fork()" et le fils fait des system("find" ) en boucle infinie pour faire bouger le disque !!!  :D  :D


 
Ah ouais, forcément le code devient vachement plus puissant qu'un rand() :o
 
( et au fait, t'as /dev/urandom :o )


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
n°1275205
Arjuna
Aircraft Ident.: F-MBSD
Posté le 31-12-2005 à 01:39:47  profilanswer
 

Skullfisch a écrit :

Le probleme c'est qu'il y a des fonctions genre qsort que j'ai pas encore vu en cours donc j'ai pas encore le droit de les uitiliser.


bah... moi j'ai parlé de qsort parceque c'est une des solutions de tri les plus simples et les plus rapides, mais fait pas t'arrêter à ça, tu peux aussi utiliser un tri à bulles ou n'importe quoi d'autre ;)

n°1275600
Hortense
Posté le 01-01-2006 à 18:58:16  profilanswer
 

Ah ben j'ai le même projet à faire

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Melange aleatoire

 

Sujets relatifs
nombre aleatoire[Visual Basic 6] Nombre aléatoire qui n'est pas vraiment aléatoire...
[ActionScript] musique mp3 aleatoireValeur aléatoire comprise entre 2 nombres?..
Image aléatoire cachéAffichage aléatoire d'images
Pb avec tableu et choix aléatoire[Résolu]Génération aléatoire puis insertion
swf aleatoire dans page htmlSelection Aléatoire
Plus de sujets relatifs à : Melange aleatoire


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR