0

Hello everyone I've been trying to create a game for a couple of weeks however I'm unable to create a function that randomly plays a new function all the time without replaying the same function it just played before.

I've been using the following script to generate a random function to play.

func playgame(){   
var randomgen = arc4random % 6                   
switch(randomgen){             
case 0:          
 game1()        
break      
case 1:   
 game2()   
break  
case 2:    
 game3()  
 break  
case 3:  
 game4()  
break  
case 4:   
 game5()  
 break  
case 5:   
 game6()   
 break   
default:    
 break     
  }    

When the player presses a button the function runs again generating a random game function.
How can I generate a random game without generating the same game that has been generated befor.
For example: if game1() was generated and I press the next game button I want to generate a random game from the other 5 games available. The idea is to be able to play the six game indefinitely.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Cristian Siles
  • 783
  • 1
  • 7
  • 13
  • Save the current game in a variable. When the next game is selected and randomgen match the last game call arc4random again, put that in a while loop so if there are more matches it keeps calling. – zaph Aug 11 '15 at 20:24

2 Answers2

1

I would recommend to make an NSArray of all games, then randomly select one of the games from NSArray index, remove randomized game so next time it will select randomly any of remaining games in NSArray.

That's the only way to make sure it won't repeat. You could control randomizer by using seeded version, but that only gives you an option to make it repeatable.

It can be easily achieved by making NSArray category:

- (id) randomARC4Element
{
    if(self.count > 0)
    {
        return [self objectAtIndex:[self randomIntBetweenMin:0 andMax:self.count-1]];
    }

    return nil;
}

- (int)randomIntBetweenMin:(int)minValue andMax:(int)maxValue
{
    return (int)(minValue + [self randomFloat] * (maxValue - minValue));
}

- (float)randomFloat
{
    return (float) arc4random() / UINT_MAX;
}

After all games are played, you can just recreate an array.

If you want to randomize a game just making sure that only the last one won't repeat, I would recommend keeping last randomized elements, creating NSArray of all elements, remove last randomized element and randomize any of elements from such an array - that is guarantee result after only one randomize iteration.

Grzegorz Krukowski
  • 18,081
  • 5
  • 50
  • 71
  • If you need I shared some random number utils that simplifies iOS API. Also enables using seeded generators: https://github.com/grzegorzkrukowski/random-utils – Grzegorz Krukowski Aug 12 '15 at 10:13
0

Make a while loop to check for last game.

var lastGame = -1

func playGame() {

    var randomgen = 0

    repeat {
        randomgen = arc4random % 6
    } while (randomgen == lastGame)

    lastGame = randomgen

    switch randomgen {
        case 1: game1()
        case 2: game2()    
        /* ... */
        default:
    }
}  

Avoiding infinite loop scenario in some cases. But also needs improvements in case when lastGame exceeds your games number

var lastGame = -1

func playGame() {

    var randomgen = 0
    var counter = 0
    let limit = 10

    repeat {
        randomgen = arc4random % 6
        counter++
    } while (randomgen == lastGame && counter < limit)

    if counter == limit {
        randomgen = lastGame + 1
    }

    lastGame = randomgen

    switch randomgen {
        case 1: game1()
        case 2: game2()    
        /* ... */
        default:
    }
}
iamandrewluca
  • 3,411
  • 1
  • 31
  • 38
  • I would not recommend repeating while random achieve a given value - that could become in worst case scenario infinite loop. – Grzegorz Krukowski Aug 11 '15 at 20:31
  • Adding a counter should get rid of infinite loop. I'll add this scenario to this answer – iamandrewluca Aug 11 '15 at 20:36
  • 1
    Yeah it's just theoretically possible, but in general looping until randomizer get desired value is not best apporach in my opinion. Especially if for example later on you want to randomize element only once, and you would keep results in anarray - then randomizing last element may take a bit of time depends on amount of data – Grzegorz Krukowski Aug 11 '15 at 20:38
  • 1
    I would still recommend keeping all games in NSArray, keeping last randomized game. Then create a copy of NSArray, remove last randomized game and randomize any of other elements from an array. That is just guarantee results after one randomizer iteration. – Grzegorz Krukowski Aug 11 '15 at 20:40
  • Now I understand the idea. I would keep in mind this for future, will be helpful. Thanks – iamandrewluca Aug 11 '15 at 20:44