This is the only chapter that was written of an unfinished, unpublished book about the Action!
and Functions, collectively referred to as "routines", are the heart of the Action!
Language. (We will
cover functions in Chapter 7.) A procedure is a group of statements,
expressions, and/or commands that accomplish a certain task. See if you can
tell what the following simple procedure is intended to do:
FOR counter=1 TO 10
If you were
to type in the procedure, compile it and run it, this is what you would see on
Procedure "Count_ten" is designed to print the BYTE numbers 1 through 10 (with
a space between each number). That's all it does. Of course, most procedures
will be more useful and probably longer, but the preceding example gives you an
idea of how simple the procedure structure really is. The only requirements are
a name for the procedure and a RETURN at the end.
NOTE: Don't leave out the RETURN! Terrible things can
happen if you do, even if the program compiles without error. You will more
than likely have to turn your computer off and back on again to regain control,
thereby losing anything you may have had in the Editor. This by itself is
reason enough to save your program to disk or cassette before each compile or
procedure name can contain any alpha-numeric characters you wish, including the
underline, as long as it begins with a letter and isn't longer than 255
characters. The parentheses are also required, and later we will discuss
passing parameters within those parentheses.
even have a procedure to do nothing at all if you wished, and in fact this is
quite useful when you are writing a program that will contain a number of
procedures. For example, if you were writing a program with several procedures,
but you weren't ready to flesh them all out, you could still call them from
your program without getting a compiler error. Here's an example of a
procedure is simplicity itself. Just type in the procedure's name at the point
you wish it to be executed. This is almost exactly like calling a subroutine in
BASIC. To call our previous two examples, we would enter the following:
there is to it!
you know how to declare and call a procedure, you're ready to write your first
real Action! Program. You will find suggestions for changes after we finish, so
please type it in and save it to disk or cassette.
excellent way to learn any new language is to analyze a simple BASIC program
and then rewrite it in the new language. In order to make the translation, we
first need to study the program so that its structure will become more obvious.
This is a simple program, and even in BASIC the flow is easy to see. That will
make it much easier for us to make our translation.
Atari BASIC, is the program that we will be taking apart and putting back
together in Action!. It's called "The Great Butterfly Chase".
10 REM INITIALIZE
INITIAL POSITIONS OF HUMAN & BUTTERFLY
40 REM 10 TURNS EACH GAME
PLAYS=1 TO 10
60 REM DRAW THE "MAP"
ROW=1 TO 5
COL=1 TO 5
COL=BCOL AND ROW=BROW THEN PRINT "B";:GOTO 150: REM
COL=HCOL AND ROW=HROW THEN PRINT "H";:GOTO 150: REM
REM NOBODY THERE
180 REM HUMAN MOVEMENT LOOP
"Move number ";PLAYS
"Direction (NSEW)";:INPUT MOVE$
MOVE$="N" THEN HROW=HROW-1: REM MOVED NORTH (UP)
MOVE$="S" THEN HROW=HROW+1 : REM MOVED SOUTH (DOWN)
MOVE$="E" THEN HCOL=HCOL+1: REM MOVED EAST (RIGHT)
MOVE$="W" THEN HCOL=HCOL-1: REM MOVED WEST (LEFT)
245 REM CHECK FOR "OUT OF BOUNDS"
HCOL>5 THEN HCOL=5:GOTO 300
HCOL<1 THEN HCOL=1:GOTO 300
HROW>5 THEN HROW=5:GOTO 300
HROW<1 THEN HROW=1:GOTO 300
"You hit the wall!"
310 REM CHECK TO SEE IF HUMAN AND BUTTERFLY OCCUPY THE SAME
HCOL=BCOL AND HROW=BROW THEN GOTO 700
330 REM BUTTERFLY'S MOVE
340 REM THE BUTTERFLY IS "SMART"
350 REM AND WILL MOVE AWAY FROM YOU
360 REM BUT HE DOESN'T ALWAYS MAKE THE
370 REM PERFECT MOVE!
BCOL>HCOL AND BROW=HROW THEN BDIR=1
BCOL>HCOL AND BROW>HROW THEN BDIR=2
BCOL=HCOL AND BROW>HROW THEN BDIR=3
BCOL<HCOL AND BROW>HROW THEN BDIR=4
BCOL<HCOL AND BROW=HROW THEN BDIR=5
BCOL<HCOL AND BROW<HROW THEN BDIR=6
BCOL=HCOL AND BROW<HROW THEN BDIR=7
BCOL>HCOL AND BROW<HROW THEN BDIR=8
460 REM THROW IN SOME RANDOMNESS
CHANGE=0 THEN BDIR=BDIR+1
CHANGE=1 THEN BDIR=BDIR-1
BDIR=0 THEN BDIR=8
BDIR=9 THEN BDIR=1
610 REM MAKE SURE THE BUTTERFLY
620 REM IS NOT OUT OF BOUNDS
BCOL>5 THEN BCOL=5
BCOL<1 THEN BCOL=1
BROW>5 THEN BROW=5
BROW<1 THEN BROW=1
670 REM SEE IF THE BUTTERFLY GOT HIMSELF CAUGHT
BCOL=HCOL AND BROW=HROW THEN GOTO 700: REM OUT OF THE
"You got him!":GOTO 740: REM OUT OF THE LOOP
730 REM OPTION TO PLAY AGAIN
"Want another game (Y/N)?";:OPEN #1,4,0,"K:":GET #1,KEY
CHR$(KEY):IF CHR$(KEY)="Y" THEN CLOSE #1:RUN
the BASIC program section by section:
set up the initial conditions of the game, setting the human's column and row
to "1" and the butterfly's column and row to "3". "MOVE$" is also dimensioned
starts the 10-play loop.
draw the map, printing an "H" for the human, a "B" for the butterfly, and a "."
For an empty cell.
prints the play number
asks for player input.
210-240 calculate the human's new position, based on his input.
250-280 check to see if the human tried to pass through a wall and "bounces"
him back to his previous position if he did.
determines whether or not the human and butterfly are in the same place and
exits from the loop if they are.
380-450 determine the best possible move for the butterfly.
470-490 add the random factor for the butterfly's move.
500-510 correct the butterfly's move – there is no direction 0 or
directs the program to the proper line according to the direction in which the
butterfly will be moving.
530-600 calculate the butterfly's new position.
610-660 keep the butterfly from going out of bounds.
Line 680 is
a repeat of line 320.
moves us to the next play.
declares the butterfly safe.
730-750 offer another game.
You might want
to run this program in BASIC and then in Action! to see the improvement in speed of
the names of the procedures we will be using in our Action! translation:
Our first Action! program may look a little
cumbersome compared with the BASIC program. But you can learn a great deal by
modifying it later, after you learn some new tricks to make it more compact.
Right now we're going to do an almost direct translation, though. We'll start
with the procedure to draw the map:
;Procedure to draw a five by five grid in Graphics 0
;(lines 60-170 in the BASIC program)
row, col ;variables LOCAL to this procedure
row=1 TO 5 ;line 70
col=1 TO 5 ;line 80
") ;line 90
col=b_col AND row=b_row THEN ;line 100
col=h_col AND row=h_row THEN ;line 110
Print(".") ;line 140
OD ;line 150
PutE() ;line 160
section to allow the human's input and movement:
;Human movement section
;(lines 180-300 in the BASIC program)
BYTE move ;"move"
is LOCAL to this procedure
number ") ;line 190
Move=GetD(7) ;line 200
PrintF("%C",move) ;we want it printed as a Character
old_col=h_col ;save these variables in case
old_row=h_row ;the human goes out of bounds
move='N OR move='n THEN
h_row==-1 ;move him up (line 210)
move='S or move='s THEN
h_row==+1 ;move down (line 220)
move='E or move='e THEN
h_col==_1 ;move right (line 230)
h_col==-1 ;move left (line 240)
h_col=old_col ;out of bounds
The procedure to move the butterfly:
;Procedure to move butterfly
b_dir ;LOCAL to this procedure
b_col>h_col AND b_row=h_row THEN
b_dir=1 ;line 380
b_col>h_col AND b_row>h_row THEN
b_dir=2 ;line 390
b_col<h_col AND b_row>h_row THEN
b_dir=3 ;line 400
b_col<h_col AND b_row>h_row THEN
b_dir=4 ;line 410
b_col<h_col and b_row=h_row THEN
b_dir=5 ;line 420
b_col<h_col AND b_row<h_row THEN
b_dir=6 ;line 430
b_col=h_col AND b_row<h_row THEN
b_dir=7 ;line 440
b_dir=8 ;line 450
Change=Rand(10) ;line 470 – "Rand" is a library function
;to be discussed in a later chapter
b_dir==+1 ;line 480
b_dir==-1 ;line 490
b_dir=8 ;line 500
b_dir=1 ;line 510
b_col==+1 ;move it to the right (line 530)
b_col==+1 ;move it to the right
b_row==+1 ;and down (line 540)
b_row==+1 ;move it down (line 550)
b_col==-1 ;move it to the left
b_row==+1 ;and down (line 560)
b_col==-1 ;move it to the left (line 570)
b_col==-1 ;move it to the left
b_row==-1 ;and up (line 580)
b_row==-1 ;move up (line 590)
b_col==+1 ;move right
up (line 600)
b_col=old_col ;correction for out of bounds
b_row=old_row ;(lines 620-660)
We need a procedure to check the status of the human and
the butterfly to see if they are trying to occupy the same space at the same
;Procedure to see if the butterfly has been caught –
;serves the same function as lines 320 and 680 in BASIC
;No local variables
(h_row=b_row) AND (h_col=b_col) THEN ;lines 320 and 680
him!") ;line 700
Caught=1 ;the "flag" to indicate a catch
Now the procedure to offer another
;This procedure determines if the player wants to quit or play
;See lines 730-750 in BASIC
;No local variables
you want to play")
game (Y/N)?") ;line 740
Decide=GetD(7) ;line 740
PrintF("%C",decide) ;line 750
decide='Y or decide='y THEN
Decide=1 ;program will run again after the RETURN
decide=0 ;program will end after the RETURN
Procedure "Main" – the procedure that controls the whole program:
B_row=3 ;initial conditions (line 30)
FOR plays=1 to 10 ;(line 50)
Draw_Map() ;call Procedure "Draw_Map" (lines 60-170)
Move_Human() ;call Move_Human (lines 180=300)
Check_Stat() ;call Check_Stat (line 320)
caught=1 THEN ;"caught" is set by Procedure Check_Stat
EXIT ;get out of the loop
Move_Fly() ;call Move_Fly (lines 330-600)
Check_Stat() ;call Check_Stat (line 680)
PutE() ;print a line with carriage return
escaped!") ;line 720
More_Play() ;call More_Play (lines 730-750)
UNTIL decide=0 ;no more games
Let's take Procedure "Main" step by
There are two "DO" loops in this
procedure, one nested inside the other. We'll look at the nested loop first and
then we can work back to the original one.
Right after "FOR plays=1 TO 10" is
the nested loop. It tells the program to do the following:
1. Draw the map
2. Let the human make a move
3. Check to see if the human caught
the butterfly and EXIT if he did
4. Print a blank line
This loop will execute 10 times (10
plays) or until the butterfly is caught. The outer loop controls the inner loop
as well as a few other things:
sets up the initial conditions – positions of human and butterfly –
and initializes the variables "caught" and "decide" to 0.
tells you you lost if all 10 plays have passed without a "catch".
asks if you want another game.
does all this UNTIL you say "No" to another game.
We need to add one more section of
code and our program will be ready to compile and run. This section is called
simply "MODULE" and all it does is tell the compiler that we want to declare
some global variables.
;declaring global variables
h_col, h_row, b_col, b_row, old_col, old_row, plays, caught, decide
Go ahead and type this program in if
you haven't already done so. Make sure that MODULE is the first piece of code,
and Main the last. Otherwise the procedures can go in any order you like.*
After you have typed in the program in the Action! Editor
and saved it <CTRL-SHIFT-W>, use <CTRL-SHIFT-M> to go to the
Monitor, Compile the program, and Run it. If you have typed it in exactly as
you see it here, it will compile and run without errors. If you do get an
error, proofread your source carefully and make any necessary corrections, save
the revised program, and try it again.
There's your first Action! program. To test what you've
learned, try making the following changes:
the butterfly not to let himself get cornered.
the human to make moves diagonally
the starting positions random – include code to keep the human and
butterfly from starting out in the same place or too close (within 1 square).
This is not always the case. In more complex programs, where routines call
other routines, you will have to ensure that a procedure to be called precedes the calling procedure (or function).
We will cover this in detail in a later chapter.