Great job, everyone. Here's my own answer in C# based on the Fisher-Yates algorithm. Should give you a perfect shuffle if your random number generator is good enough.
English version:
- Partially sortRepeatedly swap the deck untilcard at
deck[0]
with the one atdeck[v]
, wherev
is the face value of the card atdeck[0]
. Repeat untilv == 0
. Since you knowThis will partially sort the deck, but that card's original valuedoesn't matter. You now know Card 0 is at the front of the deck, which means you can steal that space in the array and use it as a loop counter and overwrite it as much as you like. This is the key "cheat" for the problem of local variables. - For eachStarting at position
i
from 1 to 51(the second card in the deck), swap the card ati
with the one atrand(i, 51)
. Note that you need (note:rand(i, 51)
, NOTrand(1, 51)
. That won't give you a random shuffle)ensure that each card is randomized. - Set
deck[0]
back to zero and0. Now the whole deck is shuffled except for the first card, so swap itdeck[0]
with a random carddeck[rand(0, 51)]
and you're done.
Should be a perfectly random shuffle.C# version:
public static void shuffle(int[] deck)
{
while (deck[0] > 0)
swap(ref deck[0], ref deck[deck[0]]);
for (deck[0] = 1; deck[0] < 52; deck[0]++)
swap(ref deck[deck[0]], ref deck[rand(deck[0], 51)]);
deck[0] = 0;
swap(ref deck[0], ref deck[rand(0, 51)]);
}
public static void shuffle(int[] deck)
{
while (deck[0] > 0)
swap(ref deck[0], ref deck[deck[0]]);
for (deck[0] = 1; deck[0] < 52; deck[0]++)
swap(ref deck[deck[0]], ref deck[rand(deck[0], 51)]);
deck[0] = 0;
swap(ref deck[0], ref deck[rand(0, 51)]);
}
while (deck[0] > 0)
swap(0, deck[0]);
for (deck[0] = 1; deck[0] < 52; deck[0]++)
swap(deck[0], rand(deck[0], 52));
deck[0] = 0;
swap(0, rand(0, 52));
while (deck[0] > 0)
swap(0, deck[0]);
for (deck[0] = 1; deck[0] < 52; deck[0]++)
swap(deck[0], rand(deck[0], 52));
deck[0] = 0;
swap(0, rand(0, 52));