Skip to content

Remember where the head went

Store a following body as an ordered list of recent head positions.

  • Sinclair ZX Spectrum
  • BASIC

The body is a short history of places the head has visited. Add three cells behind it, and a corner leaves a bend in that history.

Replace lines 110, 170, 280, 400, 3040, 4050, 7000.

Add lines 100, 120, 300, 310, 320, 340, 390, 1050, 3500, 3510, 3530, 3550, 7250.

step-01-edits.bas
 100 DIM a(4): DIM b(4)
 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: NEXT j
 170 IF k$="r" OR k$="R" THEN GO TO 100
 280 LET nr=a(h)+dr: LET nx=b(h)+dc
 300 LET grow=0
 310 GO SUB 3500: IF hit=1 THEN LET e$="You caught your tail!": GO TO 4000
 320 PRINT AT a(h)+3,b(h)+3; INK 5;CHR$ 149
 340 PRINT AT a(t)+3,b(t)+3;" "
 390 FOR j=1 TO 3: LET a(j)=a(j+1): LET b(j)=b(j+1): NEXT j
 400 LET a(h)=nr: LET b(h)=nx: LET steps=steps+1
1050 FOR j=1 TO 4: PRINT AT a(j)+3,b(j)+3; INK 5;CHR$ 149: NEXT j
3040 PRINT AT a(h)+3,b(h)+3; INK 7;CHR$ z
3500 LET hit=0
3510 FOR j=2 TO n
3530 IF a(j)=nr AND b(j)=nx THEN LET hit=1
3550 NEXT j: RETURN
4050 IF k$="r" OR k$="R" THEN GO TO 100
7000 RESTORE 7200: FOR j=0 TO 47: READ v: POKE USR "a"+j,v: NEXT j: RETURN
7250 DATA 0,60,126,126,126,126,60,0

RUN the changed program.

Complete source at this checkpoint
step-01.bas
  10 GO SUB 7000
 100 DIM a(4): DIM b(4)
 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: NEXT j
 130 GO SUB 1000
 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=0
 310 GO SUB 3500: IF hit=1 THEN LET e$="You caught your tail!": GO TO 4000
 320 PRINT AT a(h)+3,b(h)+3; INK 5;CHR$ 149
 340 PRINT AT a(t)+3,b(t)+3;" "
 390 FOR j=1 TO 3: LET a(j)=a(j+1): LET b(j)=b(j+1): NEXT j
 400 LET a(h)=nr: LET b(h)=nx: LET steps=steps+1
 410 GO SUB 3000
 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
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
3500 LET hit=0
3510 FOR j=2 TO n
3530 IF a(j)=nr AND b(j)=nx THEN LET hit=1
3550 NEXT j: 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
7000 RESTORE 7200: FOR j=0 TO 47: 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
9000 PAPER 0: INK 7: PRINT AT 21,0;"Finished. RUN to try again.     ";: STOP

Keep positions in order

a(1) and b(1) form the tail’s row and column. Slots 2 and 3 hold the middle cells. Slot 4 holds the head. DIM a(4) and DIM b(4) create two numeric arrays with four positions each. The arrays work as a pair: changing a row without its matching column would describe a different square.

The starting positions are (8,6), (8,7), (8,8), (8,9). After a step right they should be (8,7), (8,8), (8,9), (8,10). Save this idea before reading the copying loop: discard the oldest position and append one new position.

Line 390 copies slot 2 into 1, then 3 into 2, then 4 into 3. Line 400 writes the new head into slot 4. In this version t=1 and h=4 remain fixed. n=4 records the number of live cells. grow is always zero for now.

The new body graphic, code 149, uses row bytes 0,60,126,126,126,126,60,0. Its blank corners and full middle distinguish it from the face. The old head becomes a body cell, the departing tail is erased, and the new head is drawn. The middle cells already look right.

Check the proposed square

The routine at 3500 scans slots 2 through n, setting hit=1 if any row/column pair equals the candidate. It skips slot 1 because the tail is leaving on this move. A candidate outside the arena was already rejected before this scan.

Only after the tests pass do we erase or copy anything. The picture reports the coordinates; its colours never decide collision.

Why not copy slot 4 into 3 first, then slot 3 into 2?

Show the explanation

That second copy would read the new value of slot 3, losing its original position. Copy towards lower indices in ascending order so each source is read before it is overwritten.

From the starting position, turn down, left, then up on consecutive moves. The head can enter the starting tail square because the tail has already advanced. Check that four distinct cells remain, then retry. A bend that stretches or duplicates the body usually points to copying order or a mismatched row and column.

Sources

Steven Vickers, edited by Robin Bradbeer, ZX Spectrum BASIC Programming, second edition (Sinclair Research, 1983), 4 (loops) and 12 (arrays).

Run it here

This unit's program, built for you.

Program
step-01.tap
Machine
ZX Spectrum 48K (PAL)

Download step-01.tap