Mélanger un tableau d'entier ou autre?

bojda Messages postés 13 Date d'inscription mardi 8 mars 2005 Statut Membre Dernière intervention 28 février 2006 - 20 févr. 2006 à 14:48
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 - 29 mars 2008 à 00:08
Bonjour,

j'aimerais savoir si quelqu'un connaît un algorithme de mélange d'un tableau en c# ?



Merci!!

23 réponses

sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
20 févr. 2006 à 15:22
en fait, la technique est relativement simple... il fait procéder comme si tu allais trier ton tableau...

Tu commences par créer une classe qui implémente IComparer :


public
class
Melangeur :
IComparer {

private
static
Random rnd;

static Melangeur() {
rnd =
new
Random();
}



public
int Compare(
object x,
object y) {

if (x.Equals(y))

return 0;

else {

return rnd.Next(-1, 1);
}
}

}

ensuite, il suffit de trier ton tableau :


int[] toto =
new
int[16];

Array.Sort(toto,
new
Melangeur());

et voila, c'est fini.


Sébastien FERRAND (
blog)
[Microsoft MVP Visual C#]
1
Nikoui Messages postés 794 Date d'inscription vendredi 24 septembre 2004 Statut Membre Dernière intervention 19 août 2008 13
20 févr. 2006 à 17:00
Très sympa comme méthode :)
0
bojda Messages postés 13 Date d'inscription mardi 8 mars 2005 Statut Membre Dernière intervention 28 février 2006
24 févr. 2006 à 08:10
Merci, pour cette solution même si je n'en comprends pas tout le fonctionnement... en tout cas ça marche! Merci!
0
bojda Messages postés 13 Date d'inscription mardi 8 mars 2005 Statut Membre Dernière intervention 28 février 2006
21 mars 2006 à 15:52
Si quelqu'un pourrait?
En faite cette méthode, mais je la comprend pas tout à fait. Et le problème, c'est qu'environ une fois sur vingt Array.Sort(toto,
new
Melangeur()); me sort une erreur:

"Une exception non gérée du type 'System.ArgumentException' s'est produite dans mscorlib.dll

Informations supplémentaires :

IComparer (ou les méthodes IComparable dont il dépend) n'a pas retourné zéro lorsque Array.Sort a appelé x.

CompareTo(x). x : Poker.Card Type de x : Card Le IComparer : Poker.Shaker."

Si quelqu'un pourrait me dire une autre solution ou alors m'aider à trouver le problème.
Information complémentaire:
J'utilise cette méthode pour mélanger un tableau de carte dans un jeu de poker.

Merci
0

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

Posez votre question
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
21 mars 2006 à 16:09
il ne faut pas oublier :

if (x.Equals(y))
return 0;

dans la classe Melangeur...


Sébastien FERRAND (
blog)
[Microsoft MVP Visual C#]
0
bojda Messages postés 13 Date d'inscription mardi 8 mars 2005 Statut Membre Dernière intervention 28 février 2006
22 mars 2006 à 08:41
Comme écrit dans la solution proposée?

Je l'ai bien mis et il y a quand même l'erreur!
0
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
22 mars 2006 à 09:39
Essaye comme ceci :

public
class
Melangeur :
IComparer {

private
static
Random rnd;

static Melangeur() {
rnd =
new
Random();
}



public
int Compare(
object x,
object y) {

if (Object.Equals(x, y))

return 0;

else {

return rnd.Next(-1, 1);
}
}

}


Sébastien FERRAND (
blog)
[Microsoft MVP Visual C#]
0
bojda Messages postés 13 Date d'inscription mardi 8 mars 2005 Statut Membre Dernière intervention 28 février 2006
22 mars 2006 à 11:39
Pour le moment, ça a l'air de marcher... mais bon je reste prudent comme c'est une erreur qui ce produit que de temps en temps.
0
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
22 mars 2006 à 11:45
ok


Sébastien FERRAND (
blog)
[Microsoft MVP Visual C#]
0
bojda Messages postés 13 Date d'inscription mardi 8 mars 2005 Statut Membre Dernière intervention 28 février 2006
22 mars 2006 à 13:20
Bon ben j'avais raison d'être méfiant... ça n'a pas enlevé le problème.

A mon avis, tu trouveras pas le problème sans savoir ce que j'ai fait:

Card[] cards = new Card[52];
Array.Sort(cards,new Shaker());

public class Card
{
private string suit;
private int valu; /* 11 <-> J
* 12 <-> Q
* 13 <-> K
* 14 <-> AS */

private string picture;

public Card(string suit, int valu, string picture)
{
this.suit = suit;
this.valu = valu;
this.picture = picture;
}
...
}

Sinon, personne aurait une autre solution?.. ou toi, d'ailleurs
0
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
22 mars 2006 à 21:39
Card[] cards = new Card[52];
Array.Sort(cards,new Shaker());

=> là tu mélanges un tableau de 52 null

/*
coq
MVP Visual C#
*/
0
bojda Messages postés 13 Date d'inscription mardi 8 mars 2005 Statut Membre Dernière intervention 28 février 2006
24 mars 2006 à 10:46
Ouais, enfin je suis pas non plus totalement nul en prog... j'ai juste simplifié, j'ai pas tout marqué...
Le tableau de carte est bien initialisé, sinon ça ne marcherait pas du tout, et pas 19 fois sur 20...

Tant pis, je me suis résolu à ne pas résoudre cette erreur mais juste à la contourné.

Et ça marche, même si c'est pas la meilleure solution
0
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
24 mars 2006 à 19:03
C'est assez étonnant comme erreur.
Peut tu mettre le code complet des classes Card et Shaker stp ?

/*
coq
MVP Visual C#
*/
0
bojda Messages postés 13 Date d'inscription mardi 8 mars 2005 Statut Membre Dernière intervention 28 février 2006
25 mars 2006 à 10:07
public class Card
{
private string suit;
private int valu; /* 11 <-> J
* 12 <-> Q
* 13 <-> K
* 14 <-> AS */

private string picture;

public Card(string suit, int valu, string picture)
{
this.suit = suit;
this.valu = valu;
this.picture = picture;
}
}

public class Shaker: IComparer
{
private static Random rnd;
static Shaker()
{
rnd = new Random();
}

public int Compare(object x, object y)
{
if (Object.Equals(x, y))
return 0;
else
{
return rnd.Next(-1, 1);
}
}
}

Par contre pour raccourcir, j'ai enlevé les accesseurs de la classe Cards, mais bon vous m'en voudrait pas .
0
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
25 mars 2006 à 13:44
Ceci résoudra ton problème (normalement) :

public class Shaker : IComparer
{
private static Random rnd;
static Shaker()
{
rnd = new Random();
}


public int Compare(object x, object y)
{
int ret = 0;


if (Object.Equals(x, y))
ret = 0;
else
{
while(ret==0)
ret = rnd.Next(-1, 1);
}


return ret;
}
}

(testé avec 28323775 tris sans erreur)

Maintenant je voudrais bien comprendre pourquoi l'exception est levée si on ne fait pas ça...

/*
coq
MVP Visual C#
*/
0
bojda Messages postés 13 Date d'inscription mardi 8 mars 2005 Statut Membre Dernière intervention 28 février 2006
25 mars 2006 à 15:32
Heu, c'est vrai y a plus d'erreur!

Mais ça mélange plus mes cartes...
0
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
25 mars 2006 à 16:46
Exact -_-
Eh bah là je n'ai vraiment pas d'idée sur le problème de fond...

/*
coq
MVP Visual C#
*/
0
bojda Messages postés 13 Date d'inscription mardi 8 mars 2005 Statut Membre Dernière intervention 28 février 2006
25 mars 2006 à 19:20
Tant pis merci quand même. Pour les curieux voilà comment j'ai contourné le problème:

try
{
Array.Sort(cards,new Shaker());
rank = 0;
}
catch{ rank = 25;};

Donc, dans le cas où l'on a une erreur, au lieu d'utilisé le tableau de carte à partir de la 1ère, on le fait à partir de la 26ème. Comme dans mon jeu de poker, sur une partie on n'utilise qu'au plus 25 cartes, et que l'erreur ce produit rarement... il y a de très très très faible probabilité pour que sur 2 tours consécutifs on ait les même carte.

Et encore merci à vous pour votre aide.
0
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
25 mars 2006 à 19:28
En fait je pense que le problème doit venir de l'algorithme "QuickSort" utilisé pour le tri.
Il vaudrait peut être mieux que tu passes par une autre méthode de mélange.

/*
coq
MVP Visual C#
*/
0
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
25 mars 2006 à 20:37
Bon, le message n'était pas partit tout à l'heure... :

Voilà un petit exemple de ce à quoi je pensais :

private static void RandomizeArray(object[] array)
{
int arrayLength = array.Length;


// parcours de la liste en partant de la fin
for (int i = arrayLength - 1; i > 1; --i)
{
// tirage au sort d'un index entre 0 et la valeur courante de "i"
int randomIndex = rnd.Next(i);
// intervertion des éléments situés aux index "i" et "randomIndex"
object temp = array[i];
array[i] = array[randomIndex];
array[randomIndex] = temp;
}
}

/*
coq
MVP Visual C#
*/
0
Rejoignez-nous