0

I've declared a static array of integer from 1 to 5 and now want to call randomly each number with each press of a button. I don't want the same number to be called twice.

int randomNumber;
static int size = 5;

int position = arc4random() % size - 1;
randomNumber = usedNumbers[position];
int switcher = usedNumbers[size]; // wrong
usedNumbers[position] = usedNumbers[size];
size--;
usedNumbers[position] = switcher;

Here's what I've done so far. There's a hole in my logic somewhere and I could do with some help. I think it's something to do with the switcher which is trying to hold a number whilst another is being deleted.

Bart
  • 19,692
  • 7
  • 68
  • 77
Bushes
  • 1,010
  • 1
  • 18
  • 37
  • possible duplicate of [canonical way to randomize an NSArray in Objective C](http://stackoverflow.com/questions/791232/canonical-way-to-randomize-an-nsarray-in-objective-c), [Non repeating random numbers](http://stackoverflow.com/questions/1617630/) – outis Nov 26 '11 at 00:04
  • See also [What's the Best Way to Shuffle an NSMutableArray?](http://stackoverflow.com/questions/56648/) – outis Nov 26 '11 at 00:05
  • possible duplicate of [Unique random numbers in an integer array](http://stackoverflow.com/questions/1608181/) or [Non-repeating random numbers](http://stackoverflow.com/questions/1617630/) – jscs Nov 26 '11 at 03:39

1 Answers1

2

If all you want to do is to show a random number every time the button is clicked, here is some code that can help.

But first, the line you use to create the position is wrong. Do this instead:

int position = (arc4random() % 5) + 1; // Creates a random number between 1 and 5.
int position = (arc4random() % 5) - 1; // Creates a random number between -1 and 3. 

Second, I'd suggest to use an NSArray or NSMutableArray to hold your data.

I assume that you have a method that is called when you press a button. Inside that method you can simply put something like this:

int size = 5; // You might want to get the size of your array dynamically, with something like [usedNumbers count];
int position = (arc4random() % size) + 1; // Generates a number between 1-5.
NSNumber *randomNumber = [usedNumbers objectAtIndex:position]; // Here is your random number from the array.

So.. If you add the array as an instance variable to your class, your header file would look something like this:

@interface MyViewController : UIViewController

@property (nonatomic, retain) NSMutableArray *usedNumbers;

- (IBAction)buttonWasClicked:(id)sender; // Remember to connect it to your button in Interface Builder.

@end

And your implementation file:

@implementation MyViewController

@synthesize usedNumbers;

- (void)viewDidLoad {
    // Initialize your array and add the numbers.
    usedNumbers = [[NSMutableArray alloc] init];
    [usedNumbers addObject:[NSNumber numberWithInt:4]];
    [usedNumbers addObject:[NSNumber numberWithInt:13]];
    // Add as many numbers as you'd like.
}

- (IBAction)buttonWasClicked:(id)sender {
    int size = [usedNumbers count];
    int position = (arc4random() % size); // Generates a number between 0 and 4, instead of 1-5.
    // This is because the indexes in the array starts at 0. So when you have 5 elements, the highest index is 4.
    NSNumber *randomNumber = [usedNumbers objectAtIndex:position]; // The number chosen by the random index (position).
    NSLog(@"Random position: %d", position);
    NSLog(@"Number at that position: %@", randomNumber);
}

@end

If you do it like this, a random number will be chosen from the array every time the button is clicked.

Also, remember to release all your objects if you don't have ARC enabled.

PS: There are several other questions here on SO covering this subject. Remember to search before asking.

Update:

To make sure every number is used only once, you can remove it from your array when it is chosen. So the buttonWasClicked: method will be something like this:

- (IBAction)buttonWasClicked:(id)sender {
    int size = [usedNumbers count];
    if (size > 0) {
        int position = (arc4random() % size);
        NSNumber *randomNumber = [usedNumbers objectAtIndex:position];
        // Do something with your number.
        // Finally, remove it from the array:
        [usedNumbers removeObjectAtIndex:position];
    } else {
        // The array is empty.
    }
}
matsr
  • 4,302
  • 3
  • 21
  • 36
  • I appreciate the help but this method surely doesn't stop a number being repeated more then once? The number picked has to be unique every time until it has been through all of them. – Bushes Nov 27 '11 at 22:26
  • You are right, my bad. I didn't read your answer good enough. You could simply just remove the number chosen in `buttonWasClicked:`, with this line: `[usedNumbers removeObjectAtIndex:position]`. I'll update my answer. – matsr Nov 28 '11 at 22:26