If/Else Statements

## Introduction

In Perchance it's possible to make a square block output two *different* things depending on whether the answer to a "question" is true or false. This page is about `if/else` statements that are used as conditionals in our generators.

## Examples

### Simple Example

Below is a simple example where we:

1. Select a random number and put it in the "variable" called `n` (so we can use that number later)
2. Check if that number less than 4
3. If it is, then we output a random item from the `sad` list
4. Otherwise ("else") we output an item from the `happy` list

```
number = {1-6}

output
  You rolled a [n = number.selectOne]. [if (n < 4) {sad} else {happy}].

sad
  Too bad
  Oh well

happy
  Cool
  Nice

```

Here's an example generator with the above code for you to play around with. You should think of the word `else` as being equivalent to the word "otherwise". So if/else statements are written in the following form:

```
if (thisIsTrue) {outputThis} else {outputThisOtherThing}

```

Which just means:

```
if **thisIsTrue** then **outputThis**, otherwise **outputThisOtherThing**

```

### `If/Else` Statements Outputs

Notice that we don't need to put square brackets around `sad` and `happy` in the if/else statement? That's because whenever you're writing stuff inside square brackets you can (and should) refer to lists/variables without square brackets around their name. So, to be clear:

```
[if (n < 4) {[sad]} else {[happy]}]     // incorrect!
[if ([n] < 4) {sad} else {happy}]       // incorrect
[if (n < 4) {sad} else {happy}]         // correct 😌

```

If instead of having lists for sad and happy results, we just wanted to output some literal text depending on what `n` was, then we surround the stuff that's within the curly brackets in quotation marks, and that tells Perchance to output the literal text in the quotes rather than looking for lists with those names:

```
number = {1-6}

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

```

#### Text Tests

But so far we've only learned how to test if n is *less than* 4. Here's how we'd test other types of conditions:

* `if (n > 4) ...` means: if `n` **is greater than** 4
* `if (n <= 4) ...` means: if `n` **is less than or equal to** 4
* `if (n >= 4) ...` means: if `n` **is greater than or equal to** 4
* `if (n == 4) ...` means: if `n` **is equal to** 4
* `if (n != 4) ...` means: if `n` **is not equal to** 4

And here's an example where we test if `f` is equal to "banana":

```
fruit
  apple
  banana
  peach

output
  Did you know that a [f = fruit.selectOne] is [if (f == "banana") {"not spherical"} else {"spherical"}]?

```

Here's an example generator using the above code. Notice that we write `if (f == "banana")` and not `if (f == banana)`. That's because the latter one would actually look for a list called `banana` instead of comparing `f` to the literal text "banana". It's easy to accidentally forget those quotes, so watch out for that.

#### Testing Variable to Variable

You can also compare two variables with one another like so:

```
fruit
  apple
  banana
  peach

output
  [f1 = fruit.selectOne] and [f2 = fruit.selectOne] are [if (f1 == f2) {"the same"} else {"different"}] fruits.

```

Here's an example generator using the above code.

#### Output Nothing

If you'd like an "if" *without* an "else", then you can just use empty quotes for the "else":

```
if (a == 4) {outputThis} else {""}

```

If you want to *do* something in an if/else statement, but not output anything, then use the normal `, ""` approach like this (here we add 3 to `a` if it's equal to 4):

```
if (a == 4) {a=a+3, ""} else {""}

```

#### Curly and Lists with Text

If you want your outputs to contain regular text *and also square/curly blocks*, then you should wrap all the output text in quotes:

```
if (b > 0) {"There are a few [animal.pluralForm] here."} else {"There are {not any|no} animals here."}

```

### Multiple Conditions

So far, we've been writing if/else statements of the following form:

```
if (thisIsTrue) {outputThis} else {outputThisOtherThing}

```

But we can actually add more "conditions" that output different things, like so:

```
if (thisIsTrue) {outputThis} else if (thisOtherThingIsTrue) {outputThisOtherThing} else {outputThisAsABackup}

```

And we can "chain" as many of these `else if`s together as we want. Here's an example:

```
number = {1-6}

output
  You rolled a [n = number.selectOne]. [if (n < 3) {"Ouch."} else if (n < 5) {"Not too bad."} else {"Woo hoo!"}]

```

Here's an example generator using the above code. As you can see, we're outputting "Ouch." if they rolled less than 3, otherwise if they rolled less than 5 we output "Not too bad.", and if neither of those conditions (`n < 3` and `n < 5`) were true, then we output "Woo hoo!" because that must mean they rolled either a 5 or a 6.

#### Substituting Dynamic Odds for `If/Else` Statements

As I said, we can have as many `else if`s as we like, so we could have one for every number:

```
You rolled a [n = number.selectOne]. [if (n == 1) {"Ouch."} else if (n == 2) {"Dang."} else if(n == 3) {"Not great."} else if (n == 4) {"Not bad."} else if (n == 5) {"Pretty good!"} else {"Woo hoo!"}]

```

But for that sort of thing we'd be better off using dynamic odds (read the "Dynamic Odds" section on this page to learn about this):

```
number = {1-6}

output
  You rolled a [n = number.selectOne]. [comment]

comment
  Ouch. ^[n == 1]
  Dang. ^[n == 2]
  Not great. ^[n == 3]
  Not bad. ^[n == 4]
  Pretty good! ^[n == 5]
  Woo hoo! ^[n == 6]

```

### AND and OR Operators

There's one more feature of if/else that might come in handy for you. Sometimes instead of simple conditions like "if `n` is greater than 2", you want something a bit more complicated like "if `n` is greater than 2 **and** `n` is less than 5". Here's how we'd write that:

```
if (n > 2 && n < 5) ...

```

So as you can see, `&&` means "**and**". Here's how you can use "**or**" in your conditions:

```
if (n == 1 || n == 6) ...

```

That means "if `n` is equal to 1 **or** `n` is equal to 6".

> **Side note:** It's very easy to accidentally write a single equals sign in your conditions like this: `if (n = 1) ...`. That actually sets `n` equal to 1 rather than checks whether it's equal to 1. So if you're getting weird behavior with your if/else statements, just double-check that you're using double-equals to check equality rather than a single equals sign.
>
>

```
if (n > 2 && f != "banana" ) ...

```

That means "if `n` is greater than to 2 **and** `f` is not equal to `"banana"`".

### Grouping Conditions

If you need *really* complex conditions, then you will need to use brackets to properly "group" them so they get executed in the correct order, like so:

```
if(x > 10 && (y < 12 || z == 1)) ...

```

### `If/Else` Stylings

There is actually another "short-hand" way to write if/else statements. The following two lines of code are equivalent:

```
[if (n < 3) {"Not great."} else {"Cool!"}]

[n < 3 ? "Not great." : "Cool!"]

```

As you can see, the latter code is a bit shorter, but perhaps a bit harder to read. The general format of the short-hand if/else statement is:

```
[ifThisIsTrue ? outputThis : otherwiseOutputThis]

```

And you can use it exactly like the previous approach. Here's an example with 2 conditions:

```
[n == 5 || n == 6 ? "Great!" : ":("]

```

And here's an example with chained `else if`s:

```
[n == 1 ? "Ouch" : n == 2 ? "Dang" : "Not terrible"]

```

And here's a longer chain:

```
[n == 1 ? "Ouch" : n == 2 ? "Dang" : n == 3 ? "Not great" : n == 4 ? "Not too bad" : n == 5 ? "Great!" : "Woo hoo"]

```

So as you can see the pattern for chaining else/ifs with the short-hand method is:

```
[condition1 ? result1 : condition2 ? result2 : condition3 ? result3 : backupResult]

```

And you can bunch the condition/results together to make it easier to read if you want:

```
[condition1?result1 : condition2?result2 : condition3?result3 : backupResult]

```

"Side Note"There is a "short-hand" version of if/else statements that looks like this:

```
[ifThisIsTrue ? outputThis : outputThis]

```

So here's what the above dice example would look like:

```
You rolled a [n = number.selectOne]. [n < 4 ? sad : happy].

```

I'll explain this short-hand version properly towards the end of this section. Keep reading until the end to learn more about this syntax.

The curly brackets of the long-hand if statement can be confusing, because they're completely different to the normal curly brackets in Perchance. That's because everything that you write inside square brackets is actually JavaScript, and so the meanings of different special characters aren't the same as in regular Perchance code (when you're writing outside square brackets, that is). Luckily, in JavaScript, you can also write if/else statements like this:

```
if (thisIsTrue) outputThis ;else outputThisOtherThing

```

So the above sad/happy sad/happy example would look like this:

```
You rolled a [n = number.selectOne]. [if(n < 4) sad ;else happy].

```

Feel free to use this approach if it looks nicer to you.
### Where `If/Else` Fails

#### Dynamic Sub-List Referencing

There are cases where if/else statements aren't the best solution to the problem, even though they seem like the most obvious one. Here's an example:

```
output
  [r = race.selectOne, ""] Their name is [r == "human" ? name.human : r == "orc" ? name.orc : r == "elf" ? name.elf : "name/race error"] and their race is [r].

name
  human = {kate|bob}
  orc = {gruan|tsarok}
  elf = {gaia|filae}

race
  human
  orc
  elf

```

This example can be improved a lot by using "dynamic sub-list referencing", which is explained in another section on the page you're reading right now. Here's the simplified version that uses dynamic sub-list referencing:

```
output
  [r = race.selectOne, ""] Their name is [name[r]] and their race is [r].

name
  human = {kate|bob}
  orc = {gruan|tsarok}
  elf = {gaia|filae}

race
  human
  orc
  elf

```

You should read the dynamic sub-list referencing section to understand the above code properly, but the basic gist is that `[name[r]]` gets the sub-list (or "sub-property") that has the same name as the value that's stored in the `r` variable. So if `r` contains "elf", then `[name[r]]` is the same as writing `[name.elf]`.

If/else statements are very useful, but if you're starting to write really complex chains of `else if`s, then you should question whether you're doing it in the most efficient way. Often times there's a neater solution using hierarchical lists and dynamic sub-list referencing.

#### Functions

Another way to make complex if/else statements neater is to use **functions**, which are explained in a later section on this page. I'll give you the basic gist of it now, but read the functions section to learn more. Let's say we've got a generator where we roll a dice and then we want to double it if it's greater than or equal to 5:

```
dice = {1-6}

output
  [d = dice.selectOne, ""][if(d >= 5) {d = d*2, ""} else {""}]Your calculated damage is [d].

```

We could encapsulate all the damage calculations into a simple function like this:

```
output
  Your calculated damage is [calculateDamage()].

dice = {1-6}

calculateDamage() =>
  d = dice.selectOne
  if(d >= 5) {
    d = d * 2
  }
  return d

```

The nice thing about functions is that we don't need to scatter lots of `, ""` throughout our code, because the only thing that gets output by a function is the thing that we put after the `return` statement (which in this case is `d`).

The other nice thing is that complex if/else statements (especially *nested* ones) are much more readable when you can put them on multiple lines:

```
calculateDamage() =>
  d = dice.selectOne
  if(d >= 5) {
    d = d*2
  } else if(d == 4) {
    d = d + 2
  } else {
    d = d + 1
    if(d == 2) {
      d = 1
    }
  }
  return d

```

That still looks complicated, but it's much better than having it in a single line! You can treat the output of a function just like you would the output of any other command/plugin/etc in Perchance, so, for example, we can store the output of `calculateDamage()` and use it later:

```
output
  [d1 = calculateDamage(), d2 = calculateDamage(), ""]Your calculated damage is [d1] with a bonus of [d2] damage if it's a full moon.

```