0

I have a function that will randomly output a SKColor.

func getRandomColor() -> SKColor{
    let randomaval = arc4random_uniform(4)
    var color = SKColor()
    switch(randomaval)
    {
    case 0:
        color = redColor
    case 1:
        color = greenColor
    case 2:
        color = blueColor
    case 3:
        color = yellowColor
    default:()
    }
    return color
}

When two bodies collide I call this function to change colors

aball.color = getRandomColor()

    if aball.color == redColor && getRandomColor() == redColor {
        aball.color = getRandomColor() //to set the color to something other than red
        aball.colorBlendFactor = 1.0
    }

What I want to do is that, when I say aball.color = getRandomColor(), if getRandomColor() is redColor again, it needs to run the if statement again till the function returns something other than redColor. Most of the time, when my if condition is true, it calls redColor again and I can't understand how to avoid that. I basically want a different color to be returned everytime getRandomColor is called. How do I accomplish that?

Sharukh
  • 199
  • 1
  • 1
  • 12
  • How about returning **a pair of colors** (one for each object) each time there is a collision? That way, you can make sure they're different. – Nicolas Miari Apr 04 '16 at 04:33
  • You can see my answer to a similar question here: http://stackoverflow.com/a/36255680/887210 –  Apr 04 '16 at 04:37
  • @KennethBruno I looked at it, and as a beginner just starting to learn coding, I'm struggling to understand how that would apply to my situation. – Sharukh Apr 04 '16 at 17:02
  • @Sharukh We all were beginners at some time! The idea is you build an array with every color stored in it. You shuffle it so the order is "random". Then you take one from the end, use it, and put it back in a random place but not close to the end you're picking from. That way you can pick forever and not repeat the same color. –  Apr 04 '16 at 18:36
  • Gotcha, I'm gonna try to implement that in, and get it working – Sharukh Apr 04 '16 at 19:01

1 Answers1

0

How about repeatedly calling your getRandomColor() function until the result is something other than the ball's current color? :

repeat {
  let newColor = getRandomColor()
} while newcolor != aball.color
aball.color = newColor

Alternatively, you could re-write getRandomColor to accept a parameter of a color it shouldn't return and then call your amended function with aball.color:

func getRandomNumber(notColor: SKColor) -> SKColor{
    repeat {
       let randomaval = arc4random_uniform(4)
       var color = SKColor()
       switch(randomaval)
       {
       case 0:
           color = redColor
       case 1:
           color = greenColor
       case 2:
           color = blueColor
       case 3:
           color = yellowColor
       default:()
       }
      let newColor = getRandomColor()
    } while color != notColor
    return color
}

Then, when you want to change the color of the ball:

aball.color = getRandomColor(notColor: aball.color)

another approach is to have getRandomColor track its own last result. In your initialisation decalre:

var lastrandomcolor: SKColor

then

func getRandomNumber() -> SKColor{
    repeat {
       let randomaval = arc4random_uniform(4)
       var color = SKColor()
       switch(randomaval)
       {
       case 0:
           color = redColor
       case 1:
           color = greenColor
       case 2:
           color = blueColor
       case 3:
           color = yellowColor
       default:()
       }
      let newColor = getRandomColor()
    } while color != lastRandomColor
    lastRandomcolor = color
    return color
}

then just use:

aball.color = getRandomColor()

I prefer the 2nd approach where your pass a color that you don't want returned, as it gives you more control i.e. at certain times, you might not want the ball to be some other colour, not just it's own color. e.g. not blue if its in the sky. you could even pass an array of colours that shouldn't be returned.

Steve Ives
  • 7,894
  • 3
  • 24
  • 55
  • I'm trying your second approach, but it says `use of unresolved identifier "color"`. Also, I realized that I had made a mistake while writing down my code here. The `func getRandomNumer() -> SKColor` is meant to be `func getRandomColor -> SKColor`. I don't know if that is what is the causing the error. I have updated my question too – Sharukh Apr 04 '16 at 14:01
  • 1
    This is not a good way at all to solve your problem, worst case scenario means you are stuck in an infinite loop. You really should remove the color from the evaluation process all together to ensure 100% success that the same color is not picked. – Knight0fDragon Apr 04 '16 at 15:52
  • The only way to get stuck in an infinite loop is if your algorithm to pick your new colour always returns the same result which happens to be the colour you don't want. In that case, the problem is the initial colour picker, not the exclusion process. But you are right in that you have to be careful with loops to make sure that there is a get-out clause. – Steve Ives Apr 04 '16 at 17:07