When we execute the same lines of code several times, that's called a loop. Many Axbasic scripts will use loops of one kind or another.
In terms of pure BASIC, loops can be used to
In a MUD context, an Axbasic script might use loops to
For the sake of keeping things simple, we'll concentrate on abstract examples for now; we can go orc-hunting a little later.
The first kind of loop is a DO loop. We might use it to count to five. Here is a complete example.
LET count = 0
DO
LET count = count + 1
PRINT count
UNTIL count = 5
PRINT "Finished!"
END
DO marks the start of the loop and UNTIL marks the end of it.
The loop itself contains two lines: a LET statement and a PRINT statement. Axbasic executes these two lines again and again until the count reaches 5. At that point, the loop stops. If you run the script, you'll see the following output:
1
2
3
4
5
Finished!
Another example is this guessing game. The guessing game we used earlier gave up after one attempt, but this game pesters the user until they guess correctly. Try it for yourself.
LET answer = 5
DO
PRINT "What number am I thinking of?"
INPUT number
UNTIL number = answer
PRINT "Correct!"
END
When writing any kind of loop, you have to be make sure that the loop can actually end, otherwise it will keep going indefinitely and you'll be left scratching your head, wondering why your script has stopped working.
In this script, the author has mistyped the UNTIL line, accidentally writing a 0 rather than a 10. count starts from 1 and continues increasing, so the loop never ends; the script keeps running until the computer breaks down or until human civilisation collapses (whichever happens first).
! Count from 1 to 10
LET count = 1
DO
count = count + 1
UNTIL count = 0
PRINT "Finished!"
END
A typo like that is quite easy to spot. However, Axbasic scripts can manipulate data from the very simple to the fiendishly complicated, and it might not always be safe to wait for the result you were expecting. Depending on what you are hoping to achieve, you will usually need to add some way to stop a loop from running forever.
A simple example is this modified guessing game. The loop stops if the user types the correct answer, but it also stops when the user gets bored and types stop.
This is achieved with an EXIT DO statement, which stops the loop immediately. Axbasic then executes whichever line comes after the UNTIL statement.
LET answer$ = "bilbo"
PRINT "Let's play a game!"
PRINT "If you get bored, type stop"
DO
PRINT "What is my name?"
INPUT guess$
IF guess$ = "stop" THEN
EXIT DO
ELSE IF guess$ = "stop" THEN
PRINT "Correct!"
EXIT DO
ELSE
PRINT "Wrong!"
END IF
UNTIL guess$ = answer$
PRINT "Ok, no more games"
END
Another kind of loop is a WHILE loop. Here's another example that counts to five.
LET count = 0
WHILE count < 5
LET count = count + 1
PRINT count
LOOP
PRINT "Finished!"
END
WHILE marks the start of the loop and LOOP marks the end of it.
The loop again contains two lines: a LET statement and a PRINT statement. Axbasic executes these two lines again and again until the count reaches 5. At that point, the loop stops.
There is an important difference in the way DO loops and WHILE loops behave. The lines inside a DO loop are executed at least once; the lines inside a WHILE loop might never be executed, as in the following example.
LET count = 10
WHILE count <= 5
LET count = count + 1
PRINT count
LOOP
PRINT "Finished!"
END
When Axbasic reaches the WHILE statement for the first time, the count is already bigger than 5, so Axbasic immediately skips to the first line after the LOOP statement. The output simply looks like this:
Finished!
By the way, you can use EXIT WHILE if you need to stop a WHILE loop prematurely, just you used EXIT DO to stop a DO loop prematurely.
A useful trick is to use an expression, rather than a condition. Compare the following three lines.
WHILE count < 5
WHILE 1
WHILE 0
The first line contains a condition that might be true, or might be false. The remaining lines use an expression. WHILE 1 is always true and WHILE 0 is always false.
Using this you can create a loop that runs forever:
WHILE 1
PRINT "Hello, world!"
LOOP
END
...or a loop that never runs:
WHILE 0
PRINT "Hello, world!"
LOOP
END
DO loops can also use an expression rather than a condition. Once again, UNTIL 1 is always true and UNTIL 0 is always false.
This loop runs forever:
DO
PRINT "Hello, world!"
UNTIL 0
END
...but this loop runs exactly once:
DO
PRINT "Hello, world!"
UNTIL 1
END
You can use any numeric or string value in your WHILE and UNTIL statements. The value 0 is considered to be false, all other numeric values are considered true. An empty string is considered to be false, all other string values are considered true.
The third and final kind of loop is a FOR loop. If you want to do something exactly ten times or exactly a hundred times, a FOR loop is what you need.
Once again, let's count to 5.
FOR a = 1 TO 5
PRINT a
NEXT a
PRINT "Finished!"
END
FOR marks the start of the loop and NEXT marks the end of it. The loop itself contains a single PRINT statement.
When the FOR statement is executed the first time, a is set to 1. When it's executed the second time, a is set to 2. The third time, it is set to 3.
If you write a script like this, don't forget to write NEXT a rather than just NEXT. If you forget the variable, you'll see an error message.
Suppose that you want to count in tens, instead of one number at a time. In that case, you can use a STEP statement.
FOR a = 10 TO 50 STEP 10
PRINT a
NEXT a
PRINT "Finished!"
END
If you wanted to count backwards from 5 to 1, you would use a negative number after STEP.
FOR a = 5 TO 1 STEP -1
PRINT a
NEXT a
PRINT "Finished!"
END
You could even count backwards in tens.
FOR a = 50 TO 10 STEP -10
PRINT a
NEXT a
PRINT "Finished!"
END
If you miss out STEP altogether, Axbasic counts upwards in ones. Both of the following lines behave exactly the same way:
FOR a = 1 TO 5
FOR a = 1 TO 5 STEP 1
The NEXT statement has an important role: it adds a number to the variable a. This happens even on the last loop. Consider the following script:
FOR a = 10 TO 50 STEP 10
PRINT a
NEXT a
PRINT "Finished! The variable is now:"
PRINT a
END
...which produces an unexpected result:
10
20
30
40
50
Finished! The variable is now:
60
Loops can contain other loops. If you want to list the coordinates of all the squares in a grid, you could use two FOR loops, one inside the other.
FOR x = 1 to 5
FOR y = 1 to 5
PRINT "X/Y"
PRINT X
PRINT Y
NEXT Y
NEXT X
END
A FOR loop can go inside a WHILE loop, and a DO loop can go inside a FOR loop. In fact, any such combination of loops is allowed. If you use your TAB key properly, you'll find it easier to keep track of which line belongs to which loop.
There is a second type of FOR loop which we'll discuss when we get to arrays.