shuffle
imagine a deck with 3 cards (so elements 0, 1 and 2 of an array):
shuffling the bad way..
for each of the original cards[0] to cards[2]: choose a random card between cards[0] and cards[2] swap the original card with the random card
- there is 3 possible combinations here:
- 123, 132, 213, 231, 312, 321
- or in other words "3!" (which means 3 factorial = 3 * 2 * 1 = 6)
- so if we shuffled the deck 600k times, we should see each combination around 100k times
- but we dont with this algorithm..:
- because of "for each card, choose a random card between cards[0] and cards[2]"
- this implies 33 combinations = 27 outcomes
- in our heads though, we know this isnt possible.. there are only 6 (3!)
- more combinations then real world outcomes = some combinations being over-represented
- which means bad shuffling!
- more shuffling makes results here even worse (meaning the over represented probabilities become even more obvious)
- more cards makes result worse too.. e.g. a 6 card deck = 66 combinations (46,656) trying to fit into 6! = 720 real world combinations
shuffling the better way..
for each of the original cards[2] counting down to cards[0]: choose a random card between cards[0] and the original card im currently at swap the original card with the random card
- starts with swapping from the third position with any of the three cards
- so it can stay in 3rd (123), or swap places with 2nd (132) or 1st (321)
- then 2nd can stay in 2nd or swap with 1st..
- so depending on what 3rd did gives us either:
- (123 = 123 or 213), (132 = 132 or 312) and (321 = 321 or 231)
- if you work it out, thats 6 possible combinations!
- each with almost perfectly equal chance.. so good shuffling
shuffle: java
import java.util.Random; public class shuffle{ public static void main(String[] args) { //*****SET UP 2 DECKS*****: int[] cardDeck = new int[52]; int[] tempDeck = new int[52]; for(int count=0; count<52; count++) { cardDeck[count] = count; tempDeck[count] = count; } //*****NOW SHUFFLE*****: Random seed = new Random(); for(int number=52; number>=1; number--) { int numbersLeft = seed.nextInt(number); cardDeck[number-1] = tempDeck[numbersLeft]; tempDeck[numbersLeft] = tempDeck[number-1]; } //*****CHECK RESUT*****: for(int test=0; test<52; test++){ System.out.println(cardDeck[test]); } } }