Decision Structures

Remember, a computer is always asking one question: "Where is my next instruction?" Often, you'll want the answer to that question to depend on some certain conditions.

The basic structure for making decisions is the if statement.

If Statements

The syntax for an if statement in MOO is as follows:

if (condition)
  statement1;
else
  statement2;
endif

If condition is true, then statement1 will be executed. If condition is false, then statement2 will be executed.

If statements have two guarantees:

Now let's reiterate the concept by considering this code:

statement1;
if (condition)
  statement2;
else
  statement3;
endif
statement4;

Remember the all-important question: "Where's my next instruction?" When the computer completes statement1, it will ask this question. The answer depends on condition; if condition is true, the next instruction is statement2; otherwise, it's statement3. Now, the computer has just finished either statement2 or statement3, and again it asks, "Where's my next instruction?" Regardless of which instruction was just executed, the next instruction will be statement4. It always executes one or the other part of a two-branch if statement; never both.

There is also the one-branch if statement:

statement1;
if (condition)
  statement2;
endif
statement3;

After statement1, where's the next instruction?

A one-branch if either executes its code, or it doesn't. Either way, it continues on to the next line after it.

There is also the multi-branch if, using the keyword "elseif". This is left as an exercise to the reader, but there will be some in later examples in any case.

Conditions

Conditions are considered boolean, either true or false. Unlike other languages, boolean values are not their own data type; any data type can be considered true or false.

Look back at the data types chart. The null values are all considered false. Any other value is considered true. The exception is the object data type, which is always false.

Let's go back to our ball:kick verb. Let's say we want to make sure the player is actually holding the ball before they can kick it. In that case, what we need to check is whether the ball's location is the same as the player.

if (this.location == player)
  player:tell("You kick ", this.name, " across the room.");
  player.location:announce(player.name, " kicks ", this.name, " across the room.");
else
  player:tell("You have to hold the ball before you can kick it!");
endif

The == operator, like all comparison operators, returns either the integer 1 for true, or the integer 0 for false. If the ball's location is not the player, then the statement after the "else" will be executed, and the others will not.

While we're here, let's notice some more data types. Note the quotes around some of the words, denoting string values. Also take note that the "name" property is a string value, and notice how the strings are listed together with commas.

Logical Operators

Sometimes you need to test more than one condition at a time. It would make sense if the player could kick the ball if he/she was holding it, or if the ball was at the player's location.

Take a look at the following code:

if (this.location == player || this.location == player.location)
  player:tell("You kick ", this.name, " across the room.");
  player.location:announce(player.name, " kicks ", this.name, " across the room.");
else
  player:tell("There's no ball around here!");
endif

The if statement in this case will return true if the ball is at the player, or if the ball is at the player's location, or if both are true (which is impossible in this case, of course, but would be true if it was possible).

The "and" (&&) operator is similar in that it combines two conditions. In the case of "and", condition1 must be true and condition2 must be true for the entire statement to be true. If either one is false, or if both are false, then the entire statement returns false.

Truth tables are used to chart the results of every possible combination:

And

Condition 1 Condition 2 Condition 1 && Condition 2
True True True
True FalseFalse
FalseTrue False
FalseFalseFalse

Or

Condition 1 Condition 2 Condition 1 || Condition 2
True True True
True FalseTrue
FalseTrue True
FalseFalseFalse

Not

Condition !Condition
True False
FalseTrue

A Note Of Unprecedented Importance

Take extreme caution not to confuse the comparison operator == with the assignment operator =.

You may be trying to do this:

if (variable == value)

But instead you type:

if (variable = value)

The first statement tests whether variable is equal to value. The second statement will assign value to variable, and then, because any non-null value is true, the if statement will probably return true.

This is annoying and difficult to catch at best, and damaging at worst: imagine if you accidentally assigned a new value to an object's property when you meant to test it! Be careful, and pay attention to which you're typing.

Having said that, it must be added that you will make this mistake at some point. Everyone does, and it's the bane of C-based programmers everywhere. Just learn to make it something you check first.

Another solution is the following:

if (value == variable)

This is the same test with the same result, just with the two values reversed. If you accidentally replace the equality operator with the assignment operator, trying to assign variable to value will result in an error, stopping your program from executing, but doing no damage. Some programmers swear by this, but it isn't possible to do in all cases, so don't depend on it.