Harazzy
Harazzy

Reputation: 201

Swift probability of random number being selected?

I am trying to make a game where you can upgrade a specific item of yours. The quality of the new item is going to be random and based on something like this:

10% worse - 35% better then current item level = 55% chance
36% better to 90% better then current item level = 35% chance
91% better to 200% better then current item level = 5% chance
201% better to 500% better then current item level = 2.5% chance
500% better to 2000% better then current item level = 2.5% chance

How would I go about making it so a random number that is generated would have a, for example, 55% chance of being only 35% better? I had a crack and came up with this (ignore the % numbers, I was just using this one for testing).

let randomNumber = Int(arc4random_uniform(1000))


if randomNumber <= 700 {
    println("hey")
    var newLevel = (Double(Double(randomNumber) / 700.00) + 0.1) * Double(pickDamage)

} else if randomNumber <= 800 && randomNumber > 700 {
    var newLevel = (Double(Double(randomNumber) / 700.00) + 1.00) * Double(pickDamage)
} else if randomNumber <= 1000 && randomNumber > 950 {
    var newLevel = (Double(Double(randomNumber) / 700.00) + 2.00) * Double(pickDamage)
}

But this isn't really doing it the way I want.

Upvotes: 3

Views: 4325

Answers (2)

Sasha Lopoukhine
Sasha Lopoukhine

Reputation: 151

I think unifying your solution with ColinE's would be best:

func randomPermille() -> Int {
    return Int(arc4Random(1000))
}

let randomNumber = randomPermille()
switch(randomNumber) {
    case 0..<550:
        println("10% worse - 35% better then current item level")
    case 550<900:
        ... and so on

It's generally a bad idea to compare Floats or Doubles to Ints because of weirdness of floating points around whole integers. (The division by 10.0 seems especially worrying to me, but that might not matter in the end)

Upvotes: 4

ColinE
ColinE

Reputation: 70162

Why not use the Swift switch statement combined with pattern matching:

// create a random percent, with a precision of one decimal place
func randomPercent() -> Double {
  return Double(arc4random() % 1000) / 10.0;
}

let randomNumber = randomPercent()
switch(randomNumber) {
case 0..<55:
  println("10% worse - 35% better then current item level")
case 55..<90:
  println("36% better to 90% better then current item level")
case 90..<95:
  println("91% better to 200% better then current item level")
case 95..<97.5:
  println("201% better to 500% better then current item level")
default:
  println("500% better to 2000% better then current item level")
}

This makes the logic very clear.

Upvotes: 10

Related Questions