baptzmoffire
baptzmoffire

Reputation: 589

Is this shuffling algorithm sufficiently random for an iOS card game?

Didn't wanna just post, "Hey, guys, can you come up with an awesome randomization method for me?" so I've been studying algorithms for shuffling a deck of cards, creating truly random permutations, etc., ALL DAY LONG and it's been rrrrrrrreally daunting. Finally settled on a simpler approach, shown below. While I do want to create a quality game, of course, I'm not going to be using this algorithm in an online casino or anything. It's just an iOS game. So, is this random/memory-efficient enough? Or should I be giving this even MORE time and effort? TIA

Aside: Whenever I write "TIA," I think, "This is Africa," not "Thanks in advance."

@implementation NSMutableArray (Shuffle)

-(void)shuffle
    {
        for (int i = [self count] - 1; i > 0; i--) {
            [self exchangeObjectAtIndex:(arc4random() % ([self count] - 1))
                      withObjectAtIndex:i];
        }
    }

    @end

EDIT:

Ok. Wanted to run some test code so I don't post something dumb. :) In response to Adam and Nielsbot, you're recommending something more like this?

-(void)shuffle
{
    for (int i = [self count] - 1; i > 0; i--) {
        [self exchangeObjectAtIndex:(arc4random_uniform([self count] - 1))
                  withObjectAtIndex:i];
    }
}

Is that right?

Would there be any benefit to repeating it, like so?

-(void)shuffle
{
for (int i = [self count] - 1; i > 0; i--) {
    [self exchangeObjectAtIndex:(arc4random_uniform([self count] - 1))
              withObjectAtIndex:i];
}

for (int i = [self count] - 1; i > 0; i--) {
        [self exchangeObjectAtIndex:(arc4random_uniform([self count] - 1))
                  withObjectAtIndex:i];
    }
}

Upvotes: 1

Views: 1310

Answers (1)

Jack
Jack

Reputation: 133599

That's almost the so called Fisher-Yates algorithm, it's O(n) as time complexity and memory efficience is not considerable since you don't allocate anything.

The only thing I'd change is the randomly chosen index that would be in range [0, i] for i-th iteration instead that the whole range (to avoid just swapping two elements twice), then it would become the algorithm I linked.

Upvotes: 3

Related Questions