Java: Mélanger un jeu de 32 cartes?


J'ai écrit cette méthode moi-même Je veux savoir s'il y a une meilleure façon de le faire?

public Card[] shuffle(){
    for(int i = 0; i < Deck.length; i++){
       int x = i + (int) (Math.random() * (32 - i));
       Card temp = Deck[i];
       Deck[i] = Deck[x];
       Deck[x] = temp;
    }
    return Deck;
}
Author: Harout Tatarian, 2015-06-10

3 answers

Vous ne vérifiez pas, si ( 32 - i ) donne jamais une valeur inférieure à 0. L'algorithme est appeléFisher-Yates algorithme de brassage, qui ressemble beaucoup au vôtre:

private int [] shuffleMyArray ( int [] array ) {
    int size = array.length, i = 0;
    int temp = 0;
    while ( size != 0 ) {
        i = ( ( int ) ( Math.random () * size-- ) );
        if ( i < 0 ) {
            i = 0;
        }
        temp = array [ size ];
        array [ size ] = array [ i ];
        array [ i ] = temp;
    }
    return array;
}

MODIFIER 1:

La sortie des deux algorithmes vous fera mieux comprendre la différence entre les deux, voir comment Fisher-Yates prend en compte tous les indices, tout en mélangeant.

SORTIE:

Actual Array
0 1 2 3 4 
Your Implementation output
i: 0 x: 3
i: 1 x: 4
i: 2 x: 3
i: 3 x: 4
i: 4 x: 4
Fisher Yates implementation output
i: 4 size: 4
i: 2 size: 3
i: 1 size: 2
i: 0 size: 1
i: 0 size: 0
 2
Author: nIcE cOw, 2015-06-10 04:45:41

Je vais faire du deck un argument et de la méthode static. De cette façon, il est autonome. En Java, les conventions de nommage consistent à faire en sorte que les variables et les noms de méthodes commencent par une lettre minuscule. Ensuite, le chemin le plus court je sais, c'est de battre les cartes en place avec Collections.shuffle(List) et Arrays.asList(T...) comme

public static void shuffle(Card[] deck) {
    Collections.shuffle(Arrays.asList(deck));
}

Si vous voulez conserver l'original deck, alors vous pouvez le copier et return comme

public static Card[] shuffle(Card[] deck) {
    List<Card> al = new ArrayList<>(Arrays.asList(deck));
    Collections.shuffle(al);
    return al.toArray(new Card[deck.length]);
}
 1
Author: Elliott Frisch, 2015-06-10 03:59:54

Je suppose que vous pouvez obtenir un meilleur résultat si vous choisissez l'élément à échanger de tout le deck et pas seulement des cartes restantes, comme ceci:

public Card[] Shuffle(){
    for(int i = 0; i < Deck.length; i++){
       int x = (int) (Math.random() * 32);
       Card temp = Deck[i];
       Deck[i] = Deck[x];
       Deck[x] = temp;
    }
    return Deck;
}
 -1
Author: Horacio, 2015-06-10 01:59:02