0
votes

I'm making a memory game in iOS. There is a 4x4 grid and I want to know the logic of how can I generate random numbers not greater than 4. These numbers will be assigned to 16 cells of 4x4 grid. But when I apply the functions of random numbers it generate lets say 2 6 times, but in a 4x4 grid I want it to generate one number max 4 times. Here is how I'm doing it:

for (int i=0; i<16; i++) {
        int r = arc4random() % 4;
        NSLog(@"r = %d at i = %d",r,i);
    }

But it generates one number more than 4 times. One more problem I just found that there is a chance that a number never occurs say 0 occurs 4 times, 2 occurs 8 times and 3 occurs 4 times so 1 will be skipped. Kindly address that problem too.

2
Please confirm - each number 0, 1, 2, and 3 should each appear exactly 4 times. Correct? That's the only way you can fill 16 spots where no one number happens more than 4 times.rmaddy
@rmaddy yes that is true. One more problem I just realized that there is a chance that a number never occurs. Kindly address that problem too.Chaudhry Talha
@TalhaCh Sorry, but you're not listening at all at this point. It's all in Bair's answer and in the comments below it.Lyndsey Scott
@TalhaCh Not possible. To fill 16 spots with 4 numbers where no one number can occur more than 4 times, this means all 4 numbers MUST occur exactly 4 times each.rmaddy
@LyndseyScott I got my answer. Which I was not getting before. :)Chaudhry Talha

2 Answers

4
votes

You don't want to allow more than 4 of each 1 .. 4. Nevertheless, you want to fill a 4x4 grid, this implies that there must be 4 of each number. Assume otherwise, then you will end up with less than 16 numbers. What I recommend you do is create an array that contains four of each number and shuffle it using this answer and place the numbers appropriately.

1
votes

You can generate random numbers between 1..4 which does not exceed 4 times of each numbers using this solution

//create the property to add the integers
@property (nonatomic, strong) NSMutableArray *myArray;

- (void)generateMyRandomArray {
    _myArray = [[NSMutableArray alloc] init];
    for (int i=0; i<16; i++) {
        NSInteger r = [self randomNumber];
        [self validateIfNumberExist:r];
    }

    NSLog(@"my Array = %@", self.myArray); // this is resulted array between 1..4 each 4 times
    NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:nil ascending:YES];
    NSArray *result =[self.myArray sortedArrayUsingDescriptors:@[sort]];
    NSLog(@"Result Array = %@", result); //just to check 
}

- (void)validateIfNumberExist:(NSInteger)number {
    if ([self.myArray count] > 0) {
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF == %d", number];
        NSArray *resultArray = [self.myArray filteredArrayUsingPredicate:predicate];
        if ([resultArray count] < 4) {
             [self.myArray addObject:@(number)];
        } else {
            [self validateIfNumberExist:[self randomNumber]];
        }
    } else {
        [self.myArray addObject:@(number)];
    }
}

- (NSInteger)randomNumber {
    return 1 + arc4random_uniform(4);
}