Using random chance for multiple event combinations

J_J

I thought I understood what I was doing, but it's been hours now and I can't figure this out. I don't know if this is an issue with stacking my ifs, or if I don't understand how random chance works.

Basically there are a series of choices that you have made up to this point that change what happens to you when you move rooms, depending on what combination of events you've done. In this situation there is an element of chance involved. So, what I'm hoping is that each combination of events would be treated as a hundred percent. For example: You stole an item, didn't call the police, or call your friend. This results in a 25% chance you end the game, a 30% chance you are attacked and a 45% chance you are fine. BUT if you stole an item, didn't call the police but DID call your friend there is only a 10% chance that you'll be attacked and 90% chance you'll be fine. It seems to only be running the first if script no matter what combination of events have happened.

get input {
  if (result = "wake up") {
    msg ("You wake up.")
    DisableTimer (wake up)
    if (not GetBoolean(phone, "policecalled") and Got (almond fudge ice cream) and not GetBoolean (phone, "TJwork")) {
      if (RandomChance(25)) {
        finish
        msg ("hospital")
        MakeObjectInvisible (almond fudge ice cream)
      }
      else if (RandomChance(30)) {
        msg ("tattoo.")
        SetObjectFlagOn (player, "heart")
        EnableTimer (heart)
        MoveObject (player, Underground Shopping)
        MakeObjectInvisible (almond fudge ice cream)
      }
      else if (RandomChance(45)) {
        msg ("bla bla description.")
        MoveObject (player, Underground Shopping)
      }
      else {
      }
    }
    else if (GetBoolean(almond fudge ice cream, "icecreamstolen") and not GetBoolean(phone, "policecalled") and not GetBoolean(phone, "TJwork")) {
      if (RandomChance(80)) {
        msg ("tattoo")
        SetObjectFlagOn (player, "heart")
        EnableTimer (heart)
        SetObjectFlagOn (player, "tattoopain")
        MoveObject (player, Underground Shopping)
      }
      else if (GetBoolean(phone, "TJwork") and GetBoolean(almond fudge ice cream, "icecreamstolen") not GetBoolean(phone, "policecalled") ) {
        if (RandomChance(10)) {
          msg ("tattoo. ")
          SetObjectFlagOn (player, "heart")
          EnableTimer (heart)
          MoveObject (player, Sketchy Room)
          MakeObjectInvisible (almond fudge ice cream)
        }
        else {
          msg ("bla bla description.")
          MoveObject (player, Sketchy Room)
        }
      }
      else if (GetBoolean(phone, "TJwork")) {
        msg ("bla bla description.")
        MoveObject (player, Sketchy Room)
      }
    }
    else {
      msg ("bla bla desciption.")
      MoveObject (player, Underground Shopping)
    }
  }
  else {
    msg ("Where are you? Is this a dream?")
    WakeFunction
  }
}

I think you've got the logic a bit confused there; as you have else if (GetBoolean(almond fudge ice cream, "icecreamstolen") and not GetBoolean(phone, "policecalled") and not GetBoolean(phone, "TJwork")) and then inside that block, there is else if (GetBoolean(phone, "TJwork") and GetBoolean(almond fudge ice cream, "icecreamstolen") not GetBoolean(phone, "policecalled") ).

So the second 'tattoo' block, and the else clause immediately after it, can only be reached if phone.TJwork is both true and false.

Also, percentage chances aren't as neat as you might hope. In an 'else if' structure, it only checks the second RandomChance if the first one is false. So if you want the chances of each segment to be 25/30/45, you would want the conditions to be RandomChance(25), RandomChance(30 * (1 - 100/25)), and RandomChance (45 * (1 - 100/(30 * (1 - 100/25)))). (that works out to 25, 40, and 100 - the last one will always work out to be 100%, because if the first to didn't happen then the last one has to)


J_J

Thank you. I will retry.


I thought you needed to use multiple ifs. That's what I do.

if (RandomChance(12)) {
  SpawnSentret (this)
}
else if (RandomChance(12)) {
  SpawnHoothoot (this)
}
else if (RandomChance(12)) {
  SpawnSpinarak (this)
}

if you are within a function I would do it this way

if (RandomChance(12)) {
  SpawnSentret (this)
  return (true)
}
if (RandomChance(12)) {
  SpawnHoothoot (this)
  return (true)
}
if (RandomChance(12)) {
  SpawnSpinarak (this)
  return (true)
}

J_J

mrangel, thanks again. I think I lost my mind on how if scripts work. I totally redid it, and it is now working perfectly. Yay.


Another thought:
If you have a set of events to choose from and you want some to be more likely than others, you may find a method like this easier than dealing with all the maths:

options = Split("A;A;B;B;B;C;C;C;C;C", ";")
chosen = PickOneString(options)
if (chosen = "A") {
  msg ("Option A has a 20% chance")
} else if (chosen = "B") {
  msg ("Option B has a 30% chance")
} else if (chosen = "C") {
  msg ("Option C has a 50% chance")
}

You can make the list of options as long or short as you want. An item that appears in the list twice as many times is twice as likely to come up. And although it uses more memory, it might actually be faster to run because it only needs to generate one random number, rather than one for every possibility.


Log in to post a reply.

Support

Forums