## Loops and Conditionals

The styles of looping structure which SLUDGE features are described in this section. Firstly:

### The "for" loop:

    for (initialisation; check; next) {
       # Code here
    }

Here, initialisation, check and next are all segments of code. The initialisation segment tells the program what to do at the start of the loop; the check segment tells the program how to test whether the loop needs to continue and will be treated as a boolean (see the Treating Variables as Booleans section), and the next segment tells the program what to do at the end of every loop (for example to get onto the next record or to make sure the loop won't continue forever).

The most common example of a for loop is the following:

    var a;

    for (a = 0; a < 10; a ++) {
       # Code here
    }

Or a shorter version:

    for (var a = 0; a < 10; a ++) {
       # Code here
    }

This will set the value of a to 0, check whether a is less than 10 (it is), and then perform any code inside the body of the loop. This code can use the variable a, or even change it. After performing the code in the body of the loop, the program will execute the a++ segment (or "increase the value of a by 1"... a ++ is just a shorter way of saying a = a + 1). Now, a will have the value 1. The program will check whether it's less than 10 (it is), and so on. When the value of a reaches 10, the program will continue from the line of code after the closing bracket "}".

For loops are common in programming languages in exactly this form, and present in most programming languages in some form or another.

### The "loop" loop:

In C and C++ (and other languages) it is common to see the following code:

    for (;;) {
       # Code here
    }

The above means "execute the code again and again forever". However, SLUDGE is a little stricter with its for loops and the above will not work! Instead, in order to remove the need for abusing for loops in this way (although I'm sure they don't mind) SLUDGE features an equivalent structure:

    loop {
       # Code here
    }

Which also means "execute the code again and again forever". You can escape from one of these loops - or from any function - by returning from the function within the code using the return. (Currently, SLUDGE contains no break statement.)

### The "while" loop:

    while (check) {
       # Code here
    }

The code will be executed again and again until the value returned by check is TRUE (or equivalent - see the Treating Variables as Booleans section). Therefore check can be any segment of code which returns a value, whether a variable, a function call, a complex algorithm or whatever your program needs. If the value of check is FALSE when the program reaches the start of the loop, the contents of the loop are not executed at all.

### Using "if" and "else":

Sometimes you only want to perform a certain line (or section) of code in a particular situation. For example, if you're writing a function to handle keypresses, you will probably want to perform different actions for different keys...

    sub handleKeyPress (key) {
       if (key == "ESCAPE") quitGame ();
    }

If you need to perform more than one line, group the lines together using curly braces ("{" and "}").

    var neverSpokenToFarmer = TRUE;

    sub talkToFarmer () {
       say (ego, "Hi...");
       if (neverSpokenToFarmer) {
          say (farmer, "Hello? Who are you?");
          say (ego, "I'm Egor the ego. I'm on a quest.");
          say (farmer, "What quest would that be, then?");
          say (ego, "I'm trying to learn SLUDGE.");
          say (farmer, "Ar. Good luck to ya.");
          say (ego, "Can I ask you something?");
          neverSpokenToFarmer = FALSE;
       }
       say (farmer, "I'm a bit busy. Sorry.");
    }

In the above example, the value of neverSpokenToFarmer will be initially set to TRUE. So, the first time the function is called, the ego character will say "Hi...", the farmer character will say "Hello? Who are you?" and so on. The value of neverSpokenToFarmer will then be set to FALSE, and the farmer character will say the line "I'm a bit busy. Sorry."

If the function is called again, the condition in the if statement will not be true, and so the conversation will jump straight from the ego character saying "Hi..." to the farmer character saying "I'm a bit busy. Sorry."

Sometimes you may want to provide an alternative. For example, take the following example...

    sub talkToChicken () {
       say (chicken, "Have you spoken to the farmer yet?");

       if (neverSpokenToFarmer) {
          say (ego, "No.");
          say (chicken, "Lucky you.");
       }

       if (! neverSpokenToFarmer) {
          say (ego, "Yes.");
          say (chicken, "Did he ask about me? Huh? Huh?");
          say (ego, "Nope, he didn't mention you at all.");
       }
    }

This could be rewritten using the word else. The only place in which the word else can be used is straight after the group of commands to be executed by an if statement.

    sub talkToChicken () {
       say (chicken, "Have you spoken to the farmer yet?");

       if (neverSpokenToFarmer) {
          say (ego, "No.");
          say (chicken, "Lucky you.");
       } else {
          say (ego, "Yes.");
          say (chicken, "Did he ask about me? Huh? Huh?");
          say (ego, "Nope, he didn't mention you at all.");
       }
    }

Using else followed immediately by another if statement, it is possible to write complex structures like this...

    sub countEggs () {
       if (neverSpokenToFarmer) {
          say (ego, "I haven't introduced myself to the farmer.");
          say (ego, "If someone he's not met messes with his eggs...");
          say (ego, "Well, let's just say I'm not going to risk it.");
       } else if (numberOfEggs == 0) {
          say (ego, "No eggs? You're a pretty lousy chicken!");
          say (chicken, "Hey, I've been doing paperwork all morning.");
       } else if (numberOfEggs == 1) {
          say (ego, "I can only see one egg.");
          say (chicken, "Bite me.");
          say (ego, "But I forgot to bring my oven...");
       } else {
          say (ego, "There are " + numberOfEggs + " eggs here.");
          say (chicken, "What can I say? I've been broody lately.");
       }
    }

Note that there has always been some ambiguity with the following type of structure...

    if (condition1)
    if (condition2)
    # Code here
    else
    # More code here

Does that mean this?

    if (condition1) {
       if (condition2) {
          # Code here
       } else {
          # More code here
       }
    }

Or this?

    if (condition1) {
       if (condition2) {
          # Code here
       }
    } else {
       # More code here
    }

Well, in SLUDGE it means the second. Be warned. It's always best to use parentheses when using nested if structures to avoid potential problems and unexpected behaviour. Remember, your computer doesn't know what you mean unless you actually tell it... so be specific.

SLUDGE and this SLUDGE documentation are copyright Hungry Software and contributors 2000-2012