Graphics, Games and Gold

See all articles from SYNC v1 n3

Games can be divided into three broad classes. The first has a clearly defined play area which remains the same each time the game is played. Chess, backgammon, tic-tac-toe, and all the card games fall into this category. The second class requires a random area which regenerates differently each time the game is played. Into this group fall the adventure, hunt and seek classics. The last class encompasses all the animated games involving flight and shooting, such as Star Wars and Space Invaders, which require real-time inter-action.

I decided to write my own game using as much of the ZX80 graphics as possible, but without waiting for the 8K Basic ROM and 16K RAM expansion to become available. My choice of game was influenced by several considerations. Everyone knows what the successful outcome of a chess., backgammon, or card game should be, so there is little room for invention. The game either meets expectations or fails. Since the computer is to be a player, it must be a worthy opponent. A dynamic game would have to wait until the 8K ROM becomes available because the screen goes blank during computation with the 4K Basic.

My choice then was to plan an “adventure” type of game, which has the added bonus that the writer can make his own rules.

From the beginning I did not expect to fit all the features I wanted into 1K of memory. So instead I wrote a series of subroutines which could be independently de-bugged and set aside to wait for the arrival of more memory. At that time they would be at joined together to make a working program.

The hero is to roam within a randomly generated wood, cave, or castle. In the final version the monsters and treasures he encounters may appear as drawings. The game area is a rectangle 15 characters or columns by 10 lines. Later it can be expanded to occupy as much of the screen as required. See Figure 1.

[Figure: Figure 1. The Game Area — a 15 by 10 character rectangle, with the NEWLINE character at the end of each line]

Each feature of the game is written as a subroutine starting at a line number which is a multiple of 100. See Figure 2.

Figure 2. Organization of Program.

  10  CONSTANTS
 100  MAIN PROGRAM
 200    -CONT-
 300  SQUARE GAME AREA
 400  RANDOM WOOD
 500  PEEK IN DISPLAY
 600  POKE IN DISPLAY
 700  RANDOM PATH
 800
 900  MOVE CHARACTER
1000  SEARCH FOR CHARACTER
1100
1200  FIND AND REPLACE
1300  GOOD OR EVIL?

Our hero is going to begin his journey in a wood:

400 FOR L = 1 TO 10
405 LET M = L
410 IF L > 5 THEN M = 10 - L
415 LET A = RND (3) + 5 - M
420 FOR C = 1 TO A
425 PRINT CHR$ (128);
430 NEXT C
435 LET B = RND (3) + 2 + M

440 FOR C = 1 TO B
460 PRINT CHR$ (9);
465 NEXT C

470 LET D = 15 - A - B
475 FOR C = 1 TO D
480 PRINT CHR$ (128);
485 NEXT C
490 PRINT
495 NEXT L
RUN this program.

We now have a grey wood surrounded by a black border. Each time this is run it is generated differently. We now add randomly dispersed clearings where our hero will find treasures and do battle.

445 LET F = 9
450 LET E = RND(12)
455 IF E = 10 THEN LET F = 0
460 PRINT CHR$ (F);

Note that line 460 is replaced. RUN this part. Now let’s make it into a subroutine called from a main program.

100 GO SUB 400
299 STOP

497 RETURN

RUN this.

The Jan/Feb 1981 issue of SYNC describes on p. 23 how to use the memory address stored in D-FILE to locate the display file.

600 POKE ( PEEK (16396) + PEEK
(16397) * 256 + Q ) , T
605 RETURN

101 LET Q = 12
102 LET T = 58
103 GO SUB 600

RUN this. The letter U appeared in the top line of the display. Let’s change this to place the U at different points. The game area is a matrix of 15 x 10 characters, but because of the NEWLINE character, each line is really 16 characters long.

101 INPUT Q
104 GO TO 101

RUN this. The program waits for an input. Try each of the following.

1(NL)
3(NL)
17(NL)
32(NL) Oops! We destroyed the NEWLINE character. Enter two alphabetic characters to exit with error 2/101.

Delete lines 101, 103, 104.

Now we will develop a subroutine to allow our hero to move around within the wood.

900 INPUT A$
901 IF A$ = "0" THEN STOP
905 LET Q = P + 16
910 IF A$ = "N" THEN LET Q = P - 16
915 IF A$ = "E" THEN LET Q = P + 1
920 IF A$ = "W" THEN LET Q = P - 1
940 LET T = 58
945 GO SUB 600
970 LET P = Q
975 RETURN

125 GO SUB 900
101 LET P = 152
150 GO TO 125

RUN and enter E,N,W,S to get a string of U’s. Type 0 to exit from line 901.

Now we want to erase the trailing (old) positions of U to leave only one in the display.

950 LET T = 9
955 LET R = Q
960 LET Q = P
965 GO SUB 600
970 LET P = R

RUN this.

Our hero must be confined to the wood until he has earned the right to move on to other adventures.

925 IF Q ( 1 OR Q ) 160 THEN GO TO
975
930 GO SUB 500
935 IF NOT T = 9 THEN GO TO 975

Look in location Q, to which we will move from the present position P.

500 LET T = PEEK (PEEK (16396) +
PEEK (16397) * 256 + Q)
505 RETURN

RUN and try to move our hero into a clearing or out of the wood. Exit with 0(NL).

This subroutine searches for a specific character on a line and replaces it.

1200 LET P = L * 16
1205 FOR C = 1 TO 15
1210 LET Q = P + C
1215 GO SUB 500
1220 IF T = S THEN GO TO 1235
1225 NEXT C
1230 RETURN
1235 LET P = Q
1240 LET T = U
1245 GO SUB 600
1255 RETURN

Our hero is fated to be cast randomly into the wood to begin his journey.

105 LET L = RND (10)
110 LET S = 9
115 LET U = 58
120 GO SUB 1200

RUN this.

Now that we have some working subroutines we can set them aside and delete them from memory to make space for new ones.

We will work with a less fancy wood, so delete lines 400-497, and substitute:

300 LET F = 9
305 FOR L = 1 TO 10
310 FOR C = 1 TO 15
315 IF RND (10) = 10 THEN LET F = 0

320 PRINT CHR$ (F);
325 LET F = 9
330 NEXT C
335 PRINT
340 NEXT L
345 RETURN

For the purpose of checking out the next subroutines, our hero can begin at the bottom of the game area, so delete lines 1200-1255.

Simplify the main program to read:

100 GO SUB 300
101 LET P = 152
125 GO SUB 900
150 GO TO 125
299 STOP

RUN this and exit with 0(NL).

Our hero cannot enter a clearing in the wood, but he needs to know when he has found one. For this we need a search for a neighboring character routine.

1000 LET Q = P - 16
1005 GO SUB 500
1010 IF T = S THEN GO TO 1060
1015 LET Q = P + 16
1020 GO SUB 500
1025 IF T = S THEN GO TO 1060
1030 LET Q = P + 1
1035 GO SUB 500
1040 IF T = S THEN GO TO 1060
1045 LET Q = P - 1
1050 GO SUB 500
1055 IF T = S THEN GO TO 1060
1060 RETURN

When our hero finds the clearing, we will replace it with an inverse X.

1300 LET T = 189
1305 GO SUB 600
1310 RETURN

Since a clearing is a blankspace, S = 0. Add to the main program:

102 LET S = 0
130 GO SUB 1000
135 IF T = S THEN GO SUB 1300

RUN this program and move our hero around with N, S, E, or W.

We can do something more interesting when our hero finds a clearing. This routine POKEs a random number into the clearing representing gold, which our hero collects.

1302 LET V = V + X
1303 LET T = X + 28
1305 GO SUB 600
1310 RETURN

104 LET V = 0

901 IF A$ = "0" THEN GO TO 980
980 PRINT "GOLD", V
985 STOP

As you RUN this and move our hero around, he collects the gold. When 0(NL) is typed, his treasure is displayed. At this point we have all the rudiments of an adventure game. From here we can use our imagination to change the options in subroutine 1300.

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.