The complete game is the final source from lesson nine. This lesson changes no numbered lines. Save a version that reconstructs the graphics and begins at the instructions.
Keep a tape recording
Press Q to return to BASIC. Follow the tape workflow in Meet BASIC with this unnumbered command:
SAVE "tail" LINE 10Line 10 installs the custom characters and calls the title routine. Saving that entry point lets a fresh machine reconstruct what the game needs; it does not depend on graphics already left in memory.
Follow the ROM recording prompt, then export the recording using your emulator’s tape controls. Keep the readable BASIC source too. Exporting a tape does not necessarily remove earlier recordings; use the intended recording and check its name.
Start a fresh 48K session, attach the tape and enter:
LOAD "tail"Start playback. The title should appear automatically. If it keeps searching, check the tape position, playback and name. If you see an older game, check which recording was exported.
Check a complete round
Start with S. Try a turn and an ignored reversal, hit the wall and retry. Eat food and watch the length increase. Deliberately turn into the body after growth, then restart. Complete all eight foods, check that movement stops, retry once more and quit with Q.
A fresh session matters because it begins without the custom graphics and game arrays. The program must rebuild those from its own DATA and initialisation.
Would a screenshot of the winning screen prove that the saved tape loads correctly?
Show the explanation
No. It shows one visible state. Loading the tape in a fresh session and playing checks that the recording can reconstruct the program and its state.
Complete Tail Chase program
10 GO SUB 7000: GO SUB 5000
100 DIM g(16,24): DIM a(12): DIM b(12)
110 LET n=4: LET eaten=0: LET h=4: LET t=1: LET dr=0: LET dc=1: LET steps=0
120 FOR j=1 TO 4: LET a(j)=8: LET b(j)=j+5: LET g(8,j+5)=1: NEXT j
130 GO SUB 1000: GO SUB 2000: GO SUB 2500
140 LET nd=dr: LET nc=dc: LET turn=0: LET tick=PEEK 23672
150 LET k$=INKEY$
160 IF k$="q" OR k$="Q" THEN GO TO 9000
170 IF k$="r" OR k$="R" THEN GO TO 100
180 IF turn=1 THEN GO TO 240
190 IF (k$="i" OR k$="I") AND dr=0 THEN LET nd=-1: LET nc=0: LET turn=1
200 IF (k$="k" OR k$="K") AND dr=0 THEN LET nd=1: LET nc=0: LET turn=1
210 IF (k$="j" OR k$="J") AND dc=0 THEN LET nd=0: LET nc=-1: LET turn=1
220 IF (k$="l" OR k$="L") AND dc=0 THEN LET nd=0: LET nc=1: LET turn=1
240 LET elapsed=PEEK 23672 -tick
250 IF elapsed<0 THEN LET elapsed=elapsed+256
260 IF elapsed<18 THEN GO TO 150
270 LET tick=PEEK 23672: LET dr=nd: LET dc=nc
280 LET nr=a(h)+dr: LET nx=b(h)+dc
290 IF nr<1 OR nr>16 OR nx<1 OR nx>24 THEN LET e$="Mind the wall!": GO TO 4000
300 LET grow=(nr=fr AND nx=fc)
310 IF g(nr,nx)=1 AND (grow=1 OR nr<>a(t) OR nx<>b(t)) THEN LET e$="You caught your tail!": GO TO 4000
320 PRINT AT a(h)+3,b(h)+3; INK 5;CHR$ 149
330 IF grow=1 THEN GO TO 380
340 LET g(a(t),b(t))=0: PRINT AT a(t)+3,b(t)+3;" "
350 LET t=t+1: IF t=13 THEN LET t=1
360 GO TO 390
380 LET n=n+1: LET eaten=eaten+1
390 LET h=h+1: IF h=13 THEN LET h=1
400 LET a(h)=nr: LET b(h)=nx: LET g(nr,nx)=1: LET steps=steps+1
410 GO SUB 3000
420 IF grow=0 THEN GO TO 460
430 GO SUB 2500
440 IF eaten=8 THEN LET e$="Eight snacks. Nicely done!": GO TO 4000
450 GO SUB 2000
460 LET nd=dr: LET nc=dc: LET turn=0: GO TO 150
1000 BORDER 0: PAPER 0: INK 7: CLS
1010 PRINT AT 0,11; INK 5;"TAIL CHASE"
1020 PRINT AT 2,5; INK 7;"Keep some room to turn."
1030 FOR x=3 TO 28: PRINT AT 3,x; INK 1;CHR$ 144;AT 20,x;CHR$ 144: NEXT x
1040 FOR y=4 TO 19: PRINT AT y,3; INK 1;CHR$ 144;AT y,28;CHR$ 144: NEXT y
1050 FOR j=1 TO 4: PRINT AT a(j)+3,b(j)+3; INK 5;CHR$ 149: NEXT j
1060 GO SUB 3000
1070 PRINT AT 21,1; INK 5;"I J K L steer R retry Q quit";
1080 RETURN
2000 LET fr=1 +INT (RND*16): LET fc=1 +INT (RND*24)
2010 IF g(fr,fc)=1 THEN GO TO 2000
2020 PRINT AT fr+3,fc+3; INK 6;CHR$ 150
2030 RETURN
2500 PRINT AT 1,4; INK 7;"FOOD ";eaten;"/8";AT 1,18;"LENGTH ";n;" "
2510 RETURN
3000 LET z=146
3010 IF dr=-1 THEN LET z=145
3020 IF dr=1 THEN LET z=147
3030 IF dc=-1 THEN LET z=148
3040 PRINT AT a(h)+3,b(h)+3; INK 7;CHR$ z
3050 RETURN
4000 PRINT AT 2,0;" ";AT 2,2; INK 6;e$
4010 PRINT AT 21,1; INK 7;"R for another go Q to quit ";
4020 IF INKEY$<>"" THEN GO TO 4020
4030 LET k$=INKEY$
4040 IF k$="q" OR k$="Q" THEN GO TO 9000
4050 IF k$="r" OR k$="R" THEN GO TO 100
4060 GO TO 4030
5000 BORDER 0: PAPER 0: INK 7: CLS
5010 PRINT AT 3,11; INK 5;"TAIL CHASE"
5020 PRINT AT 6,1;"Eight snacks. One hungry snake."
5030 PRINT AT 9,3;"I up J left K down"
5040 PRINT AT 10,3;"L right"
5050 PRINT AT 12,1;"Keep moving. Leave room to turn."
5060 PRINT AT 14,1;"Walls and your own body end it."
5070 PRINT AT 16,1;"R retries. Q quits at any time."
5080 PRINT AT 19,6; INK 6;"S starts. Take a breath."
5090 LET k$=INKEY$
5100 IF k$="q" OR k$="Q" THEN GO TO 9000
5110 IF k$<>"s" AND k$<>"S" THEN GO TO 5090
5120 RANDOMIZE : RETURN
7000 RESTORE 7200: FOR j=0 TO 55: READ v: POKE USR "a"+j,v: NEXT j: RETURN
7200 DATA 255,129,129,129,255,129,129,255
7210 DATA 60,126,90,90,126,126,60,24
7220 DATA 60,126,252,204,204,252,126,60
7230 DATA 24,60,126,126,90,90,126,60
7240 DATA 60,126,63,51,51,63,126,60
7250 DATA 0,60,126,126,126,126,60,0
7260 DATA 8,16,60,126,94,126,60,0
9000 PAPER 0: INK 7: PRINT AT 21,0;"Finished. RUN to try again. ";: STOPThe game, seven character designs and supporting code are original course material under the samples repository’s MIT licence. The game uses shape as well as colour to distinguish the head, body and fruit. The body order and occupancy grid decide the rules independently of that artwork.
For a small optional experiment, change one character’s row bytes while preserving its role. Predict the pixels, reload the graphics and play. The snake should obey exactly the same collision rules. Restore the accepted drawing before keeping your final tape.
Sources
Steven Vickers, edited by Robin Bradbeer, ZX Spectrum BASIC Programming, second edition (Sinclair Research, 1983), 20 (tape saving, loading and entry lines).
Run it here
This unit's program, built for you.
- Program
- step-01.tap
- Machine
- ZX Spectrum 48K (PAL)