Fonction mélangeant un jeu de carte

Fermé
Befive - 17 déc. 2011 à 11:37
lermite222 Messages postés 8702 Date d'inscription dimanche 8 avril 2007 Statut Contributeur Dernière intervention 22 janvier 2020 - 19 déc. 2011 à 15:38
Bonjour,

Je cherche à effectuer un mélange de 100 cartes.
La position de la carte dans le paquet doit donc être assigner de la position n°1 à la position n°100 aléatoirement. J'ai essayé d'exploiter la fonction "rand()" jusqu'à maintenant :

void Melange(Control* c)
{
int i=0, j=0, k=0;

for (i=0 ; i<nombre_cartes ; i++)
{
tableau_cartes[i][0] = rand()%nombre_cartes;
for (j=i-1 ; j>-1 ; j--)
{
if (tableau_cartes[i][0] %= tableau_cartes[j][0])
{
tableau_cartes[i][0] = rand()%nombre_cartes;
}
}
}
printf("%d ",nombre_cartes);
for (k=0 ; k<nombre_cartes ; k++)
{
printf("%d ",tableau_cartes[k][0]);
printf("\n");
}
}

Le test ne vérifie pas toutes les valeurs précédemment assignées et donc certaines valeurs apparaissent plusieurs fois !

Je vous remercie d'avance pour votre aide !
A voir également:

7 réponses

nicocorico Messages postés 799 Date d'inscription dimanche 19 juin 2011 Statut Membre Dernière intervention 3 juillet 2018 138
17 déc. 2011 à 12:55
Pour contourner le problème, tu peux remplir ton tableau dans l'ordre, puis tirer 100 nombres au hasard et, échanger le contenu indexé par ce nombre et le contenu indexé par le nombre précédent... Ainsi, pas de problème de redondance !
1
lermite222 Messages postés 8702 Date d'inscription dimanche 8 avril 2007 Statut Contributeur Dernière intervention 22 janvier 2020 1 190
17 déc. 2011 à 22:51
Bonjour,
Je ne connais pas le C mais l'algo que j'emploi en VB..
Dim B(100) As Boolean, NB As Integer
Dim TB(100) As Integer, Tirage As Integer
    While NB < 100
        Tirage = Int(100 * Rnd) + 1
        If Not B(Tirage) Then
            B(Tirage) = True
            NB = NB + 1
            TB(NB) = Tirage
            Debug.Print Tirage
        End If
    Wend

Si tu peu traduire en C.
A+
1
nicocorico Messages postés 799 Date d'inscription dimanche 19 juin 2011 Statut Membre Dernière intervention 3 juillet 2018 138
18 déc. 2011 à 07:38
^^ Je connais pas le Vb, mais si je comprend bien ton code, il doit manquer quelque chose car le tableau de booléens ne sert pas...
Il devrais falloir le parcourir ensuite pour ajouter les cartes correspondantes aux valeurs False.
Et au final, je trouve ma solution plus simple : plutôt que de tirer les cartes et déterminer si on a bien tout sorti, mieux vaut tout sortir puis mélanger ensuite !
Une solution peut-être plus simplement explicable que celle donnée précédemment :
On rempli le tableau;
On boucle une centaine de fois l'échange entre le contenu de l'emplacement 0 et l'emplacement défini par la valeur aléatoire...
0
lermite222 Messages postés 8702 Date d'inscription dimanche 8 avril 2007 Statut Contributeur Dernière intervention 22 janvier 2020 1 190
Modifié par lermite222 le 18/12/2011 à 08:58
Tu n'a pas bien compris l'algo (normal si tu ne connais pas VB) mais le tableau de boolean répond à la remarque de Befive..
Le test ne vérifie pas toutes les valeurs précédemment assignées et donc certaines valeurs apparaissent plusieurs fois !
Je t'assure que ça fonctionne parfaitement et sans doublon, c'est justement te tableau de boolean qui empêche de sélectionner le même nombre plusieurs fois.
Par contre, avec ta solution il n'y aura pas de doublon mais un bon nombre d'erreur, que se passe-t-il quand le tirage donne plusieurs fois le même numéro ?
A+
0
nicocorico Messages postés 799 Date d'inscription dimanche 19 juin 2011 Statut Membre Dernière intervention 3 juillet 2018 138
18 déc. 2011 à 09:15
Ha oui, j'ai compris ton algo, il me manquait le fait que le 'If' court jusqu'au 'End If'...
Mais il souffre d'un défault : la boucle continue tant que tous les nombres ne sont pas sortis, ce qui peut éventuellement prendre du temps...
Quand à ma méthode, elle ne pose évidement aucun problème en cas de redondance puisqu'on se contente d'échanger les contenus, le seul risque est dans le cas ou le même nombre sort 2 fois de suite, les 2 opérations s'annulent...
0
lermite222 Messages postés 8702 Date d'inscription dimanche 8 avril 2007 Statut Contributeur Dernière intervention 22 janvier 2020 1 190
18 déc. 2011 à 09:35
Oui, pour l'échange je ne l'ai compris qu'après avoir écrit mon dernier poste.
Somme toute, les deux systèmes fonctionnent.
Quand à prendre du temps, c'est vrai, ça doit prendre une nono seconde en plus :-)
Au final, ta solution est meilleur, surtout pour de tout grand tableaux (plus de 30000), dans ces cas, la fonction Rand ne sort pas tout les nombres et bloque le programme. Ça m'est déjà arrivé.
A+
0
Merci pour vos réponses.

Je vais essayer d'appliquer la méthode de nicocorico car, lermite222, le VB et et moi... J'ai toute de même compris l'idée mais la mise en place en langage C m'est plus floue.

Je vous recontacterai si je ne parviens pas à entrer un code qui marche !

A+
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Voici ce que ça donne : (et ça marche comme il faut ^^)

int i=0, j=0, z;

// Tableau contenant les positions possibles des cartes
int tableau_position_possible[99][2];
for (i=0 ; i<99 ; i++)
{
tableau_position_possible[i][0]=i;
tableau_position_possible[i][1]=0;
}
// Mélange : placement aléatoire des positions 0 à 99
srand(time(NULL));
while(j<99)
{
z=rand()%99;
if (tableau_position_possible[z][1]==0)
{
tableau_position_possible[z][1]=1;
tableau_cartes[j][0]=tableau_position_possible[z][0];
printf("%d",tableau_cartes[j][0]);
printf("\n");
j++;
}
}

Je pense que j'ai utilisé un bout des 2 idées que vous m'avez proposé.
Pour décrire ce programme :
- J'ai tout d'abord créé un tableau avec toutes les positions possibles pour une carte dans un paquet de 100 cartes.
- La 2e colonne de ce tableau est une valeur binaire informant si la ligne a été déjà remplie ou non.
- Ensuite, je lance le mélange : tant que tout n'est pas rempli, je choisis un nombre entre 0 et 99, je marque "1" dans la 2e colonne pour dire qu'il a été choisit, puis je reporte la valeur dans le tableau à construire aléatoirement.

Encore un grand merci à vous deux !
0
nicocorico Messages postés 799 Date d'inscription dimanche 19 juin 2011 Statut Membre Dernière intervention 3 juillet 2018 138
Modifié par nicocorico le 18/12/2011 à 16:33
Oui, ça doit fonctionner, mais là encore le nombre d'itérations est inconnu, et rien ne dit qu'il n'y a pas une suite dans laquelle un nombre sera totalement absent, bouclant sans fin donc... En tous cas, dans le doute, je préfère la solution du brassage :
int i=0, j=0, z, v;  
int tableau_cartes[99];  

// Tableau contenant l'ensemble des cartes  
for (i=0 ; i<99 ; i++)  
  tableau_cartes[i]=i;  

// Mélange les contenus des positions 0 à 99  
srand(time(NULL));  
for (i=0 ; i<99 ; i++)  
{  
  z = rand()%99;  
  v = tableau_cartes[0];  
  tableau_cartes[0] = tableau_cartes[z];  
  tableau_cartes[z] = v;  
}  
for (i=0 ; i<99 ; i++)  
{  
  printf("%d",tableau_cartes[i]);  
  printf("\n");  
}  

Le chêne aussi était un gland, avant d'être un chêne
0
lermite222 Messages postés 8702 Date d'inscription dimanche 8 avril 2007 Statut Contributeur Dernière intervention 22 janvier 2020 1 190
18 déc. 2011 à 17:20
Befive : Cette solution est la meilleur.
Mais... les amis, de grâce, INDENTER vos exemples, bien que je ne pratique plus le C depuis des années cela me permettrais de comprendre un peu plus vite.
A+
0
Ma solution marche correctement et assez rapidement pour 100 objets seulement mais ta façon de faire est beaucoup plus efficace et peut être appliquer à plus grande échelle !
Je vais retenir cette solution ^^

Désolé lermite222 pour notre écriture C...
0
lermite222 Messages postés 8702 Date d'inscription dimanche 8 avril 2007 Statut Contributeur Dernière intervention 22 janvier 2020 1 190
19 déc. 2011 à 15:38
C ou pas C, rien n'empêche.. :D
int i=0, j=0, z;

// Tableau contenant les positions possibles des cartes
int tableau_position_possible[99][2];
    for (i=0 ; i<99 ; i++) {
        tableau_position_possible[i][0]=i;
        tableau_position_possible[i][1]=0;
    }
// Mélange : placement aléatoire des positions 0 à 99
    srand(time(NULL));
    While (j < 99)
    {
        z=rand()%99;
        if (tableau_position_possible[z][1]==0)
        {
            tableau_position_possible[z][1]=1;
            tableau_cartes[j][0]=tableau_position_possible[z][0];
            printf("%d",tableau_cartes[j][0]);
            printf("\n");
            j++;
        }
    }

Sélectionner le code et valider avec le bouton <> au dessus de l'éditeur.
A+
0