Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this a sufficient way to shuffle a deck of cards?

I am trying to shuffle a deck of cards in my app and I use the following code. Will this sufficiently randomize the deck? I am almost certain is will just want another opinion. Thanks!

for (int i = 0; i < 40000; i++) {
    int randomInt1 = arc4random() % [deck.cards count];
    int randomInt2 = arc4random() % [deck.cards count];
    [deck.cards exchangeObjectAtIndex:randomInt1 withObjectAtIndex:randomInt2];

EDIT: In case anyone is wondering or should come across this in the future. This is what I have gone with to shuffle my deck of cards, it is an implementation of the Fisher-Yates Algorithm. I got it from the post @MartinR suggested below which can be found here: What's the Best Way to Shuffle an NSMutableArray?

NSUInteger count = [deck.cards count];
    for (uint i = 0; i < count; ++i)
    {
        // Select a random element between i and end of array to swap with.
        int nElements = count - i;
        int n = arc4random_uniform(nElements) + i;
        [deck.cards exchangeObjectAtIndex:i withObjectAtIndex:n];
    }
like image 250
mattman88 Avatar asked Dec 25 '22 09:12

mattman88


1 Answers

Your code should work rather good if [deck.cards count] < 40000 but following is better

for (int i = [deck.cards count] - 1; i > 0 ; i--) {
    int randomInt1 = arc4random_uniform(i + 1);
    [deck.cards exchangeObjectAtIndex:randomInt1 withObjectAtIndex:i];
}

from docs:

arc4random_uniform() will return a uniformly distributed random number less than upper_bound. arc4random_uniform() is recommended over constructions like ``arc4random() % upper_bound'' as it avoids "modulo bias" when the upper bound is not a power of two.

like image 193
Avt Avatar answered Dec 28 '22 10:12

Avt