ZX Spectrum Game Master
ZX Spectrum Game Master
ZX Spectrum Game Master
Game Master
ZX Spectrum
Game Master
PK McBride
Longman
ZX SPECTRUM is a Trade Mark of
SINCLAIR RESEARCH LIMITED.
Contents
Introduction 6
Action games 12
1 Movement 16
2 Targets & invaders 36
3 The Hall of Fame 48
4 Mazes 52
5 Special effects 62
Program listings 68
Adventure games 76
6 The spirit of adventure 76
7 BASIC logic 80
8 Planning the game 84
9 The key routines 98
10 Taking it further 106
Program listing 114
Interactive games 122
11 Game design 122
Longman Group Limited First published 1984 12 First moves 124
Longman House, Burnt Mill, Harlow, 13 Developing tactics 128
Essex CM20 2JE, England ISBN 14 Take it from here 132
and Associated Companies throughout the
world. Printed in UK by Parkway Illustrated Press, Program listing 136
Abingdon
© Longman Group Limited 1984 Appendices
Designed, illustrated and edited by A Essential BASIC 148
All rights reserved. No part of this Contract Books, London B Defining your own graphics 154
publication may be reproduced, stored in
a retrieval system or transmitted in any C Super screens 157
form or by any means, electronic, The programs listed in this book have been
mechanical, photocopying, recording or carefully tested, but the publishers cannot
otherwise, without the prior permission of be held responsible for problems that
the Copyright owner. might occur in running them.
I-VF"
6 7
Introduction Introduction
There are three aspects to any computer game: Presentation comes next, How will your
1 the idea game actually appear on the screen? What will
2 the way you present the game the player have to do to play the game? How
3 the techniques you use to make the game can you make it most interesting? Are you using
work. colour and sound to the best advantage? Can
the player see all the information he needs to be
The idea Of these three, this is the most able to play? Are you giving him too much
important. It doesn't matter how good your information and causing confusion?
technique is, or how beautifully designed your
screens are, if the idea is poor, then you still
have a poor game. On the other hand, poor
presentation can rum a good idea, and if your
technique isn't good enough, it won't work
anyway.
If you are stuck for an idea, look at the games Technique is, of course, essential. You have to
that people play - board games, pencil and know how to get the effects you want, or you are
paper games, plastic peg games, group activity stuck before you start, but that is where this
games. There's inspiration there. Some of these book, and others like it come in. You can always
games will translate directly onto a computer, read up on technique. Somebody, somewhere,
others might stimulate your imagination. can tell you what you need to know to make the
Play with your micro. Try out anything new game work. You will also find that there is
you come across, any new ideas, techniques or usually more than one way to get a particular
routines - and see if they lead to a game of some effect, and a bit of creative thought will go a
sort. long way.
8 9
Introduction Introduction
Adventure games
Computer games come in a bewildering variety The classic adventure games - developed on
of types, shapes and sizes. Some are true mainframe computers in the 60s and 70s - were
computer games - the sort that don't exist in any all text based. Games were often included in
other form - others are 'computerised games' - commercial software packages, just to show off
versions of existing board or paper games. how well the computers could handle words.
The book is divided into three sections - Cheap chips have brought to home computers
Action, Adventure, and Interaction. It is a the same kind of memory capacity that the old
convenient way to try to cover the techniques of mainframes had, and now adventure games
games-writing, but in practice many games have reached the home. Many of the newer
refuse to fit into nice neat categories. games include graphics, sometimes in the form
of illustrations, sometimes as action games
spliced into the main adventure. All adventure
games share a common theme - the player has
to find his way around some unknown land,
using his wits to solve the many problems he
Action games meets, trying to discover the hidden treasures.
These are the games played out on the screen -
the arcade games. They have come a long way
in a few short years, from the TV Tennis of the
early 70s through Space Invaders, Munchman,
Donkey Kong, Frogger to the latest 3-D effect Interactive games
Star Wars games. All action games are based
on speed of movement and of response, but All computer games are interactive one way or
speed is not the only thing. another, i.e. the computer responds to what you
The best games have do, and you must respond to the computer. All
excellent graphics and sound games must work this way. By 'interactive
effects, and it's here that games' I mean those where the computer acts
imagination comes into play, as a player, in much the same way as a human
would act. The machine has to
'think', to make decisions and to
work through a strategy. These
types of games require very
careful planning, and even the
simplest interactive game is far
from simple to write. This
section comes at the end of the
book for that reason!
10
Introduction
All action games depend upon speed of
response. The speed with which the player
responds to the computer, and the speed with
which the computer responds to the player.
This can create problems when you are
working in BASIC.
Don't be put off by this, You can achieve some
quite slick games in BASIC, as long as you keep
the routines simple. Also, BASIC does have one
enormous advantage over machine code. It is
fairly simple to handle, and not too hard to track
down your mistakes. Debugging machine code
is no fun at all!
12 13
Action games Action games
The game has three types of movement. The Shoot, steer and catch
attacking spaceships move steadily from left to
right, with their height controlled by the keys. If you are a keen games player, you will have
Bombs drop straight down, and the enemy noticed that there are really only a limited
spacecraft move from right to left, but their number of different action games around. These
height is adjusted by the computer to bring tend to fall into three types: those where the
them onto a collision course with the attacker. object is to shoot things; those where you are
Also in the game are three varieties of steering round some kind of maze or obstacle
collisions: ship to ship, bomb to building, and course; and those where you are trying to catch
laser beam to ship. things. The common factor in all of these games
is the movement of objects on the screen, and
the control of the action through the keyboard
Firefight (or joysticks.) This then is where we should
start.
This is essentially a game of movement. A fire
engine has to be steered around the screen,
rushing to put out fires. The fires spring up at
random places, and the more successful you are
in putting them out, the quicker new ones burst
into flame. This is not a game anyone can win.
The only question is, how long can you last?
The main points to note here are the ways in
which 4-directional movement is managed, and
how the computer keeps track of what's going
on. An array is used to record the positions of
the obstacle blocks and of the fires. This is not
strictly necessary, as the screen could be read
directly to see what was where. However, the
array is convenient, and there will be other
times when you will need to use one to store this
type of information.
14 15
Action games Action games
routine in your programs which lets each player
choose his own keys for controlling movement.
To do this you need to create a small array to
hold the player's choices, collect those choices,
and then compare A$ with the array. The 'D.I. Y.
Key Routine' does this.
This program will crash if you go off the
Movement screen. Simply re-RUN to begin again.
16 17
Action games Movement
Continuous movement Rewrite line 1020 in that last example to give
a bigger picture - 6 squares, rather than one.
The Key Moves program doesn't give you You will notice, when you run this, that the
continuous movement - it produces a movement has slowed down a little and has
continuous line instead. To give the become a bit jerky.
impression that an object is moving, the first
essential is that there should be only one 1020 PRINT AT 5,C;" ^_ "; AT
image on the screen at any time. To do this,
you must rub out the old image before the
new image is printed. The change of You must change line 1010 as well, to stop the
graphic running off the edge of the screen.
variables doesn't have to be through key
controls. A target, for instance, would
probably move smoothly across the screen.
Here's a target moving routine.
1000 REM TARGET
1010 FOR C=0 TO 31
1020 PRINT AT 5,C;"*" • »•
1030 PRINT AT 5,C;" "
1040 NEXT C
18
Action games 19
Movement
Things to try
20 21
Action games Movement
The program here is a development of the Key Once you have designed your title page, you
Moves program. It allows you to move the will need to save it on tape, so that you can add
cursor anywhere you like on the screen, and to it to your game later. Do this using the SAVE
print at that spot, either a block of colour or a 'name1 SCREENS command. Break into the
(coloured) capital letter. The colour in which program and key in SAVE, the name of the
blocks and letters are printed can be altered at screen, and SCREENS, Make sure your cassette
any time by pressing one of the number keys, If player is set up properly, then proceed as if you
you want to rub out something, then take the were saving a program,
cursor back over that spot. There are two ways to add the title page to
Two points to note in this program. your game.
1 Put the instruction: LOAD 'name' SCREENS
1 Look at the lines 120 and 130, They stop the as the first line of the game, and SAVE the game
cursor from moving off the screen. so that it runs itself. You do this with the
2 After something has been printed, the command
cursor is automatically bumped to the right. This SAVE "gamename" LINE 10
is to stop it overprinting your block or letter. (where 10 is the first line)
You may find it more convenient to bump it left
or down instead. Alter lines 140 and 150, and Then SAVE your fancy title page on the tape
replace the LET C=C+(C<31) statement directly after the program. When the program
with your own variable change. is LOADed back in, it will run itself, and LOAD
in the screen.
10 PAPER 7:INK 0 : CIS
2 Use a loader program. This is a very short
20 LET L=10 : LET C=15 (start position - start where YOU want)
30 LET I =0 (I is the colour of the INK) program, whose sole purpose is to LOAD in a
screen, and the game program - and maybe a
40 PRINT AT L,C; "*"
50 LET A$ = INKEYS: IFA$="" THEN GOTO 50
chunk of machine code if you are using any. It
should look something like this:
60 PRINT AT L,C;" "
70 IF A$>="0" AND A$<="7" THEN LET I = VAL A$ 10 LOAD "ORBIT" SCREENS
(converts the number key stroke into the value for the Ink variable) 20 LOAD "ORBIT"
80 IF A$ ="u" THEN LET L=L-1 SAVE this loader so that it runs itself, then SAVE
90 IF A$ ="d" THEN LET L=L+1 the screen immediately after it, and finally
(small letters for the movement controls) SAVE the game program - make that auto-run
100 IF A$="r" THEN LET C=C+1 as well.
110 IF A$="L" THEN LET C=C-1 If you are going to be using a machine code
120 LET L = L+(L<0) - (L>21) (adjusts L to keep it in range) routine, then include the CLEAR command in
130 LET C= C+(C<0)-(031) (adjust C) the loader. You could find it very irritating if you
140 IF A$= " " THEN PRINT AT L,C; PAPER I;" ": had just watched a fancy screen load in, only to
LET C=C+(C<31)
have it wiped away the instant the program
150 IF A$>="A" AND A$<="Z" THEN PRINT AT L,C;INK I;
started.
A$: LET C=C+(C<31)
5 CLEAR 56999 (or whatever numbers)
160 GOTO 40
22 23
Action games Movement
Despite its name, this is not a version of the wall 400 PRINT "YOU DROVE ";SC/10;"
game, but one where you have to steer a KM"/'BEFORE YOU CRASHED."
runaway car down a hill - and your brakes are 410 STOP
not working.
The car only moves from side to side
(controlled by keys | 5 | and | 8 |), The Graphics
downhill movement is created by making the
screen scroll upwards by continually printing 1000 FOR N=0 TO 5: READ G$
on the bottom line. 1010 FOR R=0 TO 7: READ B
Normally, if you try to print below line 21, you 1020 POKE USR G$ +R,B
will get the 'scroll?' message. In this program, 1030 NEXT R: NEXT N
the SCRLCT (Scroll Count) systems variable has 1040 DATA "A",0,1,6,12,9,25,16,49
been reset, so that it will print an additional 255 1050 DATA "B",0,255,0,192,224,224,
lines before the 'scroll?' appears (line 140). 192,255
You can improve the car design by changing 1060 DATA "C",0,128,96,48,16,24,
the data in the subroutine at 1000. The original 8,140
design is shown for your reference. 1070 DATA "D",63,127,119,119,127,
127,112,112
1080 DATA "£",255,255,129,255,129,
Main loop 255,0,0
1090 DATA "F",252,254,238,238,254,
100 GOSUB 1000 254,14,14
110 CLS : LET T=10 1100 RETURN
120 LET SC=0 : LET C =14
Lines 1040 to 1090 contain the DATA for each of
125 REM GRAPHICS IN 130
the graphics A, B, C, D, E and F.
130 PRINT AT 10,C;"ABC";AT
11,C;"DEF"
140 POKE 23692,255 Kerb printing
200 GOSUB 2000
210 LET A$=INKEY$ 2000 LET X=INT(RND * 3)-1
220 LET C1=C+(A$="8")-(A$="5") 2010 LET T1=T+X
230 IF ATTR (11,CD =0 OR ATTR 2020 IF T1>3 AND T1<19 THEN LET
(11,C1+2)=0 THEN GOTO 400 T=T1
240 LET C=C1 2030 PRINT AT 21,T;PAPER 0;"H";
245 REM GRAPHICS IN 250 AT 21,T+10;"«":PRINT
250 PRINT PAPER 8;AT 9,0-1; 2040 RETURN
" (5 spaces) "; AT 10,C-1;
" ABC ";AT 11,C;"DEF" Most of what's happening here should be fairly
260 FOR D=1 TO 25 : NEXT D obvious, but the following points are worth
270 LET SC=SC+1 looking at more closely.
280 GO TO 140
24 25
Action games Movement
Try this
The winding road
1 If you haven't already done so, now is the
The road edge must change gradually, no more time to design your own car for this game. It
than one column either way at a time - in other doesn't have to be a car. It could be a downhill
words, the T variable must be altered by -1,0 skier, a parachutist landing in a narrow ravine, a
or +1. Line 2000 produces a suitable random spaceship lowering down into the depths of a
number. INT(RND*3) gives 0,1 or 2. Take away forbidden planet, or anything else your
1 to drop it into range. imagination will stretch to.
2 Give the screen a different appearance,
Testing for crashes Instead of marking the edges of the road, you
could mark the road itself:
The kerbstones don't just look black, they are 2030 PRINT AT 21 ,T;
also printed on black PAPER. This means that PAPER 0; " (12 spaces) "
the colour ATTRIBUTES of the kerb squares are
quite different from the rest of the screen. The Now check it to see if the car has lost contact
ATTR(Lme, Column) function will tell you what with the road:
colours are used at any particular square on the IF ATTR(11,C1)<>0 OR
screen, using this code: ATTR number = INK ATTR(11,C1+2)00
code, plus 8 times the PAPER code, plus 64 if
the square is BRIGHT, and 128 if it is FLASHmg. Don't forget to draw the road at the start, and to
The normal state of the screen is white PAPER print the car directly onto it in a light colour.
and black INK, so the ATTRibutes of a square
would be 8*7+0=56. Where the PAPER is 3 Why have a road at all? Why not random
black, the ATTRibutes are 0*8+0=0. Line 230 obstacles coming up at the car/skier/boat/
tests the squares where the wheels would be spaceship? This is actually easier. All you need
printed on the next move, to see if either are is a routine to produce a random number
kerb squares. between 0 and 31, and to print something on the
chosen column,
You could even arrange it so that your score
Rub out depended upon how many of those obstacles/
objects you landed on.
There is no separate rub out line here. The car Play around with the scrolling screen idea
is printed (line 250) with extra spaces above and see what you can come up with.
and round the top line. These will rub out the
old image, even though the new image may not
be directly in line.
27
26 Movement
Action games
Key controls
You could have a different key for each
direction - the number keys 1 to 8 would seem
appropriate - but that is not terribly user
friendly. It would be simpler, from the player's
point of view, to have one key for a clockwise
turn, and one for an anticlockwise turn.
1000 IF A$="5" THEN LET D=D-1
1010 IF A$="8" THEN LET D=D+1
28 29
Action games Movement
A further line is needed to stop D wandering out 70 GOSUB (90 +10*D)
of range. This line allows for full travel either 80 LET L=L + (22 AND L<0)-
way round; you can go clockwise from 8 to 1, (22 AND L>21)
and anticlockwise from 1 to 8. 90 LET C =C +(32 AND C<0)-
(32 AND C>31)
LET D=D+(8 AND D<1)-(8 AND D>8)
95 GOTO 30
You can see the way this works from this 100 LET L=L-1 : R E T U R N
program. Type it in and try it. 110 LET L=L-1: LET C=C+1: RETURN
120 LET C=C+1 : RETURN
10 LET D=1
130 LET L=L+1: LET C =C+1 :
20 LET L=10: LET C=15
RETURN
30 PRINT AT L,C;CHR$(48+D)
140 LET L=L +1: RETURN
40 LET A$=INKEY$
150 LET L=L+1 : LET C=C-1:
50 LET D=D+(A$="8")-(A$="5")
RETURN
60 LET D=D+(8 AND D<1)-(8 AND
160 LET C=C-1 : RETURN
D>8)
170 LET L=L-1: LET C=C-1 :
70 GOTO 30 RETURN
The first two lines set up the variables to hold
the direction and position (which we will be Type it all in and watch what happens when you
changing shortly), and the character is press the control keys. If you would prefer a
displayed by line 30. 48+D will give a number tidier screen, then loop the program back to
line 25, and write in a line to clear the screen
between 1 and 8. before the new graphic is printed.
As it stands, this routine gives you continuous
movement. To make it one step at a time, then
Move it rewrite line 40:
If you look at the listing for FIREFIGHT you will 40 LET A$=INKEY$: IF A$ ="" THEN
find a couple of lines that convert the direction GOTO 40
value into movement, using logical operators
(lines 160 and 170). You can work out similar
lines for 8-directional movement, but the lines
are horribly complicated. It is much simpler to
set up a bank of subroutines to change the
position variables.
30 31
Action games Movement
When you have got only one object on the is, then the program goes off to move that
screen, it's simple enough to control its speed graphic. The sguare block has a time code of 2,
through a variable in a delay loop. so that it is moved every second time the
program goes round the loop. The angled block
10 LET WHEN = 50 starts with a time code of 10, so that it is only
• • • moved every 10 loops. You can reduce this time
code and speed up the graphic, by pressing
300 FOR D=1 TO WHEN : NEXT D | 8 |. | 5 | slows it down. The graphic can be
WHEN can then be increased or decreased moved up and down the screen by keys | 6 |
by a key control line. and| 7 |, and the object of the game is to match
With two or more objects moving on screen, the speeds and positions of the two graphics.
this method will not do. If you increase the delay Type the game in and get it working, then
to slow down one object, you slow down the design some graphics of your own to make this
whole program. The CATCH program given look like a spacecraft docking manoeuvre, (For
here shows one way to allow two objects to advice on using user-defined graphics, see
move at different, controlled, speeds. It works Appendix B.)
by using multiples of numbers, in the same way 10REM CATCH
that the Fizz-Buzz game is played in schools. 20DIM T ( 2 ) : DIM X ( 2 ) : DIM Y ( 2 ) :
DIM C ( 2 ) : DIM G ( 2 )
30 LET T ( 1 ) =2: LET Yd) =10:
Fizz buzz LET X ( 1 ) =0: LET C ( 1 ) =1:
LET G(1) =143
In Fizz-Buzz, pupils count round the class, one at 40 LET T ( 2 ) =10: LET Y ( 2 ) =20:
a time, but when the number is a multiple of 3, LET X ( 2 ) =0: LET C(2) =3:
the pupil says 'Fizz1, rather than '3', '6', '9', or LET G ( 2 ) =142
whatever. For multiples of 4, the pupils would 50 POKE 23672,0: POKE 23673,0:
say 'Buzz'. It's a fun way of learning tables. The LET CT=1: CLS
Fizz-Buzz numbers don't have to be 3 and 4. 60 FOR N=1 TO 2
Here's how it would sound when played with 70 IF CT/T(N)=INT ( C T / T ( N ) ) THEN
Fizz for 2, and Buzz for 5. GO SUB 200
80 NEXT N
1, Fizz, 3, Fizz, Buzz, Fizz, 7, Fizz, 9, Fizz-Buzz
90 IF ABS ( X ( 1 ) - X ( 2 ) ) <2 AND
The computer doesn't Fizz and Buzz. Instead, it Yd) =Y(2) AND Td) =T(2)
goes to a subroutine to move the graphic, when THEN GO TO 120
it meets the right multiple in a simple counting 100 LET A$=INKEY$: IF A$<>"" THEN
loop. The overall loop (CT - Check Time) GO SUB 300
increases by 1 each time round. (Line 110). 110 LET CT=CT+1: GO TO 60
Each graphic has its own time code held in the 120 PRINT "SUCCESS IN ";INT ((PEEK
T() array. Line 70 checks to see if the Check 23673*256+PEEK 23672)750); "
Time is a multiple of a graphic's time code. If it SECONDS." __ »
32 33
Action games Movement
130 STOP should be more than made up for by the
200 PRINT AT Y ( N ) , X ( N ) ; " " improved appearance.
210 LET X(N)=X(N)+1-(32 AND X(N)=31)
220 PRINT AT Y ( N ) , X ( N ) ; INK C(N); 5 Watch out when using lines like line 70. IF
CHR$ G(N)
A/B =INT(A/B). . does not always work as well
230 RETURN
as it should. Sometimes you will find that it
misses the odd multiple because of rounding
300 LET
T ( 2 ) = T ( 2 ) + (A$="5")-(A$="8"): errors. The computer works in binary numbers,
IF T ( 2 ) <1 THEN LET T ( 2 ) =1
and only converts these to decimal for your
310 LET YN=Y(2) + (A$="6")-(A$="7")
benefit. This rounding can occasionally lead to
320 PRINT AT Y ( 2 ) ,X(2); " "
numbers being out by a very tiny decimal
330 LET Y ( 2 ) =YN
fraction. 9 and 9.000000001 may be, in reality,
340 LET N=2: GO SUB 220
the same, but the computer will see them as two
different numbers. A better check line in this
350 RETURN
kind of situation should take this form:
IF ABS( A/B - INT(A/B))<.0001
Try this THEN
It now checks to see if they are 'equal enough',
1 Improve the appearance of the game by rather than exactly equal. You will see a similar
giving it a background. If you are creating check in line 90, where the question is, are the
graphics to make this a spacecraft docking two objects close enough?
program, then add a subroutine to turn the
screen black, and scatter stars at random over
it. A few of these will get wiped out by the
space station and satellite as they cross the
screen, but it should not be enough to worry
about.
2 The movement here is horizontal only. This
is to keep the program simple. Why not
combine this program with the routines for
multi-directional movement to make a more
challenging and interesting game?
3 The two objects do not have to start at any
given place or speed, The initial values for T( 1)
and Y(l) could easily be randomized so that the
game becomes a little different each time,
4 Single square graphics are rather small,
why not make them larger and more attractive?
There will be a slight loss of speed, but this
34 35
Action games Movement
120 LET RC=RC+J: IF RO28 THEN
GO TO 20
125 REM G R A P H I C S IN 130
130 PRINT AT RL,RC;" EF";AT
RL+1,RC; " GH": GO TO 50
140 LET T=INT (RND*500)
36 37
Action games Targets & invaders
How it works
The mam loop of this program runs from line 50
to line 130. This is the part that runs the rabbit
across the screen. GOSUB 200, in lines 70 and
100, sends the program to the key controls
subroutine. The size of the rabbit's jump is fixed
by line 60, and could be of 1 or 2 squares or
nothing. If 'nothing' then the hunter gets a
chance to move his gun before the program
goes back for the next jump,
Line 250 is the line that checks for hits. There
are two parts to this - is the trigger being
pressed, and is the gun on target? This gun
obviously fires buckshot, as that line accepts
close as being good enough to count. You could
convert the gun to a rifle by insisting on greater
accuracy.
Spot on
You want to make sure that the gunsight is
directly over the target area on the rabbit. This
is the line to do it:
IF GY=RL AND GX=RC+2 THEN
The line checks the coordinates of the rabbit
and the gun more closely than the original line
does.
38 39
Action games Targets & invaders
Projects
40 41
Action games Targets & invaders
GOSUB missile Projects
42 43
Action games Targets & invaders
How it works
1 The object of the game is to shoot the X's.
Fire your missile, by pressing T.
2 If you miss the string of invaders the
program will crash.
3 You have got all the time in the world. These
invaders do not descend.
4 The program doesn't check the condition of
the invading fleet to see if it's wiped out, so
break out of the program when you have shot
them all.
Strings
Here it is! A 15 line space invader program. It The key to the program is STRING SLICING -
may not look much, but it's very impressive the art of chopping strings up and sticking them
when you think how short it is. Type it in and run back together. You can cut individual
it to see what it does, and then we will look at characters out of string by telling the Spectrum
how it does it. the position of the character you want.
10 LET I$=" X X X X X " A$=raiVlAlDlE|R|S|
20 LET C=0: LET D=+1 A$(3)=|V]
30 CLS : PRINT AT 20,15; "\" To take a slice of several characters, give the
40 PRINT AT 4,C;I$ positions of the first and last ones that are
50 LET A$=INKEY$: IF A$<> "" wanted. ^_^^_T_,_^
THEN GO SUB 100 A$(3TO7) = |V|A|D|E|R|
60 LET C=C+D If the slice you want is on the left of the string,
70 IF 0=20 THEN LET D=-1 then you only need to give the position of the
80 IF C<=0 THEN LET D=+1 last character.
90 PAUSE 5: GO TO 40 A$(TO4) = I I I N I V I A I
100 IF A$<>"1" THEN RETURN Likewise, if you want a slice from the other end,
110 FOR L=20 TO 5 STEP -1: PRINT just give the first position
AT L 15' " " A$(5TO ) - I D I E I R I S I
120 PRINT AT L-1,15;"t": NEXT L Strings can be joined together by using the
130 LET P=16-C addition sign. This is known as STRING
140 LET !$=!$( TO P-1) + " " CONCATENATION,
+I$(P+1 TO ) A$ - "SPACE" + "INVADERS" gives A$ =
150 PRINT AT 20,15; "t": R E T U R N "SPACE INVADERS"
44 45
Action games Targets & invaders
The main part of the program (30 to 90) shuffles the program will crash. Prevent this by
the string of X's backwards and forwards across including a line to check that the value of P is
the screen. The D variable holds the direction within range.
of movement, and lines 70 and 80 turn it round at 6 Shrinking Strings. Calculate the limits for the
the limits of the movement. column position for printing, so that the string of
The subroutine from 100 first whizzes the invaders travels the full width of the screen,
missile up the screen, then finds the place in the As invaders get shot at the ends of the string,
string (P) where the missile struck. The next the length of the string could be reduced. If the
line slices off the part of the string to the left of P leftmost character is hit, then the string needs to
and the part to the right, and rejoins them with a be redefined to include only that section to its
space in between. If there was an invader right:
there, then there isn't now.
IF P=2 THEN LET I$=I$(3 T O ) :
LET L=L-E
Improvements Turn this on its head to handle the other side.
1 Check for Hits. Did you get one? The way to IF P=L-1 THEN LET !$=!$( TO L-2):
answer that question is to find what was at place LET L=L-2
P in the string: The direction changing routine will need
IF I$(P)="X" THEN LET HIT=HIT+1 adjustment as well, now. The left limit for the
print column (C) will always remain at 0, but the
2 Add a Score. If you have a HIT counter, then right limit will increase as the length of the
this can be used as a basis for scoring. Write a string is reduced. You could get the computer
PRINT "SCORE =";HITS*20 line into the end of to calculate this from the L variable, but the
that subroutine. simplest method is to store the right limit in
3 Make them invade. Move the invaders another variable, and alter that as the string is
steadily down the screen, dropping a line after reduced.
every three or four passes. Keep a count of the
number of times they have crossed, and hold
their line position in a variable which is nudged
on when COUNT = 4.
You can check to see if they have landed by
looking at the line variable.
IF IL=20 THEN (end)
4 Add some nice graphics - if you haven't
already done so.
5 Crashproof it. If you try to look at, or slice off,
parts of the string which aren't there - that is, if
the missile flies past the end of the string - then
46 47
Action games Targets & invaders
The routine
It would be possible to write a routine that
compared the latest score with the recorded
scores and then shuffled the lower scores down
(and out) to make room for it. Possible, but not
48 49
Action games The Hall of Fame
9000 LET N$(6)=P$:LET S(6)=SC
How it works 9010 FOR P=1 TO 5
9020 LET H=-1
Look first at the set of lines from 60 to 100. H will 9030 FOR T=P TO 6
store the highest number, but must be set to -1 9040 IF S(T)>H THEN LET H=S(T):
before use. The T loop looks at each number in LET Z=T
the array to see if this is higher than the highest 9050 NEXT T
number it knows. If it is, then the H variable is 9060 LET X=S(P): LET S(P)=S(Z):
reset to a new high, and the reference number LET S(Z)=X
of the store is entered into Z. At the end of the 9070 LET X$=N$(P):LET N$(P)=N$(Z)
loop it swaps the highest number (the one from LET N$(Z)=X$
N(Z)) with the one at the top of its list. The P loop 9080 NEXT P
moves the starting place for the T loop steadily 9090 routine to print out
downwards. H a l l of Fame
The print-out subroutine should show you
what is happening, stage by stage.
Linking in
With a few minor adjustments, this sorting
routine can look after your Hall of Fame. The
main change is to include the names in the
swapping process. It's no good reordering the
scores, and leaving the names the same way
round. The arrays should be dimensioned to be
one more than the number you intend to display
- so that the latest score can be included. I have
written it as a subroutine starting at 9000, and
assumed a display of five names.
DIM N$(6,10):DIM S(6)
(include in initialization routine)
IF S(5)=0 THEN GOSUB 9000
(an empty place in the Hall)
IF SOS(5) THEN GOSUB 9000
(better than lowest score)
50 51
Action games The Hall of Fame
However, should you want a maze where the
computer creates paths, then you would need to
record it in an array. This will scatter 20 blocks
on a 20x20 screen.
1000 FOR N=1 TO 20
1010 LET R=INT(RND*20)+1
Mazes 1020
1030
1040
LET C=INT(RND*20)+1
PRINT AT R,C;"H"
NEXT N
You could use a similar system for scattering
There are .-basically two different types of mines, or other traps. For this, put a character
mazes, for two different types of games. The first on the screen, to mark its position, but colour it
type is a complex obstacle course, and is used the same as the screen. You can check for it
in dodging, snooting and chasing games. The with a line like this: (you have used M for mine.)
second type has confusing paths, and is used in
exploring and adventure games. With either IF SCREEN$(R,C)="M" THEN
type of game, you have two alternative ways of
creating the maze - either design it yourself, or
get the computer to design it for you. Normally, Walls
the ones you design will look better, and can be
more complicated than those produced by the These can be built at random, using a
machine, but your players will soon learn their development of the block-scatter method. The
way around them. Computer-generated mazes walls need length, as well as a starting place,
may not be as fine and fancy, but at least they and some walls will go across the screen, others
will be random. up and down. This produces random walls
across the screen.
1000 FOR N=1 TO 10
Obstacle courses 1010 LET X=INT(RND*16)+1
1020 LET Y=INT(RND*20)+1
The simplest way to set up an obstacle course is 1030 LET Z=INT(RND*3)+2
to scatter blocks around the playing area. 1040 FOR Q=1 TO Z
The position of the blocks is shown on the 1050 IF X+Q>20 THEN LET Q=Z:
screen, but is also recorded on a two- GOTO 1070
dimensional array. When the player tries to 1060 PRINT AT Y,X+Q;"H"
make a move, the coordinates of his intended 1070 NEXT Q:NEXT N
position are checked against the array to see if
the move is permissible. This is not actually These walls can be anything between 2 and 4
necessary, as you could colour the blocks blocks long, (the Z variable). Notice the
distinctively and check the ATTRibutes of the adjustments that have been made to ensure that
new position. the walls do not overrun the edge.
52 53
Action games Mazes
Projects chance, and doesn't make the game sufficiently
challenging, then add more monsters, all
1 Try and write a tank game for two players. starting from different parts of the maze. The
Get the computer to create the battlefield out of routine is exactly the same for ten monsters as
random horizontal and vertical walls. The for one, except that you no longer use simple
routines needed for controlling two tanks are variables. Hold the X and Y coordinates in an
the same as for one, except that you will need to array, and run the monster-move routine
give each player his own set of key controls. through a loop.
Think the game through carefully before you FOR Q=1 TO 10
start, and decide just how it is to be played. Will IF MX(Q)>PX THEN LET
you allow the tanks to shoot their way through MX(Q)=MX(Q)-1
walls? What range will the tanks have? What is • • • •
54 55
Action games Mazes
Here's a way to get the computer to generate a
maze of confused and confusing paths. It works
by laying a trail in stages, each of up to four
steps. The steps cover two squares at a time so
that it is spread out. At the end of a stage, it goes
back to the point where it started that part of the
path, and lays another path in a different
direction. The program then looks at the two
ends and sees which is in the most open
position. That end becomes the start of the next
stage - of the next pair of paths.
When the computer is taking a step, it picks a
direction at random, and then checks that it
hasn't tried to go that way already. It next
checks to see if the step would take it onto an
existing path, and rejects the move if it does. If
no move is possible, then the program goes
back to find a new place to start. Most of the
time, this new place will be where the last path
started, but sometimes it will reach dead ends
along both of the current paths. When this
happens, it scans the array, working from the
'bottom right' and picks up the path at the first
place it finds. This tends to make the overall
trail go from top left to bottom right, which is
what was intended. Two examples of the kinds
of pathways produced by this routine are
shown. Look at them closely and you will see
that although the paths wind backwards and
forwards, they do not actually cross, This is
important if you want to make sure that there is
no way out of a dead end, except the way that
you came.
56 57
Action games Mazes
Type the listing in carefully - there are a lot of 1050 NEXT N: IF F=1 THEN GO TO
variables floating round in there, and it only 1020
takes one mistype to create havoc. When the 1060 LET T(TC)=D: LET TC=TC+1
program runs, you will see the pathways drawn 1070 LET XD=(D=1) - (D=3)
on the screen as they develop. 1080 LET YD=(D=2) - (D=4)
1090 IF X+XD*2<1 OR X+XD*2>30
10 DIM M(20,30): DIM T(4): THEN GO TO 1020
DIM E(2,2): DIM B(2) 1100 IF Y+YD*2<1 OR Y+YD*2>20
20 LET END=0: LET X=1: LET Y=1 THEN GO TO 1020
30 GO SUB 1000 1110 IF M(Y+YD*2,X+XD*2) =1 THEN
40 LET SX=X: LET SY=Y GO TO 1020
50 FOR Q=1 TO 2: LET X=SX: 1120 PRINT AT Y+YD,X+XD;'W: LET
LET Y=SY: GO SUB 1000 M(Y+YD,X+XD) =1
60 IF END=1 THEN GO TO 200 1130 PRINT AT Y+YD*2,X+XD*2;"B":
70 IF X=SX AND Y=SY THEN LET M(Y+YD*2,X+XD*2) =1
GO SUB 2000 1140 LET X=X+XD*2: LET Y=Y+YD*2
80 LET E(Q,1)=X: LET E(Q,2)=Y 1150 IF X>26 AND Y>16 AND (X=29
90 NEXT Q OR Y=19) THEN LET END=1:
100 LET Q=1: LET B(1)=0: RETURN
LET B(2) =0 1160 LET Z=Z+1: IF Z=4 THEN
110 FOR 6=1 TO 2: FOR I=-2 TO +2: RETURN
FOR J=-2 TO 2 1170 GO TO 1010
120 LET X=E(G,1): LET Y=E(G,2) 2000 FOR 1=30 TO 1 STEP -1: FOR
130 IF Y+K1 OR Y+I>20 OR X+J<1 J=20 TO 1 STEP -1
OR X+J>30 THEN LET B(G) = 2010 IF M(J,I) =1 THEN LET SY=J:
B(G) + 1:GO TO 150 LET SX=I: LET 1=1: LET J=1
140 IF M(Y+I,X+J)=1 THEN LET 2020 NEXT J: NEXT I
B(G) =B(G) +1 2030 RETURN
150 NEXT J: NEXT I: NEXT G
160 IF B(2)<B(1) THEN LET Q=2
170 LET SX=E(Q,1):LET SY=E(Q,2):
GO TO 50
How it works
200 STOP 1 Arrays and variables.
1000 LET Z=0 M() stores the maze, T() is the temporary store
1010 LET TC=1: FOR N=1 TO 4: LET to keep track of the directions tried by the
T(N) =0: NEXT N computer, E() holds the coordinates of the ends
1020 IF TC=5 THEN RETURN of the two paths created at each stage, and B()
1030 LET D=INT (RND*4) +1 counts blocked routes.
1040 LET F=0: FOR N=1 TO 4: IF D SX and SY are the coordinates of the start of
=T(N) THEN LET F=1: LET N=4 the path, X and Y are the running coordinates.
In the step-taking subroutine (1000-1170), TC is
58 59
Action games Mazes
the try counter, Z counts the steps, and XD and
YD are the change of position variables. (One of Project
these will be 0, the other will be -1 or + 1.)
Use a maze-making routine to create an
2 The subroutine at 1000. The computer exploration game. The basic flowchart for such
picks a direction (1030), checks that it hasn't a game is given here. First get the computer to
tried to go this way before (1040) and, all being generate your maze, but do not display it. Next
well, stores the direction for future reference scatter a variety of happenings about the
(1060). The direction is then converted into a pathways. Some of these should be good things
form suitable for coordinate work (1070-1080). It to find, like bags of gold or princesses in need
then checks that the move will remain in the of rescue (they should be worth lots of points!);
maze area, and that it will not join up with an other things will be not so good - evil goblins,
existing path (1090-1110), and then takes the fire-breathing dragons or whatever. Make sure
step - or rather, two steps - in the same that these are placed on the paths by checking
direction. Finally it updates the X and Y values their coordinates against the maze array and
and checks to see whether it has reached a rejecting any not on paths. Enter them into the
suitable place on the edge, and whether it array in code. 1 indicates path, so 2 could show
should take another step at that stage. the presence of gold, 3 dragons, etc.
You will then need to add a routine to allow
3 The main routine. The first steps taken by the player to move about the maze. You might
the program are unusual in that the subroutine is like to display his movements, or, if you want to
only visited once at this point. This ensures that give your players a real challenge, you could
the path gets into the maze before it starts to continue to leave the screen blank. As he tries
divide. Lines 50 to 90 then take it through the to make a move, check that there is a path
subroutine twice, starting from the same place there, and look to see if he is about to meet
each time, and storing each endpoint. If no something interesting. All of the meetings will
steps were taken by the subroutine (line 70), be dealt with by separate subroutines. Quite
then the program goes to 2000 to find another how you deal with a fire-breathing dragon in a
place to start the path, maze is a problem for you to solve! The last
The lines from 100 to 150 assess mobility. How check is to see whether or not he has reached
many of the possible steps around the end of the end. When he does, you can give a final
each path are blocked by the edges of the score based on the quantity of treasure, and the
maze, or by existing paths9 The end which has number of wounds he has acquired in his
most openings becomes the start of the next travels.
stage, If you wish to speed up this program, Exploration games of this type are sometimes
then this whole routine can be replaced by a referred to as graphic adventures, and they
simple random switch. have much in common with adventure games, of
LET Q= 1: IF RND > .5 THEN LET Q=2 which more in the next section.
The program will lose a little finesse, but the
end result will not be too different!
60 61
Action games Mazes
Space sounds
The range of sound effects you can get from the
Spectrum can be greatly increased by the use
of a simple machine code routine. The one
given here will produce a weird and wonderful
62 63
Action games Special effects
Lasers Spinning saucers
If you want laser sounds, then you will be It is a well-known fact that all flying saucers
needing laser graphics as well. Here are a have flashing navigation lights. Have yours got
couple of ideas to try. Both use high-resolution them? You can make the whole saucer flash by
graphics, though in different ways. using the FLASH control, but you may want a
1000 OVER 1: FOR N=1 TO 2
more subtle effect than this. Here's one way to
1010 PLOT X,Y: DRAW X1, Y1 do it. It uses two separate images of the saucer,
1020 NEXT N:RETURN one with lights on, and the other with them off.
Two images are held in an array, and printed
This is really too fast to be of much use as it alternately.
stands, but by adding a command to call up
your machine-code sound effect, you will slow it 1000 FOR N=1 TO 12: READ G$
1010 FOR R=0 TO 7: READ B
to a more reasonable speed.
A series of plo'ts takes longer to appear. 1020 POKE USR G$+R,B
1030 NEXT R: NEXT N
1000 OVER 1: FOR N=1 TO 2 1040 DATA "A",1,3,0,0,3,6,12,63
1010 FOR P=X TO X1 1050 DATA "B",255,24,60,255,255,60,
1020 PLOT P,Y: RANDOMIZE USR M ABC and DEF are the 126,255
(sound effect) user-defined graphics (UDG) 1060 DATA "C",128,192,0,0,192,96,
1030 NEXT P ir the first flying saucer 48,252
1040 NEXT N id GHI and JKL are those for 1070 DATA "D",15,31,57,115,255,12,
In both of these routines, X, Y is the position of le second. 24,124
the gun and XI, Yl is the target. As both of these 1080 DATA "£",255,255,153,153,255,
will probably be printed on screen, using line 126,24,60
1090 DATA "F",240,248,156,206,255,
and column coordinates, you will need to
convert the print coordinates to high-res, 48,24,62
coordinates. Use these formulae: 1100 DATA "G",1,3,0,0,3,7,15,63
1 1 1 0 DATA "H",255,24,60,255,255,
X= C*8 + 4 255,255,255
Y= (21 - L)*8 + 4 1120 DATA 'T',128,192,0,0,192,224,
If you need to convert back to print 240,252
coordinates, then use these: 1130 DATA "J",15,31,63,127,255,12,
24,124
C= INT ( X / 8 ) 1140 DATA "K",255,255,255,255,255,
L= 21 - INTCY/8) 126,24,60
1150 DATA "L",240,248,252,254,255,
48,24,62
1160 DIM A$(2,2,3)
1170 FOR T=1 TO 2: FOR N=1 TO 2
1180 READ A$(T,N): NEXT N: NEXT T
*A
64 65
Action games Special effects
1190 DATA "ABC",DEF","GHI"/'JKL" through the program every time it meets a
1200 PRINT AT 10,10;A$(1,1); AT GOTO or GOSUB instruction, and count its way
11,10;A$(1,2) down to the appropriate line, It all takes time.
1210 PAUSE 10 A COMPILER PROGRAM will take your BASIC
1220 PRINT AT 10,10;A$(2,1); AT program and turn it into machine code,
11,10;A$(2,2) eliminating all of this interpretation and line
1230 PAUSE 10: GOTO 1200 finding. The result is a much faster program.
There are catches though. Compilers won't
This gives a steady flash. To turn this into a handle any string arrays, some won't handle any
spinning effect, you need to make a few arrays at all, or any strings, and most are
adjustments. Instead of two images, you will protected by copyright, If you wrote a game
need a set, with different lights on in each which you hoped to sell, you could not use
image, They can then be printed one after the someone else's compiler to give you the speed
other, so that it looks as if there is a single light you needed.
on a rotating saucer.
Special languages
Speed up the action
There are several versions of FORTH on the
There will probably come a time when you feel market at the moment. This language is far more
that you simply cannot get the speed you want structured than BASIC, and runs much guicker.
by writing in BASIC, and you will start to look It would be ideal for games writing, except that
round for alternatives. Machine coding is an again, it is protected by copyright, and to run a
obvious route to take, but not an easy one, Even FORTH program, you need to have the
experienced machine code programmers find language in the micro already. It's suitable for
that it takes days or weeks to produce routines enthusiasts who will simply swap games around
that do the same as BASIC routines that were between themselves, but of little value if you are
written in a few hours. There are less taxing hoping to sell your game on the open market.
alternatives that give results that are almost as SCOPE (from ISP Marketing) offers a better
good. solution. SCOPE routines are not unlike BASIC
to write, and the complete routine can be
compiled into a block of independent machine
Compiler programs code which will work without the SCOPE
language being present. This can be a
BASIC is slow because the computer has to complete program, or a set of routines to call up
interpret every command as it goes through the from a BASIC program. The SCOPE code can
program. When it meets an instruction, it has to be saved in the same way that any machine
work out what it means, call up the appropriate code can be, and there is no copyright problem
routine from ROM, look up any variables or about using SCOPE in games that you hope to
coordinates that are being used and then sell.
implement it. The computer also has to sort
67
66
Action games Special effects
199 REM
200 REM STARTING VARIABLES
210 LET L=6: REM SHIP LINE
220 LET C=0: REM SHIP COLUMN
240 LET E=0: REM NO ENEMY
FIGHTERS - YET
250 LET B=0: REM NOT DROPPING
Program listings 260
BOMBS
LET F=0: REM LASERS NOT
FIRING
270 LET SN=5: REM NUMBER OF
SPACESHIPS
290 REM
300 REM MAIN LOOP
305 REM GRAPHICS IN 310 AND 320
310 FOR N=1 TO SN: PRINT AT
10 REM "ORBIT" 20,N*2; INK 0;"A": NEXT N
15 REM 320 INK 0: PRINT AT L,C;"A"
20 REM SHOOTING AND BOMBING 340 LET A$=INKEY$
25 REM 345 REM
30 LET G=0: LET H=0: RESTORE 6000: 346 REM DROP BOMBS
GO SUB 6000 347 REM
40 PRINT AT 21,0;" *** READY - 350 IF B=0 AND A$="0" THEN LET
PRESS ANY KEY ***": PAUSE 0 BL=L: LET BC=C: LET B=1
100 BORDER 4: PAPER 6: INK 0: CLS 355 REM
110 INK 1: PRINT AT 14,14;"B"; 356 REM FIRE LASERS
AT 15,6;"B";AT 15,13;"BBB"; 357 REM
AT 16,6;"B«";AT 16,12; 360 IF A$="1" THEN GO SUB 3000
"BBBBB";AT 16,26;"BBB" 370 PRINT AT L,C;" "
120 PRINT AT 17,2;"BB";AT 17,6; 380 LET L=L+(A$="6")*(L<18)-
"••"; (A$="7")*(L>0)
AT 17,11;"BBBBBBB"; 390 LET C=C+1-(32 AND C>30)
AT 17,26;"BBBBB" 410 IF F=0 AND RND>.9 THEN LET
130 PRINT AT 18,2;"BB";AT 18,6; F=1: LET G=INT (RND*10):
"BB";AT 18,10;"BBBBBBBBB"; LET H=31
AT 18,26;"BBBBB" 415 REM
140 FOR L=10 TO 18: PRINT AT L,21;"BBB": NEXT L 416 REM CRASH INTO BUILDING?
150 FOR L=19 TO 21: PRINT INK 3; 417 REM
AT L,0;"BBBBBBBBBBBBBB 420 IF ATTR (L,O=49 THEN
••••••••••••••••••"- GO TO 600
NEXT L
68 69
Action games Program listings
430 OVER 0: INK 0: PRINT AT 1027 REM
L C" "A" 1028 REM CRASH INTO SHIP?
440 IF B THEN GO SUB 2000 1029 REM
450 IF F THEN GO SUB 1000: REM 1030 IF G=L AND H-C<=1 THEN LET
FIGHTER? F=-1
460 IF F=-1 THEN GO TO 600 1070 RETURN
470 GO TO 340 2000 REM
600 FOR N=1 TO 6: PRINT AT L,C; 2001 REM BOMB ROUTINE
INK N;"A": BEEP .01,N*4: 2002 REM
NEXT N 2005 PRINT AT BL,BC;" ": LET
610 PRINT AT L,C;" " Graphics occur in the BL=BL+1
620 PRINT AT 20,0; INK 3; following lines: 2010 IF ATTR (BL,BC)>48 THEN GO
'''••••••••••••"
430, 600, 660 TO 2100
630 LET SN=SN-1: IF SN=0 THEN 1020, 2030, 3100 2030 PRINT AT BL,BC;"B"
GO TO 700 2040 RETURN
640 IF F=0 THEN GO TO 670 2100 IF BL=19 THEN GO TO 2200
650 FOR N=H TO 0 STEP -1: IF 2110 FOR T=1 TO 3: PRINT AT
ATTR (G,N)=49 THEN GO SUB BL,BC;"*": BEEP .01,10: PRINT
3100: GO TO 670 AT BL,BC;" ": NEXT T
655 REM 2200 LET B=0: RETURN
656 REM G,H ARE LINE & COLUMN 3000 REM
VARIABLES OF ALIENS 3001 REM LASERS
657 REM 3002 REM
660 PRINT AT G,N;"C": BEEP 3005 IF C>24 THEN RETURN
.02,25: PRINT AT G,N;" ": 3010 INK 3: OVER 1
NEXT N 3020 PLOT FN C(),FN L( ) : DRAW
670 LET F=0: LET L=6: LET C=0: 48,0
GO TO 300 3040 OVER 1: PLOT FN C(),FN L():
700 STOP DRAW 48,0
1000 REM 3050 OVER 0: IF ATTR (G,H)<>51
1001 REM MOVE ALIENS THEN RETURN
1002 REM 3100 LET F=0: FOR N=3 TO 6:
1005 PRINT AT G,H;" ": LET PRINT AT G,H; INK N;"C":
H=H-1 + (32 AND H<1): LET BEEP .02,N*5: NEXT N
G=G+(L>G)-(L<G) 3110 PRINT AT G,H;" ": RETURN
1007 REM 4999 STOP
1008 REM CRASH INTO BUILDING? 6000 PAPER 7: INK 0: CLS
1009 REM 6010 PRINT AT 2,13;"ORBIT"
1010 IF ATTR (G,H)=49 THEN GO TO
3100
1020 PRINT AT G,H; INK 2;"C"
70 71
Action games Program listings
6020 PRINT AT 5,2;"YOU ARE IN
ORBIT AROUND THE ";AT 7,2;
"PLANET XERON. YOUR TASK IS
TO"
6030 PRINT AT 9,2;"FLATTEN THE
BUILDINGS, AND TO";AT 11,2;
"BEAT OFF ENEMY FIGHTERS."
6040 PRINT AT 14,2;"CONTROLS:";AT 10 REM "FIREFIGHT1"
16,3;"6 UP 7 DOWN";AT 18,3; 20 GO SUB 5000: REM front page
"1 FIRE LASERS 0 DROP BOMBS" and graphics
6100 REM GRAPHICS 30 GO SUB 6000: REM screen
6110 FOR N=1 TO 3: READ G$: REM display and variables
WHICH GRAPHIC LETTER 36 REM main loop starts here
6120 FOR R=0 TO 7: READ B: REM 40 IF INKEYSo"" THEN GO TO 40
NUMBER FOR DEFINING EACH ROW 50 PRINT AT l,c;e$(d)
6130 POKE USR G$+R,B: NEXT R: 60 IF PEEK 23672>tl THEN GO SUB
NEXT N 1000
6140 REM SPACESHIP 68 REM fires out of control
6150 DATA "A",0,224,124,50,255, 70 IF f>25 THEN GO TO 500
124,0,0
80 LET a$=INKEY$
6160 REM BOMB
88 REM quit
6170 DATA "B",48,48,208,252,30,
90 IF a$="Q" THEN GO TO 600
30,14,0
98 REM squirt
6180 REM ALIEN FIGHTER
6190 DATA "C",0,60,118,173,247, 100 IF a$="1" THEN GO SUB 1100:
GO TO 40
126,36,66
120 IF a$<"5" OR a$>"8" THEN
6200 REM FUNCTION DEFINITION
GO TO 50
6230 DEF FN L()=171-L*8 128 REM direction change
6240 DEF FN C()=C*8+8 130 LET d=d+(a$="8")-(a$="5"):
6250 RETURN LET d=d+(4 AND d<1)-(4 AND
d>4)
140 PRINT AT l,c;"
148 REM movement
150 IF a$<>"7" THEN GO TO 40
160 LET I1 = l-(d=4)*(l>1) +
(d=2)*(l<20)
170 LET c1 = c-(d=3)*(c>1) +
(d=1)*(c<29)
180 IF s$(U,c1 TO c1+1)<>"
THEN GO TO 50
190 LET 1=11: LET c=c1
72 73
Action games Program listings
200 GO TO 50 YOUR POLE FOR A MINUTE"
500 BEEP 2,10: PRINT AT 0,5; 5100 RESTORE 5100
"ENOUGH!!!": STOP 5110 FOR n=1 TO 9: READ g$
600 STOP 5120 FOR r=0 TO 7: READ b: POKE
998 REM put arsonist to work USR g$+r,b
1000 LET f1=1NT (RND*20)+1: LET 5130 NEXT r: NEXT n
fc=INT (RND*29)+1: IF ABS 5140 DATA "a",0,7,125,255,255,255,
(fl-l><5 AND ABS (fc-c)<5 60,24,"b",127,220,242,241,
THEN GO TO 1000 255,255,60,24: REM right
1010 LET s$(fL,fc)="f": PRINT AT 5150 DATA "c",3,7,9,9,15,12,31,4,
fl,fc; PAPER 6; INK 2; FLASH "d",128,192,32,32,224,96,
1;"I": LET f=f+1: REM GRAPHICS 240,64
1020 POKE 23672,0: RETURN 5160 DATA "e",254,59,79,143,255,
1098 REM find position and 255,60,24,"f",0,224,190,255,
direction of hose 255,255,60,24
1100 LET f L=L-(d=4)*(L>1) + 5170 DATA "g",3,4,15,12,15,15,31,4,
(d=2)*(L<20) "h",128,64,224,96,224,224,240,64
1110 LET fc=c-(d=3)*(c>1) + 5180 DATA "i",16,16,16,25,187,191,126,60
(2 AND d=1)*(c<29) 5200 DIM E$(4,2): FOR N=1 TO 4:
1118 REM check for fire READ E$(N): NEXT N
1120 IF s$(f l,fc)o"f" AND 5210 DATA "AB","CD","EF","GH": REM GRAPHICS
S$(f L,fc+1)<>"f" THEN RETURN 5220 LET TL=200: REM TIME LIMIT
1130 LET s$(fl,fc TO fc+1)=" ": 5380 PRINT AT 21,0; "PROGRAM
PRINT AT fL,fc;" ": REM TWO SPACES READY - ANY KEY TO START"
1140 LET tl=tl-5: REM reduce time 5390 BEEP 1,0: PAUSE 0
Limi t 5400 RETURN
1150 LET f=f-1: REM 1 Less fire 6000 DIM s$(20,30): BORDER 4:
1160 RETURN PAPER 7: INK 0: CLS
5000 PRINT AT 1,10; PAPER 6; INK 6010 PRINT PAPER 2;" (32 spaces) "
2; FLASH 1; " FIREFIGHT " 6020 FOR n=1 TO 20: PRINT AT
5010 PRINT AT 3,2;"Steer the fire n,0; PAPER 2;" ";AT n,31;" ":
engine around";AT 5,2;"the NEXT n
screen, putting out fires." 6030 PRINT AT 21,0; PAPER 2;" (32spaces) '
5020 PRINT AT 7,2;"You Lose if 6040 FOR N=1 TO 25: LET L=INT
the fires get out";AT 9,2; (RND*10)*2+1: LET C=INT
"of controL!" (RND*15)*2+1
5030 PRINT AT 12,2;"Use these 6050 LET s$(L,c)="1": PRINT AT
keys:";AT 14,3;"STEER RIGHT 8 L,c; PAPER 0;" ": NEXT N
LEFT 5";AT 16,9;"GO FORWARD 6060 LET 1=1: LET c=1
7";AT 18,3;"SQUIRT 1 QUIT Q" 6070 LET d=1: LET f=0
5050 PRINT AT 21,0;"HANG ONTO 6080 RETURN
74 75
Action games Program listings
The spirit of adventure
Adventure games should challenge the players'
ingenuity, wit and staying power. Cunning, not
speed, is the key to success in these games, and
this means that the speed at which the program
runs is not particularly important either. That's
good news, because it means that you do not
have to think about machine code, or about
making sure that your program is always written
in the most efficient and fastest way.
What is an Adventure Game? You have
probably played them already, but just in case
you haven't met them before . , .
An Adventure Game is like an adventure
story, except that you - the player - are part of
that story. It will usually be set in some exotic
place - a Lost Temple, a mad scientist's secret
base, the Wild West, an alien planet, the ocean
floor, a jungle, or whatever. The object of the
game is usually to explore all the parts of this
place, meeting and overcoming terrible
dangers, and eventually finding some
wonderful object, treasure, captured princess,
magic wand, or even the Lost Crown of the
Umbamajini!
The game is played as a series of events, with
the computer first telling the player which
'room' that he is in, and something about it -
what he can see there, and which ways he can
leave. The player then tells the computer what
he wants to do. The instruction might be to go to
76 77
Adventure games The spirit of adventure
the next room, or to pick up an object that he friendly, others hostile. You will also need to
can see, or what he is going to do to stop the place a variety of objects in various locations,
'great hairy monster with gnashing teeth and for the player to find. Some of these might be
rolling eyes' from eating him up. These absolutely vital to the success of the adventure,
instructions are given using a few simple words, others merely useful, and some totally useless.
which the computer has been programmed to One of those objects should be the chest of
understand. treasure, magic ring, lost crown or whatever
Some adventure games go beyond this, and else you decide is the key object which must be
are more a variety of 'Dungeons and Dragons', found.
where the player is one of a band of explorers, All of this needs to be planned out carefully
the others being controlled by the computer. on paper, well before you start to hit the
Each player has his own special mixture of keyboard. The more time and care you take at
strengths and abilities - he may be a magician, this stage, the quicker ana iess frustrating the
a warrior, a burglar, a dwarf. The player's programming will be.
character is decided at the beginning of the The final stage of the writing process is
game by a random process. testing the game. You will find, unless you are
At the time of writing, probably the most one of those rare perfect human beings, that
successful adventure game around is 'The there are things that you didn't foresee, and that
Hobbit' (Psion & Melbourne House), where the your program needs all sorts of minor - or major
player enters Tolkien's wonderful world of - adjustments before the game goes as you
dwarves and trolls, elves and goblins, wanted.
magicians and spiders. Like proper adventure All in all, writing an adventure game is a long
games, this is text-based, but some pretty process, but an interesting one. We'll start to
pictures of different locations have been added look at it in detail shortly. First, though, there are
- just to brighten things up. a few programming techniques that are vital in
this type of game, so let's have a look at those.
78 79
Adventure games The spirit of adventure
would have jumps all over the place.
A neater and, in the end, simpler way to cope
with two conditions is to use the LOGICAL
OPERATORS. These are the words AND, OR
and NOT.
80 81
Adventure games BASIC logic
Logical operators is true OR both are true. You can see this in the
truth table.
Computer scientists like to show how logical
operators work, by setting out all the possible String variables
combinations in a TRUTH TABLE, Here's the
table for AND (when there are two conditions). All of the examples above have used number
You will see that both the X condition and the Y variables, but the logical operators work just as
condition have to be true, before X AND Y is well with string variables. Try this:
true, (The program only jumps if X AND Y is 10 INPUT "COLOUR 1";C$
true.) 20 INPUT "COLOUR 2";D$
30 IF C$="RED" AND D$="BLUE" THEN
PRINT "MY FAVOURITE COLOURS."
40 STOP
Now change line 30 and try it again:
30 IF C$= "RED" OR D$= "BLUE" THEN
PRINT "I LIKE GREEN."
Note that line 30 only works properly if the same
typefaces are used by both the player and the
computer, It's no good if the player types in 'red'
and the computer is looking for 'RED', There are
other problems like this with string variables,
and we will return to them later.
82 83
Adventure games BASIC logic
Planning the game The adventurer sets out from Port Bata, on the
coast of Equatorial Guinea, to explore inland
regions beyond. Much of the land through
which he will travel is thick jungle, but there are
also mountains, swamps and desert. The
adventurer has brought a number of useful
The story things with him, but he does not have all that he
will need if he is to survive and complete his
What is the story behind your game? Where mission. There are other essentials which he
does the action take place, and what sort of must find, somehow or other, as he goes on. For
things can happen. What is the point of the a start, he will need an axe if he is to chop his
game? These are basic questions that you must way through the impenetrable jungle.
answer before you can go any further. The journey is fraught with danger. There are
Adventures based on Goblm-and-Dwarf wild animals and cannibals out there in the
fantasy land are traditional, but are perhaps a jungle, and the explorer could easily come to an
bit overdone. Haunted Houses and Science untimely, and sticky, end in a patch of swamp.
Fiction locations are quite common, but offer There are also some valuable contacts to be
lots of scope for imagination. How about a made. Legend has it that the inner room of the
search for the Bigfoot in the wild timberlands of temple is sealed with an enchanted door. Only
America, or the Quest for the Holy Grail, set in he who knows the Word can open that door.
Medieval Europe? You could even set up a The Guardian of the Word is an old hermit who
detective-type adventure based on your own lives somewhere in the mountains. Perhaps he
town, or another real area that you know quite could be bribed to part with his secret...
well. The object of the game is to find that Lost
In JUNGLE, the story is this: deep in darkest Crown. Only that way can the search come to an
equatorial Africa, there is a hidden temple, and end. As an extra, and rather unfriendly, twist to
somewhere in that temple is the ancient crown the game, it is possible to destroy the crown
of the Emperor of Umbamajini. In ages long accidentally, and not notice. The penalty for this
past, the Umbamajiman Empire stretched from is to be trapped forever in the game!
coast to coast across that vast continent, and,
according to the legend, whoever can find the
Lost Crown will be able to claim that enormous
empire, and all its wealth, as his own.
84 85
Adventure games Planning the game
When you have got your storyline planned, and trees to see), or even hidden doors which must
you are happy with it, then it is time to start on be searched for.
the map, This is the stage at which you will work At some point you will have to convert these
out the details of the game, exits into the form of compass directions, as that
The size of your map - how many different is the way that the program will handle them. It
areas or 'rooms' it has - depends upon how may be useful to do it at this stage. If you want to
much memory you are prepared to allow for it. give the impression that your mapped world
A lot of space will be needed for all the data that has three dimensions - stairs in a house, a
the game requires, and for the routines to mountain climb, dungeons and towers in a
handle the different events. In JUNGLE the map castle, then you can label some of your exits Up
has 64 rooms, and the total program takes up and Down, You will then need a special routine
approximately 8k, which is more than enough to convert the Up/Down movements back into
for anyone to key in. If you intend to make much two dimensions. This is done in JUNGLE, You
use of the game, and you have a 48k Spectrum, can even create a truly three-dimensional map,
then you should expand it later. The but more of that later.
descriptions, and event-handling routines, have
been much compressed to keep the program as
short as possible. The map data
The map should allow several good routes
from the start to the goal and should include a All of the data from the map - the descriptions of
number of dead ends, one-way systems and the rooms and the exit directions - must be
other obstacles. There should also be other transferred into arrays in the program. You
places of interest to visit on the way. Some of would not normally do this yet, as there is still
these visits may be vital to the game - in much to be worked out. However, when you are
JUNGLE, you have to go to the shop to get an ready to start programming, here's what needs
axe before you can chop your way through the to be done.
areas of impenetrable jungle, The initialization routine is usually written as a
You do not have to fill every space on the subroutine at the end of the program. It will
map. Rooms can be left empty and walled off inevitably be rather long, and you don't want the
from the player. This map is never visible on the computer to have to run through its bulk every
screen, and sealed rooms could be a useful time it has to look for a line number. In JUNGLE,
distraction for some players. The really serious it is numbered from 2000 onwards.
adventurers try to draw up the map for The first thing to do is to set up the arrays, for
themselves as they carefully explore each and the rooms and the exits. Some programmers
every avenue. They could spend a long time prefer to use single dimensioned arrays for
trying to get into those closed off rooms! their maps - DIM R$(64,14) - (64 rooms, with up
Mark on the map the exits from each room. to ] 4 letters allowed for each description).
These do not have to be open, or even visible. This has its advantages - for a start it uses
You can have locked doors, darkened rooms slightly less memory than a two-dimensional
where the exits can only seen when a torch is lit array, but it also has its drawbacks. I use two-
(or dense jungle where you have to chop down dimensional arrays for two-dimensional maps,
86 87
Adventure games Planning the game
88
89
Planning the game Planning the game
It is very obvious that R$(4,5) is directly Project
over R$(5,5), but not so clear that R$(29) is
above R$(37). Start to plan out your own game. If you are
The data for the rooms and exits can be read feeling ambitious and intend to make it a big
into the arrays by the same loop, and this also game - a hundred or more rooms - then only
keeps the information together in the DATA map out the main routes and areas at this stage.
lines. Leave the rest of the rooms empty, and sealed
off, until you have got the essential routines
2020 FOR N=1 TO 8: FOR T=1 TO 8:
running.
READ R$(N,T),E$(N,T):NEXT
Draw up the map and work out the exits, then
T:NEXT N
convert the information to a DATA list. You
2030 DATA "DESERTW'DESERTV'WS",
could write the subroutine to set up the arrays
"CLEARING'Y'ES'Y'JUNGLEV'/EWS"
and read in the data now, and save it on tape, to
Notice two things in that DATA line: the first be added to later.
DESERT square is a dead end - there is no way
out of it whatsover, and the JUNGLE square has
hidden exits. The"/" before the directions
signals this to the program.
When you have typed in your data, write in a
short routine to print it all out again. That way
you can check it more easily than you could by
reading through the DATA lines.
2500 FOR N=1 TO 8: FOR T=1 TO 8:
PRINT N;T;R$(N,T);E$(N,T):
NEXT T: NEXT N
90 91
Adventure games Planning the game
The SHOP has a SHOPKEEPER visible in it. If
the player offers money or trade goods to the
shopkeeper, he will be given an AXE. The
player must have the axe before he can enter
any JUNGLE square,
Next door to the SHOP is UBIMBI VILLAGE,
where the player will meet a WITCHDOCTOR.
He plays no meaningful part in the game, and
the MEDICINE, which he will give you in
Your adventure games must have things for the exchange for any trade goods, is quite useless.
players to find, and people, or 'things' for them The player is not to know this. You can write an
to meet. If yours is a Tunnel of Gloom1 type of interesting variation to the game by adding an
game, where several different varieties of INVENTORY routine. This takes note of all the
nasties are lying in wait for your luckless things that the player is carrying, and can be
adventurer, then these could be scattered at used to limit the number of items which can be
random about the place, as in the maze games carried. This forces the player to make guesses
covered in the action games section. about what is, and what is not useful.
If you want to create a more organized and ALL of the JUNGLE squares contain JUNGLE,
thoughtful type of adventure, then you will need which is treated as an object by the program,
to spend more time working out where you are but handled by a special routine. It is not
going to place what, and for what reason. There necessary, therefore, for JUNGLE to be marked
should be some objects which are vital to the in every square.
success of the game - the key to the door, the The word 'Objects' is used here for good
matches and torch to light the darkened rooms grammatical reasons. When the player gives his
- and others which will give your players move to the computer, it is in two words
something to think about. Their locations are (generally) - Verb followed by Object. The
also very important, and cannot be left to program will need a routine to check the move
random chance. You could not have the to make sure that it is valid, and part of this
matches hidden at the end of the darkened check will involve looking at the object word
tunnel, as the player could never reach them, and comparing it with the ones it knows. To
Lastly, the objects can be characters in the enable it to do this, the objects need to be
story. written into an array. The locations of the
You can see examples of all of this in these six objects also need to be stored in an array, and
squares from the JUNGLE game. if, as happens in JUNGLE, some objects are
When the player enters the PLANTATION, visible and others are hidden, you need some
he will find BANANAS, He can take these, and means of indicating this.
eat them if he likes. This might be tasty, but If you look at the listing, you will find that line
won't do him a lot of good. He really needs to 2010 sets up a number of arrays, including these
keep those bananas with him in case he meets a - 0$(), P() and F(), O$() is for the OBJECTS, P()
GORILLA, and then they can be put to good is for their positions, given as coordinates, and
use, F() is a set of FLAGS, These are mainly used to
92 93
Adventure games Planning the game
indicate the state of the objects - are they
visible, hidden, or being carried by the player?
The main list of objects is given here. There is
some order to the way that they are organized.
The first object is JUNGLE, which appears to
be at 0,0 but in fact is in every appropriate
square. It has to be included in the object list
because one of the valid moves (and the one
which is probably used more than any other) is
'CHOP JUNGLE1. What sort of actions are you going to allow in
Objects 2 to 8 are all things which can be your game? The adventurer must be able to go
found lying around in various squares, and from place to place, to pick things up and to use
which can be carried off by the explorer. them in various ways. He might also be able to
The RIVER is a bit like JUNGLE. A twist in the speak, search for hidden objects, light torches,
program allows it to appear in (or between) two unlock doors, kill monsters and other enemies,
squares, 8,6 and 8,7 and while it can't be carried eat and drink, and cast magic spells. The limit to
off, 'CROSS RIVER is a good move. the number of possibilities in your game is the
The set of objects from 11 to 22 are arranged amount of memory space that you are prepared
in pairs. The first of each pair - GORILLA, to leave for the routines which manage the
HERMIT, SNAKE, WITCHDOCTOR, SHOP- actions. In JUNGLE these take very nearly half
KEEPER, and CANNIBAL - is visible in the of the total program. The verb list itself is very
given square. If the player does the right thing short:
to, or with, this character, then he is rewarded LOOK, GO, TAKE, GIVE, SAY, OPEN, EAT,
by getting the second object of the pair. To save LIGHT, CHOP, CROSS, KILL.
memory space, most of these follow the same Each of these requires its own routine, of
routine. The player gives a present, and anything from three to ten program lines. Some
receives one in exchange. There are verbs are very simple to handle. 'LOOK will
exceptions to this. The gorilla only likes normally just send the program back to the
bananas, and the snake has to be killed, in the point where it prints a description of the room
right way, to uncover the crown. Also, you can that the adventurer is in at that time. Sometimes
eat the cannibal and still find the torch. it will also reveal objects that are normally
hidden, but to handle this, it is only necessary to
Object list check the coordinates of the current location
1 Jungle 9 River 17 Witchdoctor against those of the squares with hidden
2 Key 10 Bananas 18 Medicine objects.
3 Gun 11 Gorilla 19 Shopkeeper Other verbs are more complex. When the
4 Beads 12 Stick 20 Axe program meets a GO instruction, it must check
5 Cloth 13 Hermit 21 Cannibal that the verb is followed by a valid direction
6 Money 14 Word 22 Torch word (N,E,S,W,U,D), that the exit is visible and
7 Boat ' 15 Snake 23 Lion that it is possible to GO in the given direction. If
8 Matches 16 Crown 24 Door all is well, then the instruction must be
94 95
Adventure games Planning the game
converted into a change of coordinates, and, if you look at line 2010, you will also see that the
not, then the player needs a message to tell him P() - Position array, and FQ, the Flags, both
why not, have twenty-seven stores. Twenty-four flags are
When you are working out your verb list, needed for the major objects, and a further
think about the acceptable Verb-Object three to indicate visibility, and the status of the
combinations at the same time. two doors. The PQ array is really slightly larger
than necessary, but was made that size to allow
VERB OBJECT RESULT a simple READing loop.
LOOK none needed Show location, + 2110 FOR N=1 TO 30: READ 0$(N):
hidden objects if in IF N<28 THEN READ P(N,1),
right squares P(N,2),F(N)
GO N, E, S, W, U, D Move if exit visible,
present and open KILL is the most complex of the verbs used in
the JUNGLE game. It must be used in the form
TAKE Portable Flag to show being 'KILL WITH GUN/AXE/STICK', and can only be
objects carried used where a second character or animal is
GIVE Any carried Receive object, if in present. In the version given here, the KILL
right square
instruction always works where the victim is
SAY the WORD Open enchanted harmless (GORILLA, HERMIT, WITCHDOCTOR
door, if WORD
and SHOPKEEPER), although none of these
carried should be killed, as each has something to give
OPEN DOOR Unlock door, if KEY to the adventurer. When the player tries to kill
carried the LION,SNAKE or CANNIBAL, it becomes a
EAT BANANAS Yum yum' message bit more risky. There is a chance that he will
CANNIBAL Reveal hidden miss, and then he gets eaten. Finally, as part of
TORCH this routine, the SNAKE has to be killed with the
LIGHT TORCH Shows exits, if right thing if the Lost Crown is to be revealed.
TORCH and Think through the possible complexities of
MATCHES carried
the Verbs before you commit yourself to them.
CHOP JUNGLE show exits from It would probably be best, in the early stages of
jungle square the game, to keep to an absolute minimum. You
CROSS RIVER move between 8,6 can always expand the game later when the
and 8,7 essential routines are working properly.
KILL GUN Depends on place
(WITH) AXE and victim
STICK
You will notice that the 'Objects' listed next to
GO are the directions, and these need to be
added onto the Object List. In JUNGLE, the O$()
array is dimensioned for thirty objects (twenty-
four things and characters, and six directions). If
96 97
Adventure games Planning the game
This can create a minor problem. If the player
The key routines stays in one location for any length of time, while
he tries out different instructions (perhaps
looking for a way to escape), then there is going
to be a build up of text. You can cope with this in
several ways.
The program core 1 Restrict the amount of text. Only display the
location, and other basic information, and not
Adventure games will generally follow the the previous moves. This is a simple way to
same pattern, and use the same, or very similar, keep the screen tidy, but some players like to
routines at their core. They are made individual be able to see at least some of their most recent
by the data that goes in at the initialization stage, moves,
and by their action subroutines.
2 Store the last few moves and display them
separately. The display can be updated by a
The print routine simple loop. Here the M$() array stores the last
five moves.
This starts by telling the player where he is and 4000 FOR N=1 TO 5
what he can see. How you present this is 4010 LET M$(N)=M$(N+1): NEXT
important. Straightforward text printing, as in 4020 RETURN
JUNGLE, can get boring, unless you have a gift
for words and can write some stunning The latest move is then stored in M$(6).
descriptions of the rooms. Pictures can be NOTE A very friendly option to offer your
added here if you are prepared to take the players is a 'Move Review'. If the space is
trouble. They do, of course, take up memory, available, you could store every move in an
and a separate picture for each location would array, and display the move number at each go.
eat up space alarmingly. Limiting yourself to a The player could then choose to see any
different picture for each type of location will particular move or set of moves, or every move
help - in JUNGLE there are 40 types of rooms in that he has made. This could be especially
those 64 squares. An alternative is to give useful at the end of the game, where he tries to
pictures only for certain locations - the more find out where he went wrong!
interesting ones, or those where an object is to
be found. 3 Create a limited scroll. You can get the
Divide the screen into picture area and text computer to shuffle lines of print up the screen,
area and keep all your printing within the limits. while the rest stays fixed, by getting it to read
98 99
Adventure games The key routines
the characters and rewrite them on another At the end of the routine, D$ holds the first word
line. This is the kind of routine that you would and Q stores the position of the space. This will
need: be needed later.
The next stage is to run the verb array
10 CLS through a loop, comparing each in turn with D$.
20 FOR Z=1 TO 5:PRINT Z : N E X T Z
When the word is found, its reference number
30 FOR L=1 TO 5 : F O R C=0 TO 10:
is stored in VG (Verb Good). If at the end of the
LET X$=SCREEN$(L,C)
loop VG = 0 (to which it was set at the start)
40 PRINT AT L-1,C;X$:NEXT C:
then the computer knows that no match has
NEXT L been found.
50 PRINT AT 4,0;Z: LET Z=Z+1
If you are using verbs which do not need
60 GOTO 30 objects - like LOOK, or RUN - then now is the
Line 30 starts reading the screen from the time to check for them. Keep these single word
second line down, storing the character in X$. instructions at one end of the array so that
This is then displayed directly above by line 40, handling them is e a s y . . . ,
Line 50 then prints the next Z number in the I F VG=1 (if the word is LOOK)
space created below to keep the demonstration
going. Only numbers are used here but this Next make sure that there is another word
technique can be used for as much text as you there....
want, anywhere on the screen. IF Q=LEN A$ THEN
You must not try to slice a word that isn't there,
Syntax checks as the program will crash, and the next stage is
to slice off the second half of the input and
Checking that the player has used words that transfer it to another store.
make sense to the computer is largely a matter LET W$=A$(Q+1 TO LEN A$)
of string slicing and logic. The routine that
handles this in JUNGLE runs from line 150 to W$ is then compared with the words in the
300. object list, and its reference number held in KW
It starts by separating the first word from the (Known Word).
rest of the string. This is done by finding the The final section of the main program sends
space between the words and slicing off the the computer off to the action subroutines, and
portion to the left of the space. then checks for any possible endings before
looping back to the PRINT lines.
150 . . . F O R N=1 TO LEN A$: In JUNGLE, there are several ways in which
IF A$(N)<> " " THEN GOTO 170 the program can be ended. The adventurer can
160 LET D$=A$(TO N-1):LET Q=N: be lost in the desert, or walk into a patch of
LET N=LEN A$ jungle without an axe, disappear in quicksand
170 NEXT N or swamp, or be eaten. Lines 340 to 370 deal
with these possibilities. There is even a chance
that your player might actually reach the goal
100 101
Adventure games The key routines
and find the crown. This is checked in one of the
subroutines, and the program ends at that point.
This is not good programming practice, and is The variables
not to be encouraged. Ideally you should always R$Q Room ARRAY
return from subroutines, and end your program PL, PC Player's Line and Column co-ordinates
from the main routine. You must do this if you GE Giver or Enemy - used to store ref. number
are going to offer the player another game from when a character or animal is met,
within the program. Leaping out of subroutines CS Can See something? (0 = No. 1 = Yes)
without using RETURN leaves the return line VE Visible Exits? (0 = No, 1 = Yes)
number on the Gosub Stack, and uses up E$() EXIT ARRAY
valuable memory space. You can see the limit F() Flag ARRAY. F(25) is general visiblity flag,
of the Gosub Stack by running this program: F(25) = 0 means you can't see anything.
Q Stores position of space in instructions.
10 LET N=0 D$ Do something - the Verb.
20 PRINT N, VG Verb Good. VG = 0 means word not
30 LET N=N+1: GOSUB 100 known,
100 GOTO 20 W$ Word - do What, The object.
How many return addresses can it store before KW Known Word. KW = 0 - unknown object.
overflowing? EU Eat You. EU = 1 means that something or
someone has eaten the adventurer.
Project
102 103
Adventure games The key routines
Action subroutines are all about Condition command pass without comment,
Testing. Has the player used a meaningful The first part of line 1210 is not strictly
combination of words? Is he in the right place to necessary. It transfers the array variable to a
perform a particular action? Has he all the simple variable for ease of handling.
equipment he needs to be able to do it? As so many of the rooms in this game have
Look at the routines in the JUNGLE listing to hidden exits, it makes sense to check that the
see how they are tackled. They are not easy player can see to go, before you do anything
program lines to read, as they contain so many else."/" indicates that the exit is hidden, and if
reference numbers and variables. Take, for F(25)=0 then either the jungle hasn't been
example, the GO subroutine - your adventure chopped down, or the torch has not been lit.
games will need one very similar to this. The last stage before allowing a move is to
check that the player is not trying to walk
1200 IF KW<25 THEN PRINT "I CAN'T through locked doors. These are at 4,5 and 6,5,
GO "; W$: RETURN and their status is flagged by F(26) and F(27).
1210 LET G$=0$(KW,1):FOR N=1 TO Normal N,E,S,W movements are a simple
4: IF E$(PL,PC,N>="/" AND F$ matter of using the logical operators to add to or
(25) ="0" THEN PRINT "I CAN'T take from the line or column variables. There
SEE TO GO ANYWHERE,": RETURN are then two extra lines to convert TJ' and 'D'
1220 IF G$oE$(PL,PC,N) THEN GO into two-dimensional moves. The way it works
TO 1290 in JUNGLE is that Up means West for any room
1230 IF PC=5 AND (PL=4 AND above line 3, and South for any room below.
F(26)=0) OR (PL=6 AND Likewise, Down means East on lines 2 and 4,
F(27)=0) THEN PRINT "THERE and North on line 3 and below line 4. If you are
IS A CLOSED DOOR.": RETURN using Up and Down, then try and arrange it to
1240 LET PC=PC-(G$="W") + (G$="E") keep the conversion simple.
1250 LET PL=PL-(G$="N") + (G$="S") Notice that there are two RETURN lines. If,
1260 IF G$="U" THEN LET and when, the program finds a valid move, it
PC=PC-(PL<4): PL=PL+(PL>3) will come to line 1280, close the loop and return.
1270 IF G$="D" THEN LET If it runs right through the loop without finding a
PC=PC+(PL=2 OR PL=4): LET match between your chosen direction and the
PL=PL-(PL=3 OR PL>4) possible exits from that room, then it returns
1280 LET N=4: NEXT N: RETURN after printing the 'No go' message.
1290 NEXT N:PRINT"! CAN'T GO THAT
W A Y . " : RETURN
The first thing to check here is that the player Project
has given a proper direction. All of these have
reference numbers of 25 or more. (Line 1200.) If Start writing the subroutines to handle the
you wanted to include witty responses to any actions in your own game.
illegal commands they would have to be fitted
in before this general cut-out line. For example,
you might not want to let a GO BANANAS
104 105
Adventure games The key routines
Helpful hints
Taking it further In this form, the program gives the player
advice on how to cope with the particular
situation he finds himself in. The hint will appear
as a single line in the normal text area. It might
JUNGLE is a very basic example of adventure be a clue, or it might be the actual solution to a
games. There are a great many ways that it problem. If you have the memory space to
could be improved. You might like to do this spare, you could set up an array to hold helpful
instead of, or as well as, writing your own game hints for every room, and read these into the
array at the same time as the program is
from scratch. reading the room descriptions and exits.
A more economical form of help-giving is to
have a short list of general hints.
1 TRY GOING NORTH
Struggling players will very much appreciate a 2 TRY GOING SOUTH
HELP option. It can take several forms, but ,.,etc
whatever kind of help you give, it should be 7 HAVE A GOOD LOOK ROUND
accessed in the same way. Include HELP in 8 USE THE STICK
your Verb list, and write in a subroutine to 9 DON'T KILL HIM
handle it. 10 THIS IS A USEFUL OBJECT
You can then create an array to hold the
reference numbers of the appropriate hint for
The help page each room.
Here the normal location text display is
replaced by a complete page of general help
and advice. As an absolute minimum this should
include a list of the acceptable Verbs and
Objects, and a note on how to enter commands.
You can go further and give a list of all the
acceptable combinations of words (if there is
space on the screen).
If you intend to give more specific help, then
it is better done a different way.
106 107
Adventure games Taking it further
example here, any player with a strength of 9 or
Wizards, Warriors & Dwarves more knows that the odds are in his favour. He is
most likely to kill the wolf (with a score of 7 or
Some adventure games are played 'Dungeons more) on the first blow, but even a very low
and Dragons' style. In this game each player has I score will inflict 50% wounds, so that a second
a different character, with a different balance off stroke would finish it off.
abilities. Warriors are strong, but not very The player's ability levels change during the
bright, and can use only the simplest spells. course of the game, He gains in magic and
Wizards have much magic at their disposal, strength as he overcomes challenges, and he is
Burglars are sneaky, Dwarves are tough and weakened by combat. The object of the game is
can keep a few spells up their sleeves. The to survive, and grow, as well as to find treasures.
game is usually played by groups of people, As you can imagine, the action subroutines to
acting as a single party as they explore their cope with these encounters can become very
way around the dungeons, and they are then complex, When working out this type of game,
able to put their different abilities to work in keep it as simple as possible at first, Develop
different situations. A feature of Dungeons and the routines you need to handle the encounter
Dragons is that the dungeons are inhabited by a with one type of monster - the ability variables,
weird variety of monsters, some of whom can the Kill/Wound array, the 'dice-roller' - and then
be best defeated by Warriors, others by expand it, one aspect at a time.
Wizards, and others by Dwarves.
To develop a game along these lines you are
going to need a whole set of new routines, At
the simplest level, the game could be played by
one player with his character determined by
chance at the start. This can be done in either of
two ways. The character type can be selected
at random, with his balance of abilities fixed by
the character, or the level of his different
abilities can be decided by a set of RND lines,
and a character given according to the balance.
Of the two, the first method is by far the easiest
to organize.
The levels of his abilities are held in
variables, and brought into play during
encounters. When player meets monster, and
decides to fight, he does it by rolling the dice,
The score needed to defeat the beast will
depend upon the nature of the monster, and the
level of the player's abilities. This combination
of chance and known quantities enable the
player to plan his moves more wisely. In the
108 109
Adventure games Taking it further
Other characters can be introduced to the
game in different ways. There can be Random factors
predetermined companions, as in the famous
HOBBIT program, and these can take a more or The simple random number is not always
less active part in the game. Their abilities can enough. It's fine where you want something to
be added to the player's, when they are around, happen once every so many times:
and they can be made to appear and disappear IF RND>.8 THEN
at intervals. There are several ways in which
you could handle this. Their presence can be Where you have a distinct set of possible
controlled by random lines in the mam loop: outcomes you can use lines like these:
LET X=RND
IF RND>.9 AND COMPANION=0 THEN
LET COMPANION =1
IF X <=.25 THEN., (go North)
IF X >.25 AND X <=.5
You can mark certain squares as crossroads THEN .. (go East)
where the companion will branch off, if he was IF X >.5 AND X <=.75
with the player, and join him if he wasn't. THEN., (go South)
Their stay can be timed. Reset the timer at IF X >.75 THEN., (go West)
the beginning of the game, and have the
companion wandering off after a given time. In your encounters with monsters you might
want a more flexible, and realistic, outcome.
POKE 23672,0: POKE 23673,0 Producing a random number on the computer is
like rolling a dice. Every number is as likely as
This would check for a lapse of 15 minutes: the next. What you want is for the middling
IF PEEK 23673>180 THEN numbers to come up more often than the
extremes. Something in between is always
These same techniques can be used to create
more likely than total failure or total success.
moving monsters in your game, They don't
actually have to move from square to square, You can create the 'curve1 effect in two ways.
simply to appear - preferably when least One way is to set the limits for the random
numbers so that the central section is wider:
expected.
The companion characters can be brought IF X >.3 AND X <.7 THEN..
under the control of the player, or of a group of (50% wounds)
players. At the INPUT stage, the computer
The alternative is to combine two random
would need to be told which character was to
numbers. The most likely number you would
be affected by the following command, and the
get by rolling two dice is 7. This can turn up in
variables that hold information about the player
six different ways. The extreme numbers, 2 and
must be made into arrays to cope with the extra 12, will only turn up about once in every thirty-
characters. Apart from that, the rest of the game
six rolls. For a percentage result - perhaps the
runs the same way that it does for a single percentage of wounds in an encounter - use
character.
two random numbers between 0 and 50, Over
half of the totals will be between 35% and 65%.
110 111
Adventure games Taking it further
3-D maps worthwhile to stop at an early stage of your
planning, and try to work out how much
Running an adventure game in three memory your game will need. As a very rough
dimensions is no more difficult than running one guide, in the JUNGLE program, about Uk was
in two dimensions. The only extra programming used for the mam program loop, 3k for the
involved is a pair of lines to handle the change action subroutines and 2k for the initialisation.
of 'floor', You will need to take a little extra care A further 2k was needed to create the arrays.
when setting up your maps, to make sure that The memory cost of an array can be
the different floors agree with each other. The calculated accurately. A string array uses 1 byte
stairs going up from one level must meet the for each element, plus a few bytes for labelling.
ones that come down from above. R$(10,10,10) will take approximately Ik, and will
The room array will need an extra dimension, allow you up to ten letters per room for
and you will need to adjust the initialization descriptions. If you created space for
stage so that all your data is read in, and in the descriptions of fifty letters (about seven words)
right order. then a hundred room map would still only need
If your game takes place within a building, 5k. The DATA lines to fill the array would
then you will probably waste little space within probably need another 5k. You could cut this
the array, Each room will be used. On the other cost by SAVEmg the array DATA separately
hand, if the game is set in a wider landscape, and LOADmg it in at the start of the game.
with mountains and castles rising out of flat land,
then there could be quite a lot of the array left
blank - unless your hero can fly! It is always
112 113
Adventure games Taking it further
150 LET Q=1: LET D$=A$: FOR N=1
TO LEN A$: IF A$(N)<>" "
THEN GO TO 170
160 LET D$=A$( TO N-1): LET
Q=N: LET N=LEN A$
170 NEXT N: GO SUB 3000
180 LET VG=0: FOR N=1 TO 11: IF
Program listing 190
200
D$<>V$(N) THEN GO TO 220
IF D$0"KILL" THEN GO TO 210
IF A$(Q+1 TO Q+4)="WITH"
THEN LET D$=D$+" WITH": LET
Q=Q+5
210 LET VG=N: LET N=18
220 NEXT N
230 IF VG=0 THEN PRINT "I DON'T
KNOW HOW TO ";D$: GO TO 120
10 REM "JUNGLE" 240 IF VG=1 THEN GO TO 310
20 GO SUB 2000 250 IF Q=LEN A$ THEN PRINT ' "TELL
30 PRINT " LOCATION ";R$(PL,PC) ME AGAIN. ";D$;" WHAT ? ":
40 PRINT " YOU CAN SEE... " GO TO 120
50 LET GE=0: LET CS=0: FOR N=1 260 LET W$=A$(Q+1 TO LEN A$):
TO 24: IF P(N,1)oPL OR GO SUB 3020
P(N,2)oPC THEN GO TO 70 270 LET KW=0: FOR N=1 TO 30: IF
60 IF F(N)=1 THEN PRINT 0$(N): W$oO$(N) THEN GO TO 290
LET CS=1: IF N>10 AND N/2 280 LET KW=N: LET N=31
OINT (N/2) THEN LET GE=N 290 NEXT N
70 NEXT N: IF CS=0 THEN PRINT 300 IF KW=0 THEN PRINT '"I DON'T
" NOTHING." KNOW THE WORD ";W$: GO TO
80 PRINT " VISIBLE EXITS " 120
90 LET VE=0: FOR N=1 TO 4: IF 310 GO SUB 1100+50*VG+(50 AND
(E$(PL,PC,N)="/" AND F(25)=0) VG>2)
OR E$(PL,PC,N)=" " 320 IF F(25)=1 THEN LET F(25)=2:
THEN LET N=4: GO TO 110 GO TO 340
100 PRINT (E$(PL,PC,N) AND 330 IF F(25)=2 THEN LET F(25)=0
E$(PL,PC,N)<>"/"): LET VE=1 340 IF R$(PL,PC, TO 9)
110 NEXT N: IF VE=0 THEN PRINT ="QUICKSAND" OR R$(PL,PC, TO 5)
"NONE" ="SWAMP" THEN GO TO 1000
120 INPUT "WELI ?";A$ 350 IF PL=1 AND PC=1 THEN GO TO
130 IF A$="STOP" THEN GO TO 1070 1040
140 IF LEN A$<6 THEN LET A$= 360 IF F(20)<>3 AND R$(PL,PC, TO 6)
A$+" " ="JUNGLE" THEN GO TO 1040
114 115
Adventure games Program listing
370 IF EU THEN GO TO 1020 1300 IF PL<>P(KW,1) OR PC<>P(KW,2)
380 GO TO 30 OR F(KW)=0 THEN PRINT " TAKE
1000 PRINT R$(PL,PC)': GOTO 1060 WHAT?": RETURN
1020 PRINT "YOU HAVE BEEN EATEN .": 1310 IF KW>22 THEN PRINT "THAT'S
GO TO 1060 NONSENSE!": RETURN
1040 PRINT "LOST.STARVED." 1320 IF KW=1 OR (KW>10 AND KW/2
1060 PRINT "HARD LUCK.YOU'RE DEAD." <>INT (KW/2)) THEN PRINT
1070 PRINT "USE ""RUN"" TO "YOU CAN'T TAKE A ";W$:
RESTART.": STOP RETURN
1150 IF PL=2 AND PC=8 THEN LET 1330 IF F(KW)=3 THEN PRINT "YOU
E$(2,8)="UNS": RETURN HAVE ALREADY GOT IT."
1160 IF PL=3 AND PC=6 THEN LET 1340 LET F(KW)=3: RETURN
E$(3,6)="EW": RETURN 1350 IF GE=0 OR GE=15 OR GE=23
1170 IF PL=2 AND PC=4 THEN LET THEN PRINT "GIVE WHAT TO
F(2)=1: RETURN WHOM?": RETURN
1180 RETURN 1360 IF F(KW)<>3 THEN PRINT "YOU
1200 IF KW<25 THEN PRINT "I CAN'T HAVEN'T GOT THE ";W$: RETURN
GO ";W$: RETURN 1370 IF GE>12 AND KW>2 AND KW<9
1210 LET G$=0$(KW,1): FOR N=1 TO THEN GO TO 1390
4: IF E$(PL,PC,N)="/" AND 1380 IF GE=11 AND KW<>10 THEN
F(25)=0 THEN PRINT "I CAN'T LET F(KW)=0: RETURN
SEE TO GO ANYWHERE.": RETURN 1390 LET F(GE)=0: LET F(GE+1)=3:
1220 IF G$<>E$(PL,PC,N) THEN PRINT "THE ";0$(GE);" SAYS
GO TO 1290 'THANK YOUy /
1230 IF PC=5 AND ((PL=4 AND 1395 PRINT "HE GIVES YOU THE ";
F(26)=0) OR (PL=6 AND 0$(GE+1)'"AND GOES AWAY.":
F(27)=0)) THEN PRINT "THERE RETURN
IS A CLOSED DOOR.": RETURN 1400 IF PL<>4 OR PC<>5 THEN
1240 LET PC=PC-(G$="W") + (G$="E") PRINT "THAT'S NO USE HERE.":
1250 LET PL=PL-(G$="N") + (G$="S") RETURN
1260 IF G$="U" THEN LET 1410 IF KW<>14 THEN PRINT "IT'S
PC=PC-(PL<4): LET NO USE SAYING ";W$: RETURN
PL=PL+(PL>3) 1420 IF F(14)<>3 THEN PRINT "YOU
1270 IF G$="D" THEN LET DON'T KNOW THE WORD."
PC=PC+(PL=2 OR PL=4): LET 1430 LET F(26)=1: PRINT "A DOOR
PL=PL-(PL=3 OR PL>4) OPENS IN THE EAST WALL":
1280 LET N=4: NEXT N: RETURN RETURN
1290 NEXT N: PRINT "I CAN'T GO 1450 IF PC<>5 OR F(25)<1 THEN GO
THAT WAY.": RETURN TO 1490
116 117
Adventure games Program listing
1460 IF PL=6 AND F(2)=3 THEN LET 1670 PRINT "CROSS WHAT? CROSS
F(27)=1: PRINT "THE DOOR IS COMPUTER SOON!": RETURN
OPEN": RETURN 1680 LET PC=7-(PC=7): PRINT
1470 IF PL=6 AND F(2)<>3 THEN "SAFELY ACROSS.": RETURN
PRINT "YOU HAVEN'T GOT THE 1700 IF KW<>3 AND KW<>12 AND
KEY.": RETURN KW<>20 THEN PRINT "YOU
1480 IF PL=4 AND F(27)<>1 THEN CAN'T KILL WITH THAT.":
PRINT "YOU HAVEN'T SAID THE RETURN
WORD.": RETURN 1710 IF GE=0 THEN PRINT "KILL
1490 PRINT "WHAT DOOR?": RETURN WHAT?WHO?": RETURN
1500 IF KW=10 AND F(10)=3 THEN 1720 IF GE=11 OR GE=13 OR GE=17
LET F(10)=1: PRINT "YUM OR GE=19 THEN GO TO 1760
YUM": RETURN 1730 IF GE=15 AND KW=12 THEN
1510 IF KW=21 AND GE=21 THEN GO TO 1780
GO TO 1540 1740 IF RND>.6 THEN PRINT
1520 IF F(KW)<>3 THEN PRINT "IT "MISSED!": LET EU=1: RETURN
ISN'T YOURS TO EAT.": RETURN 1750 PRINT "KILLED HIM!": LET
1530 PRINT "YUK!": LET F(KW)=0: 0$(GE)=" ": RETURN
RETURN 1760 LET F(GE)=0: PRINT "A BIT
1540 LET F(22)=1: LET F(21)=0: UNNECESSARY, BUT HE'S DEAD.":
PRINT "BURP! SEE WHAT YOU'VE RETURN
FOUND.": RETURN 1780 PRINT "IT'S DEAD, AND YOU'VE
1550 IF KW<>22 THEN PRINT "YOU FOUND THE LOST CROWN OF
CAN'T LIGHT A ";W$: RETURN UMBIMAJINI.": GO TO 1070
1560 IF F(8)<>3 THEN PRINT "YOU 1999 RETURN
NEED MATCHES.": RETURN 2000 REM "INITIALIZATION"
1570 IF F(22)<>3 THEN PRINT "YOU 2010 DIM R$(8,8,14): DIM E$(8,8,4):
NEED THE TORCH.": RETURN DIM 0$(30,11): DIM P(27,2):
1580 LET F(25)=1: PRINT "IT'S DIM V$(11,5): DIM F(27)
ALIGHT, BUT NOT FOR LONG.": 2020 FOR N=1 TO 8: FOR T=1 TO 8:
RETURN READ R$(N,T),E$(N,T):
1600 IF F(20)<>3 THEN PRINT "NO NEXT T: NEXT N
AXE.NO CHOP!": RETURN 2030 DATA "DESERT"," ", "DESERT","WS",
1610 IF KW<>1 THEN PRINT "YOU "CLEARING","ES","JUNGLE","/EWS"
CAN'T CHOP DOWN ";W$: RETURN 2035 DATA "SWAMP", " "/'JUNGLE",
1620 LET F(25)=1: PRINT "NOW YOU "/EWS","PLAIN","WE","LOW HILL",
CAN SEE.": RETURN "WS"
1650 IF PL=8 AND (PC=6 OR PC=7) 2040 DATA "DESERT","NE","DESERT","WNE",
AND F(7)=3 THEN GO TO 1680 "P LA I N","N S W","RU I N","N E"
1660 IF F(7)<>3 THEN PRINT "YOU
NEED A BOAT.": RETURN
118 119
Adventure games Program listing
2045 DATA "JUNGLE","/ND", 2110 FOR N=1 TO 30: READ 0$(N):
"CLIFF SIDE","UDN", IF N<28 THEN READ
"CLIFF PATH","UDS", P(N,1),P(N,2),F(N)
"HILL SIDE","UN/S" 2120 NEXT N
2050 DATA "PORT BATA","ES","OLD 2130 DATA "JUNGLE",0,0,1,"KEY",
STREET","ESW","EDGE OF 2,4,0,"GUN",3,1,1 /'BEADS",
TOWN","NSW","PASSAGE","/ENS" 7,2,1,"CLOTH",3,3,1
2055 DATA "STAIRS","/UD","CAVE","E/W", 2140 DATA "MONEY",3,1,1,"BOAT",
"CLIFF PATH","NSW","HUT","N" 4,1,1,"MATCHES",3,2,1,
2060 DATA "BEACH","NES","DUNES", "RIVER",8,6,1
"NSW","SWAMP'," "/'SMALL ALCOVE", 2150 DATA "BANANAS",5,4,1,
"/NE" "GORILLA",?,7,1,"STICK",
2065 DATA "TEMPLE ROOM","/UWE", 7,7,0
"INNER SANCTUM","W", 2160 DATA "HERMIT",3,8,1,"WORD",
"CLIFF TOP","DNS","SWAMP"," " 3,8,0,"SNAKE",4,6,1,
2070 DATA "QUICKSAND"," "/'PLAIN", "CROWN",4,6,0
"NESW","JUNGLE","/NEW", 2170 DATA "WITCHDOCTOR",6,2,1,
"PLANTATION","WS" "MEDICINE",6,2,0,
2075 DATA "ENTRANCE HALL","S/ED", "SHOPKEEPER",6,3,1,
"PRIEST'S ROOM","/W","CLIFF "AXE",6,3,0
PATH","NES","ROCKY LEDGE","UDW" 2180 DATA "CANNIBAL",8,8,1,
2080 DATA "BEACH","NES","UBIMBI "TORCH",8,8,0,"LION",6,6,1,
VI LLAGE"/'NES","SHOP","WS", "DOOR",6,5,0,"U",0,0,0,"D",
"JUNGLE" ,"NES" 0,0,0,"N",0,0,0,"E","S","W"
2085 DATA "JUNGLE"/'/NEW", 2190 FOR N=1 TO 11: READ V$(N):
"CLEARING","WE" /'MOUNTAIN", NEXT N
"DSW","MOUNTAIN PASS","DS" 2200 DATA "LOOK","GO","TAKE","GIVE",
2090 DATA "BEACH","NS"/'STREET", "SAY","OPEN","EAT","LIGHT",
"NS","YARD","N","JUNGLE", "CHOP',"CROSS","KILL"
"/NES" 2210 LET PL=3: LET PC=1: LET
2095 DATA "PLAIN","ESW","LAKE","EW", EU=0
"LARGE NEST","NESW","JUNGLE", 2220 RETURN
"/WN" 3000 IF LEN D$<5 THEN LET
2100 DATA "JUNGLE","/NE","VILLAGE D$=D$+" ": GO TO 3000
END","NEW","PLAIN","EW", 3010 RETURN
"PLAIN","NEW" 3020 IF LEN W$<11 THEN LET
2105 DATA "JUNGLE","/NEW","WEST W$=W$+" ": GO TO 3020
BANK","W","EAST BANK", 3030 RETURN
"NE","WEETU VILLAGE","W"
120 121
Adventure games Program listing
and to play it as a board game, or a pencil and
paper game. This is the best way to work out
the rules, and to find out what size of board and
what number and variety of pieces you need to
122 123
Interactive games Came design
First moves How much damage does the hit cause? Enough
to knock out the other tank?
The program lines from 300 on, and the
subroutines at 1000 and 1200, manage this part
of the program. The orders are held in the array
In BATTLE, the game is played on a 16 x 16 grid O$(2,4,3) - two armies, four tanks in each, and
- the battlefield - on which are marked three up to three parts for each order - the type of
features - two rivers and a wood. These are command, and direction and distance where
natural obstacles which the tanks cannot cross, necessary,
and the wood does not even allow the passage Movement involves relatively little. The tank
of shells, The battlefield is shown on the screen, is removed from its old position both on screen
and also held in an array. and in the array, and its new position is then
Each player has four tanks, at the beginning calculated from the given direction. If this
of the game, and on each move he gives square is already occupied by another tank, or
instructions to all of these, The tanks can move, by an obstruction, then the tank is replaced
fire or stand inactive, and the player can specify where it was. Otherwise, its new position is
the direction and distance of movement or entered on the screen, in the array, and in the
shelling. The orders need to be stored in an line and column variables of the tank's own
array, and a second array is needed to hold the array. The screen is laid out so that the line and
position and the damage status of each piece. column positions for the array agree with the
There are two parts of this program where PRINT AT lines and columns.
we can expect to have problems - the routines Firing is slightly more complicated. The
that manage the computer's decision-making, shells are moved in much the same way as the
and the routines that carry out the orders. If we tanks, and, in fact, both are able to use the same
replace the computer with a second (human) subroutine (at 1100) to convert direction into a
player in the early version of the program, then change of line and column. Checking for a HIT
we are able to concentrate on the analysis and is a simple matter of looking at what is in the
movement routine, array at the shell's square, A further routine is
The routine will work through the orders, needed to analyse the hits (1200 on). This
taking one from each player in turn. Is the piece compares the line and column of the shell with
still present, or has it been knocked out of the the stored positions of all the tanks, until it finds
game? Is it making an active move this time, or a match.
just standing still? If moving, is there a vacant This is not the only way to cope with this type
square in the right place? If firing, does it hit of problem. An alternative is to use a separate
another tank, and, in which case, which tank? code for each piece in the map array.
124 125
Interactive games First moves
In BATTLE, the player's tanks are all coded as
T, the computer's/second player's, as 'E' (for
Enemy), '1234' and 'ABCD' could have been
used instead. This would have made it very
simple to spot which tank had been hit, but
would have created other problems elsewhere
in the program. Look up the lines where the
computer checks for 'T' and 'E' and imagine how
they would look under the alternative system.
How quickly should the game end? This is the
key question when working out the damage
assessment routine. If you are converting an
existing game into a program, then you can
follow the methods used in the game. In
BATTLE, the amount of damage caused by a hit
depends upon two factors - the distance
between the tanks and a random number (line
1250), The damage status of the tank that is firing
the shell could be worked into the equation if
you felt it was useful. This line would do it:
LET DAMAGE = ((5-E)*INT(RND*10)+10)
*A(P,N,3)/100
'E' is the variable from the loop that moves the
shell. Its value is equivalent to the distance
between the tanks.
A(P,N,3)/100 is the percentage damage
status, where 100% means undamaged.
Probably the best approach to damage
calculations is to keep playing through the
game with different damage lines, until you find
one that gives the right effect.
126 127
Interactive games First moves
which can be knocked out most quickly, and a
development of this is to concentrate as much
fire as possible on one tank at a time. That way
you reduce the number of opponents most
quickly, and therefore reduce the amount of
damage that you will suffer.
128 129 .
Interactive games Developing tactics
There was an interesting little problem involved
in finding a single direction value - for the
computer's orders - from the scan routine. This
produces X and Y values of either -1,0 or +1.
You could use eight separate lines, like this;
IF X=-1 AND Y=-1 THEN LET D=8
IF X=0 AND Y=-1 THEN LET D=1
etc, etc
The routine would work, but it's long, and it
will slow the program down. The computer will
have to check a total of sixteen possibilities as it
works through those lines.
To find a more compact way of doing this, we
have to look for a pattern in the values of X, Y
andD,
The table shows that D will be 2,3 or 4 when
X= +1, and that it will be 2 when Y= -1,3 when
Y=0 and 4 when Y= +1. This leads us to the
line:
3500 IF X=1 THEN LET D=3+Y
When you have found one pattern, the next is
always more obvious.
3510 IF X=-1 THEN LET D=7-Y
A simple 'truth in a bracket' test allows one
line to cater for the two values of D when X=0:
IF X=0 THEN LET D=1+4*(Y=1)
The program now only has to test three values
of X in this routine. The saving in time is obvious,
Whenever you find a long, repetitive routine,
look for ways of compacting, Usually the
increase in speed is worth the effort of rewriting
the lines, but not always. Sometimes the more
compact routine will be so involved and
complex that it is not worth using - you, after all,
will be faced with the problem of debugging it,
and will you remember exactly how it works in
a few months' time?
130 131
Interactive games Developing tactics
initialization routine after the wood's position has
Take it from here been set. It checks that columns 5 to 8 are clear.
IF C>8 THEN LET P1=1
(C = wood column)
Plan 1 is now operational. It is worked into the
Strategies computer's move by a new line:
3065 IF P1=1 AND C>=5 AND C<=8
There's room for improvement in the BATTLE THEN GOTO 3100
program, in both meanings of the term. The (C = tank column)
program could definitely be improved, and
there's memory space in which to write your Plan 2 would use a similar pair of lines to find
extensions to the program. and move up a broad column on the other side
Ways of improving the computer's tactics of the wood.
have already been covered, but what about its
strategy? At the moment its master plan is to
find where the wood isn't and advance, This Landscaping
approach is hardly likely to give a hard time to
any Napoleons among its human opponents, but Your map could include other features such as
could it be improved? The answer must be yes. hills and roads. Hills would slow down the tanks,
How does a thoughtful human (you) approach but offer improved shelling distances from the
the game? What possible opening moves can summit. Roads could give greater speed. If you
you make? Is it best to attack along a single feel the map is too small to accommodate all the
broad front, or does it pay to split your force? features you would like to include-then use a
How does the position of the wood affect the larger map. You could reduce the amount of
game? In what ways do you respond to your other information on the screen, or remove it
opponent's plan of campaign? altogether, writing in a new 'Help' page that the
As you find answers to these questions, write player could call up at will.
them down in terms of orders of priorities, or of
specific responses to specific situations. They '
can then be added into the program. For
example, if you wanted the computer's tanks to
advance four abreast, if there was room, you
would start by including this line in the
132 133
Interactive games Take it from here
the Second World War, computers were much
Other units used for working out the probabilities of
success of different types of military action. The
A whole new range of possibilities, and planners could feed the machines with data
complexities, can be introduced into your game about their own and the enemy's weapons and
by including other units such as artillery or forces, the nature of the terrain, and the
anti-tank infantry units. These would have possible effects of different kinds of weather,
different speeds of movement, ranges of fire, and the computers were then able to pull all the
and resistance to hits. Each different type would information together to give an assessment of
need a separate set of control routines, but they the plans. If you are a keen war-gamer, you
would follow the same general plan as those should, at the very least, write programs to
used for the tanks. make your machine handle the hit tables and
For a more mobile game, you could try damage assessment, and to keep track of all the
'redesigning' your tanks, so that they can fire results.
while they are moving. If you restrict the firing Whatever the game you decide to program,
to the direction of movement, then this won't do spend a long time planning it, before you try
raise any major problems. to write the program, and don't expect it to work
perfectly first time, because it won't. You are
entering difficult territory. Enjoy the journey.
A game of your own
What will your interactive games be? Most
board games can be programmed, though
some will take more thought and effort than
others. The tactical games like chess, draughts,
Chinese Checkers and Ludo all offer real
challenges. (The major challenge on Chinese
Checkers is how you cope with a hexagonal
board!) Other board games present different
problems of programming and of presentation,
but the routines to work out the computer's
decisions are usually quite simple.
Card games can be programmed and are
particularly interesting if you are keen on the
mathematics of probability. At the time of
writing, card-playing programs are fairly thin on
the ground - perhaps because people prefer to
play cards with people.
War-gaming is traditional computer territory.
Some of the first computers ever built were
used for calculating the trajectories of shells. In
134 135
Interactive games Take it from here
208 REM cp=1 if computer plays
209 REM
210 IF cp=1 THEN GO SUB 3000:
GO TO 350
220 LET p=2: GO SUB 2000
349 REM
136 137
Interactive games Program listing
448 REM fire routine 1030 LET a(p,n,1)=l: LET
449 REM a(p,n,2)=c
450 FOR e=1 TO VAL o$(p,n,3): 1037 REM
GO SUB 1100 1038 REM display tank
460 IF m$(l,c)="w" THEN LET e=4: 1039 REM
GO TO 490: REM in wood 1040 PRINT AT a(p,n,1),a(p,n,2);
467 REM INK p;"A"
468 REM move shelL 1050 LET t$="T": IF p=2 THEN LET
469 REM t$="E"
470 LET z$=m$(l,c): PRINT AT 1057 REM
l,c;"*":BEEP .02,0 1058 REM enter in array
477 REM 1059 REM
478 REM check for hit 1060 LET m$(a(p,n,1),a(p,n,2))=t$
479 REM 1070 RETURN
480 PRINT AT l,c;"B": IF z$="T" 1100 LET l=l+(d>3 AND d<7)-
OR z$="E" THEN GO SUB 1200 (d=8 OR d<3)
490 NEXT e 1110 LET c=c+(d>1 AND d<5)-(d>5)
500 NEXT p: NEXT n 1120 RETURN
507 REM 1200 PRINT AT l,c; INK
508 REM check for win 1 + (z$="E");"A"
509 REM 1219 REM
510 FOR p=1 TO 2: LET v=0: FOR 1220 REM which was hit?
n=1 TO 4: LET v=v+a(p,n,3): 1221 REM
NEXT n 1228 REM check line and column
520 IF v=0 THEN GO TO 600+ 1229 REM
(100 AND p=2) 1230 FOR x=1 TO 2: FOR y=1 TO 4:
530 NEXT p: GO TO 100 IF a(x,y,1)ol OR
600 PRINT AT 20,1;"*** Red wins. a(x,y,2)oc THEN GO TO 1300
***": STOP 1237 REM
700 PRINT AT 20,1;"*** Blue 1238 REM make tank flash
wins. ***": STOP 1239 REM
1000 PRINT AT l,c;"B": LET 1240 LET z=22528+32*l+c: POKE z,
m$(l,c)=" " (PEEK z+128)
1010 GO SUB 1100: REM change Line 1247 REM
and column 1248 REM damage assessment
1017 REM 1249 REM
1018 REM is move blocked? 1250 LET damage=(5-e)*INT
1019 REM (RND*10)+10
1020 IF m$(l,c)<>" " THEN GO TO 1260 LET a(x,y,3)=a(x,y,3)-damage
1040 1267 REM
1268 REM knock out if under 10
138 139
Interactive games Program listing
1270 IF a(x,y,3)>=10 THEN GO TO 2069 REM
1290 2070 PRINT a$;: LET o$(p,n,1)=a$:
1280 LET a(x,y,1)=0:LET a(x,y,2)=0: IF a$="S" THEN GO TO 2140
LET a(x,y,3)=0: PRINT AT 2080 INPUT AT 0,0;"Which
l,c;"B": LET m$(l,c)=" ": direction? ";a$
LET y=4: LET x=2: GO TO 2090 IF a$<"1" OR a$>"8" THEN GO
1300 TO 2080
1287 REM 2100 PRINT a$;: LET o$(p,n,2)=a$
1288 REM turn off flash 2110 INPUT AT 0,0;"Distance ?";a$
1289 REM 2120 IF a$<"1" OR a$>"4" THEN GO
1290 BEEP .1,25: POKE z,(PEEK TO 2110
z-128) 2130 PRINT a$;: LET o$(p,n,3)=a$
1300 NEXT y: NEXT x: 2140 POKE z,PEEK z-128
LET e=4: RETURN 2150 NEXT n: RETURN
2000 REM get orders 2999 REM
2001 REM 3000 REM computer gives orders
2010 FOR n=1 TO 4 3001 REM
2017 REM 3005 FOR n=1 TO 4: LET m=0: LET
2018 REM tank still operational? o$(2,n)=" "
2020 IF a(p,n,3)=0 THEN GO TO 3007 REM
2150 3008 REM tank still operational?
2027 REM 3010 IF a(2,n,3)=0 THEN GO TO
2028 REM make tank flash 3190
2029 REM 3020 LET l=a(2,n,1): LET
2030 LET Z=22528+32*a(p,n,1)+ c=a(2,n,2)
a(p,n,2>: POKE z,PEEK z+128 3027 REM
2035 REM 3028 REM scan for enemy in range
2038 REM collect order codes 3030 LET h=4: GO SUB 3200
2039 REM 3040 IF m=1 THEN GO TO 3190
2040 PRINT AT 19+p,n*6; INK p;n;: 3047 REM
POKE 23658,8: INPUT AT 3048 REM scan for enemy just out
0,0; ("Player ";p;":Unit ";n;" of range
- Move ?");a$ 3050 LET h=6: GO SUB 3200
2050 IF a$="S" OR a$="F" OR a$="G" 3060 IF m=1 THEN GO TO 3190
THEN GO TO 2070 3067 REM
2057 REM 3068 REM main line of advance
2058 REM ignore invalid inputs 3069 REM
2059 REM 3070 IF c=ac OR c=ac+1 THEN GO
2060 GO TO 2040 TO 3100 '
2067 REM 3080 IF c<ac THEN GO TO 3110
2068 REM transfer to array 3090 IF c>ac THEN GO TO 3140
140 141
Interactive games Program listing
3100 IF m$(l-1,c)=" " THEN LET 3250 IF m$(U,c1)<>" " THEN LET
o$(2,n,2)="1": GO TO 3180 z=H
3110 IF m$(l-1,c+1)=" " THEN LET 3260 NEXT z: NEXT x: NEXT y
o$(2,n,2)="2": GO TO 3180 3270 RETURN
3120 IF m$(l,c+1)=" " THEN LET 3497 REM
o$(2,n,2)="3": GO TO 3180 3498 REM get Direction from scan
3130 LET o$(2,n,1)="S": GO TO 3499 REM
3190 3500 IF x=1 THEN LET d=3+y
3140 IF m$(l-1,c-1)=" " THEN LET 3510 IF x=-1 THEN LET d=7-y
o$(2,n,2)="8": GO TO 3180 3520 IF x=0 THEN LET d=1+4*(y=1)
3150 IF m$(l,c-1)=" " THEN LET 3527 REM
o$(2,n,2)="7": GO TO 3180 3528 REM finish off order
3160 LET o$(2,n,1)="S": GO TO 3529 REM
3190 3530 LET q$="G": IF h=4 THEN LET
3165 REM q$="F"
3170 REM STAND if no good move 3540 LET o$(2,n,1)=q$: LET
3175 REM o$(2,n,2)=STR$ d: LET
3180 LET o$(2,n,1)="G": LET o$(2,n,3)="4"
o$(2,n,3>="2" 3547 REM
3190 PRINT AT 21,n*6; INK 2;n; 3548 REM close loops
o$(2,n): NEXT n: RETURN 3549 REM
3200 REM 3550 LET z=8: LET x=1: LET y=1:
3201 REM scan routine LET m=1: RETURN
3202 REM 3999 STOP
3205 FOR y=-1 TO 1: FOR x=-1 TO 4000 PAPER 7: INK 0: BORDER 7:
1: FOR 2=1 TO h CLS : PRINT AT 0,13;"BATTLE"
3210 IF x=0 AND y=0 THEN GO TO 4010 PRINT AT 2,1;"Each move
3260 opens with you giving'""each
3220 LET U = l+z*y: LET c1=c+z*x piece its orders."
3230 IF c1<1 OR L1<1 OR c1>16 OR 4020 PRINT "The second player (or
L1>16 THEN LET 2=8: GO TO Spectrum)"'y/gives his orders,
and the moves"
3260 4030 PRINT "are then played
3237 REM out .'""POSSIBLE MOVES:"
3238 REM spotted a target
4040 PRINT " GO.. FIRE.. STAND
3239 REM (do nothing)""'Direction and
3240 IF m$(H,c1)="T" THEN GO SUB
3500: GO TO 3260 distance must be"
4050 PRINT "given for GO or FIRE
3247 REM commands."
3248 REM path blocked 4060 PRINT " GO 1 or 2 squares."
3249 REM
142 143
Interactive games Program listing
4070 PRINT "Rivers & woods can't 5120 FOR n=1 TO 2: FOR e=1 TO 4:
be crossed.'""FIRE - Max. 4 LET a(n,e,1)=1+(15 AND n=2):
squares - more damage at REM Lines
close range." 5130 LET a(n,e,2)=e+6: REM
4500 FOR n=1 TO 2: READ g$: REM coLumns of pieces
graphics 5140 LET a(n,e,3)=100: REM 100% =
4510 FOR r=0 TO 7: READ b: POKE undamaged
USR g$+r,b: NEXT r: NEXT n 5150 NEXT e: NEXT n
4520 DATA "A",0,0,31,24,126,255, 5160 BEEP 1,0: INPUT AT 0,0;"ONE
PLAYER OR TWO ?"; LINE A$
126,60: REM tank
4530 DATA "ff',0,1,0,1,0,1,0,85: 5170 IF A$<>"1" AND A$<>"2" THEN
REM grid Lines GO TO 5160
5000 DIM m$(16,16): REM map 5180 LET cp=VAL A$(1)
5010 DIM o$(2,4,3): REM orders 5200 BORDER 5: CLS
5020 LET m$(6, TO 3)="rrr": 5205 REM
LET m$(7,4)="r": 5210 REM blank map
LET m$(10,13)="r": 5215 REM
LET m$(11,14 T0)="rrr" 5220 PRINT AT 0,0; PAPER 2;"(18
5030 REM rivers on map spaces) "
5040 LET l=INT(RND*6)+4: LET 5230 FOR n=1 TO 16: PRINT AT
c=INT (RND*5)+5 n,0; PAPER 2;" "; PAPER 7;
5050 FOR n=L TO 1+3: LET "BBBBBBBBBBBBBBBB"; PAPER 2;
m$(n,c TO c+3)="wwww": NEXT " ": NEXT n : REM GRID
n 5240 PRINT AT 17,0; PAPER 2;"(18spaces)"
5055 REM 5250 REM direction display
5060 REM wood in random position 5255 REM USE KEYBOARD FOR SYMBOLS
5065 REM IN 5260
5070 LET ac=5: IF c<8 THEN LET 5260 PRINT AT 1,20;"DIRECTIONS";
ac=11 AT 3,22;"8 1 2";AT 4,23;
5075 REM "\I/";AT 5,22; "7-*-3"; AT
5080 REM attack Line misses wood 6,23;"/l\";AT 7,22;"6 5 4"
5085 REM 5270 REM
5090 LET m$(1,7 TO 10)="TTTT": 5280 REM put details on map
LET m$(16,7 TO 10)="EEEE" 5290 REM
5095 REM 5300 FOR 1=1 TO 16: FOR c=1 TO
5100 REM starting positions 16: IF m$(l,c)=" " THEN GO
5105 REM TO 5350
5110 DIM a(2,4,3): REM 2 armies - 5310 REM rivers
4 pieces in each - Line, 5320 IF m$(l,c)="r" THEN POKE
coLumn and damage status 22528+32*L+c,40
5115 REM 5330 REM woods
144 145
Interactive games Program listing
5340 IF m$(l,c)="w" THEN POKE
22528+32*L+c,32
5350 NEXT c: NEXT L
5360 REM display armies
5370 PRINT AT 1,7; INK 1;"AAAA"
5380 PRINT AT 16,7; INK 2;"AAAA"
5390 RETURN
146 147
Interactive games Program listing
CLEAR clears the memory beyond the BASIC
program, wiping out all variables, arrays, etc.
CLEAR 50000 resets RAMTOP, the end of
your BASIC program area, to address 50000
(48k machine.) Used to create a safe space in
which to store machine code programs.
CHR$ converts an ASCII code number into a GOSUB (line number) sends the program to a
character, graphic, or control command. subroutine, storing the current line number in
CIRCLE draws a circle. Follow it by three the gosub stack. When the program meets a
numbers - the x and y co-ordinates of the RETURN command, it returns to the line at
centre, and the radius. which it left the main program.
148 149
Appendix A Appendix A
GOTO (line number) sends the program to variable, i.e. how many characters in it.
the line given. If there is no line with the stated LET gives a value to a variable. LET A=99.
number, then the program will go to the next LET N$="PETER".
line down. LIST displays the program on the screen.
LIST 100 (or whatever) to start the list from a
IF THEN test a condition, and the particular line.
program branches if the condition is true. LOAD "MYGAME" will search for a program
INK is the colour in which characters are called "MYGAME" and load it into the computer.
printed. Use a number between 0 and 7 to get LOAD"" will load the first program it finds.
the colours shown on those keys. INK 8 is
transparent - characters will be printed in NEW clears the BASIC area of memory, (the
whatever INK colour happens to be set at the program and any variables and arrays) ready
squares on which they appear. INK 9 will make for a new program. Things beyond the BASIC
the Spectrum print either in white, or black, area - UDG's and machine code routines - are
whichever gives the best contrast with the not affected.
PAPER colour at the print position. NEXT is the closing command for a
INKEY$ reads the keyboard. It can be used FOR. .NEXT. .loop. As long as there is a number
directly; left, and it is within range of the STEP, then the
program will loop back to the FOR.
IF INKEY$ ="8" THEN X=X+2...
It is safer, however, to transfer the character OR tests to see if either or both of two
read, from INKEY$ to a normal store.... statements are true.
LET A$= INKEY$. OVER 1 can produce some peculiar printed
IFA$="8"THEN.... effects. Two characters can both appear at the
INPUT waits for the user to type something in, same position, but where their INK dots
and then to press ENTER to close the message. coincide, the screen will be PAPER colour.
If you are friendly towards your users, you will OVER 0 is the normal condition.
usually include prompts in the INPUT lines, so
that they know what they are supposed to do: PAPER is the colour of the background.
Numbers 0 to 7 give the colours shown on the
INPUT "PLEASE TYPE IN YOUR NAME";N$ keys. PAPER 8 is transparent - anything printed
INT lops off the whole number part of any this way will pick up whatever the background
number. INT 4.567 = 4. INT 9.9999 = 9. Almost colour happens to be at that point. PAPER 9 is
essential when using the RND function, as this contrast, and will be either black or white, to
produces decimals, and you will want whole give the best contrast to the current INK colour.
numbers for most purposes. PAUSE makes the program wait for a given
INVERSE prints reversed characters by length of time. PAUSE 50 will cause a wait of 1
putting PAPER where the INK should be and second. PAUSE 0 for an endless wait. The
vice versa. program can be moved on at any time by
pressing a key. PAUSE 0: LET A$ =INKEY$ is
LEN tells you the length of a string or a string one way to collect keystrokes.
150 151
Appendix A Appendix A
PEEK (an address) will tell you the contents of RESTORE pushes the data marker back to
any address. Some PEEKs are more useful than the top of the data list. If you want to READ the
others. same set of DATA several times - perhaps the
PLOT puts a dot of INK at the point marked by data for your signature tune - then you must
x,y coordinates. PLOT 100,50 will plot a point restore the data marker before it reads.
100 dots from the left, and 50 dots up. RESTORE followed by a line number sets the
POKE (an address) puts data into an address data marker to the data that starts at, or after,
in memory. Machine code routines have to be that line.
POKEd into place. RETURN sends the program back from a
PRINT puts things on the screen. The PRINT subroutine to the main program.
lines can contain a wide variety of commands to RND produces a random decimal number
change the appearance of the printed material between 0 and 1. It can be used as it is to set a
- colour commands are the most obvious. random limit:
PRINT AT line, column;"... will print at a RUN clears all variables and starts the
given place on screen. program. This can be replaced by GOTO
PRINT SEPARATORS: a semicolon (;) followed by the first line number if the program
between two items will make the second item has already been run and you want to keep the
appear immediately after the first. information that the variables contain,
A comma (,) between two items makes the
second item appear in the next available print SAVE "MYGAME" transfers a program to
zone. tape, and labels it "MYGAME".
An apostrophe (') between two items makes SAVE "MYGAME" CODE (number)
the second item appear on the next available transfers a machine code program starting from
line. the address given.
PRINT TAB column;"... will print at a given SAVE"MYGAME" LINE 10 saves a named
column on the next available line. program so that when reloaded it automatically
PRINT, (ZONE). A print zone is half a screen runs from line 10.
wide. SAVE "MYGAME" SCREEN$ transfers a
screen to tape, with the label "MYGAME".
RANDOMIZE should be used at the start of SQR gives you the square root of a number.
any program where you are going to use STOP halts the program. It can be restarted
random numbers. It makes sure that the random with CONT.
number sequence starts at a random place. STR$ converts a number to a string variable.
READ must be followed by a variable. It STR$ 9 is "9".
transfers DATA from the DATA line to the given
variable. VAL gives you the value of a number in a
REM marks the start of a line where you can string, or string variable. VAL "99" - 99.
write remarks to remind you what the program VAL will also give you the answer to a sum in
is doing. The computer ignores anything on a a string. VAL" 3+4*SQR 16" -19
REM line. VERIFY is used after SAVING a program, to
make sure that the tape recording is good,
152 153
Appendix A Appendix A
light for each BIT that is set to 1 in each row.
To define a character then, you need to put a
new pattern of binary numbers into the memory
space for that character. Spectrum's User
Defined Graphics are to be found in Graphics
Mode, on the letter keys 'A' through to 'U'.
154 155
Appendix B Appendix B
30 DATA BIN 00000000, BIN
11110000,BIN 01101000,
BIN 01100100,BIN 11111111,
BIN 01100100,BIN 01101000,
BIN 11110000
The next stage is to learn to convert binary
number patterns into normal decimal numbers.
To do this, use the Conversion Table, Work
through your number from left to right, and
Appendix C
when you find a ' 1', note down the decimal
number above that column. Add the decimal
numbers together at the end. The DATA line in Super screens
the example program can now be changed:
30 DATA 0,240,104,100,255,100,104,240
This section introduces two machine code
routines that allow you to produce screen
When you want to define more than one effects that you could never achieve in BASIC.
character - which will usually be the case - When you are typing in these routines, or any
then you can compact even further by using a other machine code routines for that matter,
double loop. The outside loop determines the take extra care to ensure that you type exactly
number of characters, and READs the letter for what is written. A mistake in a machine code
each character. The inside loop is the same as routine will not make the Spectrum print a
that used above. helpful Error Report. What normally happens is
10 FOR N=1 TO 2: READ G$
that the machine locks up and you have to pull
the plug and start again.
20 FOR R=0 TO 7: READ B
30 POKE USR G$+R,B: NEXT R: NEXT N
You will get more out of machine code
40 DATA "B",56,60,56,16,56,120,191,184
routines if you understand what they are
50 DATA "C",184,184,40,36,36,68,132,196
supposed to do. Read up on Z80 machine code,
and then use the Assembler codes in Appendix
You will probably find it best, at first, to stick to A of the Spectrum manual to analyse the routine.
the binary form of numbers, as it is then much
easier to see how the numbers and the patterns Screen Dump and Recall
relate to each other. Compact the DATA into This transfers an entire screen display to a
decimal form later, when you are happy with reserved area in memory, and transfers it back
the designs, and when you feel you need the again when wanted. The process is much the
extra memory space. same as transferring screens to and from tape
with SAVE and LOAD instructions, but infinitely
Conversion table quicker.
128 64 32 16 8 4 2 1 10 CLEAR 24999
0 1 1 0 1 0 0 0 20 FOR N=25000 TO 25023
Total = 64 + 32 + 8= 104 30 READ X:POKE N,X: NEXT N
156 157
Appendix B Appendix C
40 DATA 33,0,64,17,0,98 very slick transfer between game and Help. To
1,0,27,237,176,201 do this you will need two dumps. This version of
50 DATA 33,0,98,17,0,64, the routine will do it:
1,0,27,237,176,201 10 CLEAR 49999
Type it in and run it. Nothing visible has 20 FOR N=50000 TO 50047
happened yet, but the code is in place. Now 30 READ X: POKE N,X : NEXT N
print something in the screen, then enter this: 40 DATA 33,0,64,17,0,196,
1,0,27,237,176,201
RANDOMIZE USR 25000
50 DATA 33,0,196,17,0,64,
Clear the screen, then enter this: 1,0,27,237,176,201
60 DATA 33,0,64,17,0,223,
RANDOMIZE USR 25012
1,0,27,237,176,201
You should see your original screen again. 70 DATA 33,0,223,17,0,64,
RANDOMIZE USR 25000 sent the Spectrum to 1,0,27,237,176,201
the machine code routine that started at
address 25000. That routine - the data in line RANDOMIZE USR 50000, and RANDOMIZE
40 - dumps the screen contents in another area USR 50012 dump and recall the first screen.
RANDOMIZE USR 50024, and RANDOMIZE
of memory.
USR 50036 dump and recall the second screen.
CLEAR 24999 resets RAMTOP to that
address, to create an area beyond the BASIC 2 Use the routine for animating a graphic
program for your screen dump. This dump across a detailed background. Dump the
needs nearly 7k of memory, so you are only left background, print your graphic, and then recall
with about 2k for your BASIC. If you have a 48k the background to erase the graphic before you
machine, this could be changed to CLEAR move it. It's fast, and very effective.
56999, The machine code routine and screen
dump area is now much higher in memory, and Smooth Scrolls
you have 34k left for your program. If you do this Try this for a super title screen, or work it into
you must also change the next line to: an action game to give a moving background.
FOR N=57000 TO 57023 10 CLEAR 29999
20 FOR N=30000 TO 30016
The machine code routine starts the screen
30 READ X: POKE N,X: NEXT N
dump at 25088. This needs moving to match the 40 DATA 33,255,87,14,192,6,32,
new RAMTOP. Change the 98's in the DATA 183,203,22,43,16,251,13,32,
lines to 223. 98*256=25088: 223*256=57088. This 245,201
is the start of the new screen dump area. 50 INK 6: PAPER 0: CLS
60 FOR N=1 TO 50: LET
Using the Screen Dump
1 Use screen dumps to save the game screen Y=INT(RND*176):
when you bring up a Help page. You could LET X=INT(RND*256)
even hold the Help page in a dump, to allow 70 PLOT X,Y: NEXT N
80 LET Z=USR 30000
158 159
Appendix C Appendix C
90 LET Y=INT(RND*176):PLOT255,Y
100 GOTO 80
LET Z=USR 30000' is another way of calling up
a machine code routine. If you use
RANDOMIZE USR 30000 here, then you
interfere with the random numbers, so that they
are no longer random.
Variations
With a few minor alterations, you can make this
routine scroll the screen from left to right. This
program shows it in operation.
10 CLEAR 29999
20 FOR N=30000 TO 30016
30 R E A D X: POKE N,X: NEXT N
40 DATA 33,0,64,14,192,6,32,183,
203,30,35,16,251,13,32,245,201
50 LET L=0
60 LET Z=USR 30000
70 PRINT AT L,0;"B"
80 LET L=L+1: IF L>21 THEN LET L=0
90 GOTO 60
You don't have to scroll the whole screen. If you
have watched a screen being loaded in from a
tape, you will have noticed that it works in three
blocks of eight lines each. Change DATA line to
this if you only want the bottom third of the
screen to move:
40 DATA 33,0,80,14,64,6,32,183,
203,30,35,16,251,13,32,245,201
The third number has been changed to 80, and
the fifth to 64. These control where in the
display file you start your scroll, and how much
you move. There are three possible starting
points - Top of screen (64), Middle section (72)
and bottom third (80). To scroll a third of the
screen only, the fifth number should be 64; 128
moves two-thirds of the screen, and 192 scrolls
it all.
160
Appendix C
Open up the fantastic world
of computer games
ZX Spectrum Game Master
Arcade games, adventure games, strategy games
they're all here in the ZX Spectrum Game Master.
BUILD YOUR OWN GAMES
Not just a book of listings but a guide to creating and
personalising your own games. The ZX Spectrum Game
Master provides all the building blocks you'll need to
start programming your own games. Title pages, game
screens, sound effects, movement routines, scoring
routines. Everything you need and a lot more besides,
FULL LISTINGS
To start you off there are plenty of full length Spectrum
games listed in the Game Master. Choose between
arcade, adventure, and strategy games. Then, when
you've played through a game, use the listings to develop
something of your own. Put on your own title page - and
your own name.
It's your game after all.
GAME MASTER
Move en to wholly original games. The tricks and routines
in the ZX Spectrum Game Master will give you the
confidence to set off on your own. How to develop your
own ideas, how to plan your games, how to present them
on screen, how to program them
for maximum efficiency
MASTER THE ART OF THE SUPER GAMESTERS.
ZX SPECTRUM GAME MASTER.
Longman
Computer
Books