jj_hennessy
jj_hennessy

Reputation: 55

Eliminating repeats in a switch statement w/ Swift in iOS

In this small practice app I am building, the background is supposed to keep alternating colors every .25 seconds because it looks really cool. However because of the fact that I am using the "arc4random_uniform" function, it occasionally will pick the same case twice in a row, resulting in a long duration of the same color which I do not like. Any ideas on how to eliminate immediate repeats in these switch statements so that it does pick the same case twice in a row?

    switch arc4random_uniform(10) {
    case 0:
        self.backgroundImage.backgroundColor = UIColor.redColor()
    case 1:
        self.backgroundImage.backgroundColor = UIColor.orangeColor()
    case 2:
        self.backgroundImage.backgroundColor = UIColor.yellowColor()
    case 3:
        self.backgroundImage.backgroundColor = UIColor.greenColor()
    case 4:
        self.backgroundImage.backgroundColor = UIColor.blueColor()
    case 5:
        self.backgroundImage.backgroundColor = UIColor.purpleColor()
    case 6:
        self.backgroundImage.backgroundColor = UIColor.blackColor()
    case 7:
        self.backgroundImage.backgroundColor = UIColor.whiteColor()
    case 8:
        self.backgroundImage.backgroundColor = UIColor.brownColor()
    case 9:
        self.backgroundImage.backgroundColor = UIColor.grayColor()
    case 10:
        self.backgroundImage.backgroundColor = UIColor.blackColor()

    default:
        self.backgroundImage.backgroundColor = UIColor.clearColor()

    break;

    }

Upvotes: 0

Views: 409

Answers (3)

Lyndsey Scott
Lyndsey Scott

Reputation: 37300

Eli's answer will work, but regenerating random numbers in a while loop is unnecessarily inefficient. Instead, if the current random number is the same as the previous, I recommend incrementing the random number using the remainder when divided by 10 and using that number in the switch statement so that the random operation isn't repeated unnecessarily, ex:

var prevNum:UInt32 = 0

func changeColor() {
    var randomNum = arc4random_uniform(10)
    if randomNum == prevNum {
        randomNum = (randomNum+1)%10
    }
    prevNum = randomNum

    // insert your switch statement here
}

Theoretically (although it's improbable in practice) Eli's code can cause an infinite loop.

Upvotes: 2

Palle
Palle

Reputation: 12129

You can create a color cycle by creating an array and then shuffling it. This way, numbers cannot be repeated. Then you can go through the array and use every value once.

var numbers = [Int](0 ..< 10)

for i in 0 ..< 10
{
    let j = Int(arc4random_uniform(10))
    (numbers[i], numbers[j]) = (numbers[j], numbers[i])
}

To avoid repetitions when generating a new array, you can use

if numbers.first == oldNumbers.last
{
    numbers.remove(at: 0)
}

Upvotes: 0

Eli Sadoff
Eli Sadoff

Reputation: 7308

Try storing a variable with the previous value and before you enter the switch statement have a while statement where you do

var num = arc4random_uniform(10);
while(num == prev) {
  num = arc4random_uniform(10);
}

then go into your switch statement.

Upvotes: 1

Related Questions