Dynamic Odds

## Introduction

Sometimes you might sometimes want to change the odds of certain items in a list based on what item was previously randomly selected from another list. This page will talk about **Dynamic Odds** which is used to have odds based on other variables used in the generator.

## Example

### Simple Example

For example, let's say you're randomly selecting a character, and then randomly selecting a fruit that they're eating. But you've got some characters that don't eat certain fruits, so you want to make sure you don't randomly select fruits that they wouldn't enjoy, or are allergic to. So let's say that Jamie is allergic to blueberries, but all of the other characters can eat any fruit. Here's how we'd prevent blueberries from being chosen if the chosen character was Jamie:

```
output
  [c = character.selectOne] was eating [fruit]

character
  Adela
  Aisha
  Jamie
  Bob

fruit
  an apple
  some blueberries ^[c != "Jamie"]  // only selectable if c is NOT equal to "Jamie"
  a slice of watermelon

```

What we're doing here is using a square block **within an odds declaration**. So instead of "static" odds like `^4` or `^0.3`, we're using a square block in place of 4 or 0.3 to *generate* the odds each time we randomly select an item from that list. In this case, we've got a "logical" statement inside the square block: `c != "Jamie"`.

This means: `c` *is not equal to* `"Jamie"`. Is that logical statement true, or false? Well, we don't know yet! It depends on what the `c` variable contains and that only gets decided when we actually run the generator. We do know that `c` will contain a character name, but we don't know which one yet.

Okay, so if we run the generator and "Jamie" is selected by the `[c = character.selectOne]` block, then `c` *does* contain "Jamie" and so `c != "Jamie"` is **false**. So the odds declaration essentially changes from `^[c != "Jamie"]` to `^false` in that case. Now, it turns out that `^false` is exactly equivalent to `^0` - they mean the same thing. So what we've done is set the odds of the "some blueberries" item to **zero** whenever `c` contains "Jamie".

Does that make sense? If not, that's okay! This is complicated stuff if you're new to coding. Try re-reading the above carefully, and if you're still confused, read below, because there's another way to do this which might make more sense to you (and remember, you can always ask for help on the forum).

### If Else Equivalent

You might not have come across it in your Perchance adventures yet, but you can make a square block output two (or more) different things based on a "question" that you ask Perchance, otherwise known as an "if/else" or "conditional" statement (`if x then y, otherwise z`):

```
number = {1-6}
output
  You rolled a [n = number.selectOne]. [if (n < 4) {"Too bad"} else {"Cool"}].

```

What's going on here? Let me explain: This stuff is called "if/else" syntax, and it's quite common in the programming world. In general, if/else statements say: **if this\_thing is true, output something, otherwise output other\_thing**. So "else" really means "otherwise" In the above example, we're saying "If `n` is less than `4`, output `"Too bad"`, otherwise output `"Cool"`.

So, we can use if/else to write our previous character/fruit example in another way:

```
fruit
  an apple
  some blueberries ^[if (c == "Jamie") {0} else {1}]
  a slice of watermelon

```

That's a bit longer to write, but it might make it a bit easier to understand what's going on. If `c` equals `"Jamie"`, then we output `0` as the odds of "some blueberries", otherwise we output `1`.

> Side note: Notice that we've been putting `Jamie` inside quotation marks in our dynamic odds and if/else notation? That's important because if we wrote `if (c == Jamie) ...` then Perchance would interpret that as "if `c` is equal to the `Jamie` list or variable" rather than comparing `c` to the literal text "Jamie".
>
>

### Number Comparison

Let's go through another example of some dynamic odds. See if you can work out what's going on:

```
temp = {0-45}

output
  Today it was [t = temp.selectOne] degrees Celcius, [comment]

comment
  so we had to wear warm coats. ^[t < 15]
  so we went to the pool. ^[t > 30]
  so we just wore shorts and t-shirts. ^[t >= 15 && t <=30]

```

Again, notice that in the `comment` list the "odds" of each item isn't a number? It is instead a logical statement, (aka, a boolean expression). The "expression" `t < 15` means "`t` is greater than `15`". If this expression is true, then it evaluates to `1`, otherwise it evaluates to `0`.

So, for example, if `t` were `23`, then `^[t < 15]` would "evaluate" to `^1` (the default likelihood), otherwise it would evaluate to `^0` (which means it is impossible - zero probability). Here are some "operators" that you can use in dynamic odds expressions:

* `<` means **is less than**
* `>` means **is greater than**
* `<=` means **is less than or equal to**
* `>=` means **is greater than or equal to**
* `==` means **is equal to**
* `!=` means **is not equal to**

Also notice that last item in the `comment` list uses `&&` which means "and". So `^[t >= 15 && t <=30]` will evaluate to `^1` only if `t` is greater than or equal to `15` AND `t` is less than or equal to `30`, otherwise it will evaluate to `^0`. You can also use "or" in your expressions by writing `||`.

Let's quickly jump back to our Jamie/blueberries example to show how we'd make it so Aisha is also allergic to blueberries:

```
fruit
  an apple
  some blueberries ^[c != "Jamie" && c != "Aisha"]  // only if (c is NOT equal to "Jamie") AND (c is NOT equal to "Aisha")
  a slice of watermelon

```

### Setting the "Odds" on Dynamic Odds

What if, for example, you wanted to give an item an odds of `^8` if a certain boolean expression was true? Here's how you could do that:

```
comment
  ...
  what a perfect day! ^[(t == 24)*8]

```

That works because `true` is "arithmetically" equivalent to `1` and `false` is "arithmetically" equivalent to `0`. Here's a post from the forum that explains this further in case you're interested.

But we're getting into more complex territory where it may be easier to just use an if/else statement:

```
comment
  ...
  what a perfect day! ^[if (t == 24) {8} else {0}]

```

That means "if the temperature is 24, the odds will be 8, otherwise they'll be 0". As I mentioned earlier, the syntax/format is:

```
if (**this\_is\_true**) {**then\_output\_this**} else {**output\_this**}

```

The word "**else**" just means "**otherwise**" in this context. As explained earlier, you can use if/else statements anywhere in your Perchance code - not just in dynamic odds.

### If Else Calling Lists

So, for example, this code works as you'd expect:

```
comment
  what a [if (t == 24) {"perfect"} else {"terrible"}] day!

```

And again, as a reminder, notice that **we need to put quotes** around "perfect" and "terrible" - otherwise Perchance would think we were referring to lists or variables with the names `perfect` and `terrible`. Here's an example where we don't add quotes because we do actually want to refer to lists:

```
comment
  what a [if (t == 24) {goodAjective} else {badAjective}] day!

goodAdjective
  perfect
  happy
  ...

badAdjective
  terrible
  sad
  ...

```

Since we're not using quotes around `goodAdjective` and `badAdjective`, Perchance knows that we're referring to lists that have those names, rather than the literal text "goodAdjective" and "badAjective".

### Chaining If Else Statements and the Or Operator

Note that you can also "chain" the if/else statements like so:

```
comment
  ...
  what a perfect day! ^[if (t == 24) {8} else if (t < 24) {4} else {1}]

```

Okay, back to dynamic odds. Let's throw an "or" operator in our previous example to make it so `23` degrees also causes the "what a perfect day!" comment with a high probability:

```
comment
  ...
  what a perfect day! ^[if (t == 24 || t == 23) {8} else {1}]

```

### Order of Operations

Brackets become very important in boolean expressions when they start to become complex and include both "and" and "or" operators. Do you remember "order of operations" from primary school? They might have taught you a term like "BIMDAS" to help you remember which operations come first. Boolean expressions also have an order of operations:

1. Brackets
2. Less-than / greater-than
3. Equals-to / not-equal-to
4. And
5. Or

So you'll need to use brackets to create complex expressions like this, for example:

```
... ^[x > 10 && (y < 12 || z == 1)]

```

As hinted at in the `*8` example above, you can also use arithmetic expressions in dynamic odds, just like you can in normal square bracket blocks. Let's start with a simple example using subtraction inside square brackets:

```
temp = {0-45}

output
  Today it was [t = temp.selectOne] which is 7 degrees greater than yesterday, when it was [t-7] degrees.

```

We can "randomize" the number `7` in the above example like this:

```
temp = {0-45}
diff = {5-10}

output
  Today it was [t = temp.selectOne] which is [d = diff.selectOne] degrees greater than yesterday, when it was [t-d] degrees.

```

And here's a "contrived" example that uses some arithmetic inside dynamic odds notation (since, at the moment, I can't think of a *simple* "real-world" example where this would be useful):

```
num = {1-6}

output
  I rolled a [n1 = num.selectOne] and a [n2 = num.selectOne]. [comment]

comment
  Multiply. ^[n1 * n2]
  Add. ^[n1 + n2]
  Divide. ^[n1 / n2]
  More complex. ^[n1 + n2 * n1]
  More complex, plus re-ordering. ^[(n1 + n2) * n1]

```