GFAflowcontrol

From Atari Wiki
Revision as of 12:28, 13 October 2011 by Admin (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Flow Control Part 1

This time you'll finally make your programs do things more then once without having to retype your code. The creation of so called loops is essential for making complex programs work. The concept of looping and simple counting loops

Before going further let me explain you the fundamental idea of looping. The idea is to make your program repeat a section of code for a defined amount of time. You may let GFABASIC count a variable for you and you can then use the value of that variable in an ongoing calculation. Or you can let GFABASIC loop a certain part of code until a special condition has been met. Take a look at the following sample program:

FOR i%=1 TO 5
  PRINT i%
NEXT i%

This little example program loops 5 times and counts the variable i% from 1 to 5 and prints the current value to the screen. This sort of loop is called a FOR-NEXT-loop. You can use any numerical variable to count. Most often this sort of loop is used to do things a certain amount of time or to iterate over a list. The loop will repeat the code between the FOR and its corresponding NEXT. Each time GFABASIC reaches the NEXT, it will increment the count variable and will stop the loop if the maximum count has been reached.

You can ofcourse have another loop inside the current one. Just make sure not to use the same variable for counting or GFABASIC will do unpredictable things:

FOR i%=1 TO 5
  FOR j%=1 TO 10
    PRINT i%;" * ";j%;" = ";i%*j%
  NEXT j%
NEXT i%

That sample program has one FOR-NEXT-loop in another and it calculates the product of the both counter variables creating some sort of multiplication table. Some rules and advice to keep in mind with FOR-NEXT-loops:

1. Always terminate an opened FOR with a corresponding NEXT. 2. Always terminate FOR-loops in the correct order. If you write FOR i%=... first and FOR j%=.. next, make sure to terminate the inner loop first. 3. You can count downwards with the word DOWNTO instead of TO. Try FOR i%=5 DOWNTO 1. 4. You can count in steps not equal 1 with the keyword STEP: FOR i%=1 TO 10 STEP 2 That will increment i% in steps of 2 until it reaches 10. 5. GFABASIC will check for correct loop termination while entering the code into the editor. 6. You can terminate the FOR-NEXT-loop with the EXIT IF statement.

That was easy. Now a very fundamental construct for flow control: test for certain conditions and the method for letting your program take an alternative code segment.

Conditions

A very fundamental idea in programming is to create and use conditionals. These will allow you to make decisions when certain conditions are met.

Try to imagine that you count a special variable and want to do something else when the value of your counter is 5:

FOR i%=1 to 10
  IF i%=5 THEN
    PRINT "i% is now 5"
  ELSE
    PRINT "i% is not 5"
  ENDIF
NEXT i%

Try to understand this example fully. It is so fundamental that you will never be able to write a real program if you don't understand how to formulate and use conditionals. This program loops 10 times and counts in the variable i%. For each iteration of the loop it checks if i% is 5 in the IF line. If that condition is true, i% is 5, then it executes the program branch until the ELSE and omits the following part. If the condition is not true, GFABASIC will only execute the part behind the ELSE. Make sure to terminate each IF conditional with an ENDIF or GFABASIC will get lost and produce an error message. The THEN behind the conditional is not needed but some other BASIC dialects will require it.

You may leave out the ELSE fork. GFABASIC will then do nothing if the condition is not true.

IF i%=5 THEN
  PRINT "i% is 5"
ENDIF
REM the following part is fully identical in function and behavior
IF i%=5
  PRINT "i% is 5"
ENDIF

The REM stands for remark and is a generic comment. Comment your programs and you will be able to understand it later. A ' might be used as well. Anything behind the REM will be ignored by GFABASIC.

You can combine expressions and conditions to check for multiple conditions in one go.

IF (i%=1) AND (j%=2)
  PRINT "i% is 1 and j% is 2"
ENDIF

This example would only do the PRINT statement if i% is 1 and j% is 2. This is simple boolean logic. The brackets are optional but sometimes you need them or GFABASIC will not evaluate an expression as intended. With the brackets you can control which condition has to be fulfilled first. The following statements are not identical:

IF ((i%=1) AND (j%=2)) OR (x%=1)
...
ENDIF

IF (i%=1) AND ((j%=2) OR (x%=1))
...
ENDIF

You see brackets are useful. Take care when developing your logic and try to formulate it with the least amount of conditionals possible. Ofcourse you can check if value are less or more then a certain amount. See the following table:

Condition
does what
i%<j%
will evaluate to TRUE if is i% is less than j%
i%<=5
will evaluate to TRUE if i% is 5 or less
i%=100
will evaluate to TRUE is i% is exactly 100
i%<>j%
the opposite of an equality test - evaluates to TRUE if i% is

not equal j%, meaning i% is different from j%

i%>50
will evaluate to TRUE if i% is larger than 50
a%>=50
will evaluate to TRUE if a% is 50 or larger

Ofcourse you do not need to check for single variables. You can evaluate full expressions like the following one:

IF x%+y%>18
...
ENDIF

Usage of brackets is again recommended:

IF (x%+y%)>18
...
ENDIF

You can combine conditionals with boolean expression as shown above. See this table for more information. Make sure to use brackets at the proper places or you code will go crazy:

Boolean

connector

does what
condition1 AND condition2
evaluates to true only if both conditions are fulfilled
condition1 OR condition2
gets true when one or both conditions are fulfilled
NOT condition
gets true if the opposite of the condition is true - mean NOT

i%<5 will get true when i% is 5 or greater

condition1 XOR condition2
evaluates to true when exactly one of the both conditions is

fulfilled

There are a few more conditionals but you create any condition and expression with these. Now that you have the knowledge about conditional expressions, it is time to introduce you to a few more loop statements.

Conditional and endless loops

Sometimes you don't know how far you need to count for a special operation. Or imagine a game. You don't want to let it run just for 10 frames but until the player sprite did collide or something like that. The first new loop will loop until a condition is fulfilled:

REPEAT
...
UNTIL <condition>

This is a so called REPEAT-UNTIL-loop. It loops at least once and checks for the condition after the loop contents have been executed by GFABASIC. Use it for things that need to be done at least once. You can emulate FOR-NEXT-loops with it if you want trickier counting:

i%=1
REPEAT
  PRINT "i%=";i%
  i%=i%+1
UNTIL i%>5

This example will emulate a plain FOR-NEXT-loop that counts i% from 1 to 5. In GFABASIC v3 and up you can also write the following which is the same as the REPEAT one above:

DO
...
LOOP UNTIL <condition>

Surely you can test the condition before entering a loop. This is useful if you want to loop only when a certain condition is already true:

WHILE <condition>
...
WEND

This is the so called WHILE-WEND loop. It checks the condition first and it will not execute the loop body if the condition is not fulfilled. Sometimes you want to loop endless. GFABASIC has a special loop construct for this purpose although you can create never ending loops easily with the types above if you use a condition that will never get true. The never ending loop is called DO-loop. The 3 loops in the example are all equal in functionality and will loop endless.

DO
  PRINT "endless"
LOOP
i%=0
REPEAT
  PRINT "endless"
UNTIL i%=1
i%=0
WHILE i%=0
  PRINT "endless"
WEND

At this point it is important that you know you can terminate at your GFABASIC program at any point and return to the editor. This is useful if your program gets stuck in an endless loop which was not intended. Press the keys ALTERNATE+CONTROL+SHIFT together and GFABASIC will ask you for a program stop. Sometimes you will want to terminate a running loop at another point than the official loop beginning or loop end. Use the EXIT IF statement in your loop for extra conditions. This will also terminate FOR-NEXT-loops if you wish to and it is the only way to terminate a DO-loop.

i%=1
DO
  PRINT "i%=";i%
  EXIT IF i%=5
  i%=i%+1
LOOP

Please note that the EXIT IF statement has no ENDIF or the like. It just terminates the loop and continues your program behind the loop end.

Progress Check

Now that you have learned the fundamentals of looping and conditions, check yourself with the progress check. I advise you not to continue with this tutorial until you fully understood the ideas, concepts and constructs of this chapter.

  1. Can you combine multiple conditions in one conditional statement? If yes, give an example: ...
  2. Write a loop that counts from 4 to 10: ....
  3. Implement this loop with all loop types mentioned in this chapter.
  4. Can you count in increments different then 1? How?
  5. Write a program snippet that will print "Hello Atari" on screen if the value of the variable i is less or equal 4.
  6. Which parts of the IF-THEN statement are optional?
  7. Write a program that will print a nicely formatted multiplication table on screen for all numbers from 1*1 to 10*10.
  8. Which statement will terminate any loop on condition? Do you need an ELSE part or terminate it with ENDIF?
  9. Explain the difference between OR and XOR.
 10. Explain the difference between REPEAT..UNTIL <condition> and DO..LOOP. Is there any?
 11. Give 2 methods how you can change the DO...LOOP into a terminating one like the REPEAT..UNTIL one.

back to GFA Tutorial