Give the archive a visitor. The player proposes a neighbouring square; the map gets the final say.
Continue from Draw the archive. Replacing a numbered line means entering its complete new contents. Deleting line 20 removes the STOP that ended the drawing stage.
Delete line 20.
Replace lines 10, 1022, 1024.
Add lines 100, 140, 200, 210, 220, 250–350 in steps of ten, 370, 470, 1030, 1040, 2000, 2010, 2030, 2040, 2060, 2080, 8100, 8110, 9000.
Delete a line by entering its number alone and pressing Enter. Then enter the replacements and additions below.
10 GO SUB 7000: GO SUB 7100
100 LET x=3: LET y=16: LET steps=0
140 GO SUB 1000
200 LET k$=INKEY$
210 IF k$="q" OR k$="Q" THEN GO TO 9000
220 IF k$="r" OR k$="R" THEN GO SUB 8100: GO TO 100
250 LET k$=INKEY$
260 LET dx=0: LET dy=0
270 IF k$="i" OR k$="I" THEN LET dy=-1
280 IF k$="k" OR k$="K" THEN LET dy=1
290 IF k$="j" OR k$="J" THEN LET dx=-1
300 IF k$="l" OR k$="L" THEN LET dx=1
310 LET nx=x+dx: LET ny=y+dy
320 IF m$(ny,nx)=CHR$ 145 THEN GO TO 370
330 IF nx=x AND ny=y THEN GO TO 370
340 LET r=y: LET c=x: LET x=nx: LET y=ny: GO SUB 2000
350 LET steps=steps+1: LET r=y: LET c=x: GO SUB 2000
370 GO TO 470
470 GO TO 200
1022 LET r=3: LET c=27: GO SUB 2000
1024 LET r=y: LET c=x: GO SUB 2000
1030 PRINT AT 20,1;"I up J left K down L right"
1040 PRINT AT 21,1;"R retry Q quit";
2000 LET z$=" ": LET colour=7: LET shade=0
2010 IF m$(r,c)=CHR$ 145 THEN LET z$=CHR$ 145: LET colour=1
2030 IF r=3 AND c=27 THEN LET z$=CHR$ 146: LET colour=5
2040 IF r=16 AND c=3 THEN LET z$=CHR$ 147: LET colour=4
2060 IF r=y AND c=x THEN LET z$=CHR$ 144: LET colour=7
2080 PRINT AT r+1,c; PAPER shade; INK colour; BRIGHT 1;z$: RETURN
8100 IF INKEY$<>"" THEN GO TO 8100
8110 RETURN
9000 PAPER 0: INK 7: BRIGHT 0: PRINT AT 21,0;"Finished. RUN to try again. ";: STOPComplete program at this stage
10 GO SUB 7000: GO SUB 7100
100 LET x=3: LET y=16: LET steps=0
140 GO SUB 1000
200 LET k$=INKEY$
210 IF k$="q" OR k$="Q" THEN GO TO 9000
220 IF k$="r" OR k$="R" THEN GO SUB 8100: GO TO 100
250 LET k$=INKEY$
260 LET dx=0: LET dy=0
270 IF k$="i" OR k$="I" THEN LET dy=-1
280 IF k$="k" OR k$="K" THEN LET dy=1
290 IF k$="j" OR k$="J" THEN LET dx=-1
300 IF k$="l" OR k$="L" THEN LET dx=1
310 LET nx=x+dx: LET ny=y+dy
320 IF m$(ny,nx)=CHR$ 145 THEN GO TO 370
330 IF nx=x AND ny=y THEN GO TO 370
340 LET r=y: LET c=x: LET x=nx: LET y=ny: GO SUB 2000
350 LET steps=steps+1: LET r=y: LET c=x: GO SUB 2000
370 GO TO 470
470 GO TO 200
1000 BORDER 0: PAPER 0: INK 7: BRIGHT 0: CLS
1010 PRINT AT 0,1; INK 5; BRIGHT 1;"NIGHT PATROL";AT 0,20;"THE ARCHIVE"
1020 FOR r=1 TO 18: PRINT AT r+1,1; INK 1; BRIGHT 1;m$(r): NEXT r
1022 LET r=3: LET c=27: GO SUB 2000
1024 LET r=y: LET c=x: GO SUB 2000
1030 PRINT AT 20,1;"I up J left K down L right"
1040 PRINT AT 21,1;"R retry Q quit";
1050 RETURN
2000 LET z$=" ": LET colour=7: LET shade=0
2010 IF m$(r,c)=CHR$ 145 THEN LET z$=CHR$ 145: LET colour=1
2030 IF r=3 AND c=27 THEN LET z$=CHR$ 146: LET colour=5
2040 IF r=16 AND c=3 THEN LET z$=CHR$ 147: LET colour=4
2060 IF r=y AND c=x THEN LET z$=CHR$ 144: LET colour=7
2080 PRINT AT r+1,c; PAPER shade; INK colour; BRIGHT 1;z$: RETURN
7000 RESTORE 7500: FOR j=0 TO 31: READ a: POKE USR "a"+j,a: NEXT j: RETURN
7100 DIM m$(18,30): RESTORE 7200
7110 FOR r=1 TO 18: READ m$(r): FOR c=1 TO 30
7120 IF m$(r,c)="#" THEN LET m$(r,c)=CHR$ 145
7130 NEXT c: NEXT r: RETURN
7200 DATA "##############################"
7210 DATA "##############################"
7220 DATA "########### ############# ###"
7230 DATA "##### ####### # ###"
7240 DATA "##### ###"
7250 DATA "##### ###### # #####"
7260 DATA "###### ######### ##### ######"
7270 DATA "###### ############ ######"
7280 DATA "###### ############ ######"
7290 DATA "###### ############## ######"
7300 DATA "#### ################ ####"
7310 DATA "#### #### ########## ####"
7320 DATA "##### ####### #####"
7330 DATA "##### #####"
7340 DATA "##### ###### # #####"
7350 DATA "## ######### ############"
7360 DATA "##############################"
7370 DATA "##############################"
7500 DATA 24,24,0,60,90,24,36,66
7510 DATA 255,128,128,255,8,8,8,255
7520 DATA 126,66,90,66,90,66,126,0
7530 DATA 126,66,66,74,66,66,126,0
8100 IF INKEY$<>"" THEN GO TO 8100
8110 RETURN
9000 PAPER 0: INK 7: BRIGHT 0: PRINT AT 21,0;"Finished. RUN to try again. ";: STOPRUN. Hold I to go up, J left, K down and L right. Try uppercase letters too. R returns you to the entrance; Q ends the program. The file is scenery at this stage.
Propose, then accept
LET stores values. x and y remember the player position; dx and dy describe a possible change. INKEY$ reports a currently held key, or an empty string when there is none. Each pass clears both offsets before checking the key. An unrecognised key therefore means no movement.
| Key | dx | dy |
|---|---|---|
| I | 0 | −1 |
| J | −1 | 0 |
| K | 0 | 1 |
| L | 1 | 0 |
Line 310 calculates nx and ny, the proposed position. Line 320 checks m$(ny,nx). If it contains character 145, the program skips the move. The outside of this map is solid wall, so a player moving one square at a time cannot reach an out-of-range index. Opening a hole in that boundary would require an explicit bounds check.
Only an accepted move replaces x and y. Separating the proposal from the stored position means a rejected move needs no undo operation.
Restore what was underneath
The routine at 2000 draws one square, using r and c as its requested row and column. It starts with floor, then considers a wall, file, entrance and player. Later choices can replace earlier ones, so the player appears over an object while occupying its square.
Line 340 remembers the old square in r and c before changing x and y. Drawing that square now restores its underlying object. Line 350 draws the new player square. We do not clear and rebuild the whole archive for one footstep. steps counts accepted moves, although this version does not display it as a score.
Why would printing a blank space behind the player damage the entrance?
Show the explanation
The entrance is drawn over floor. A blank would erase its picture when the player moved away. Reconstructing the square from its position draws the entrance again.
Let go before retrying
A held movement key should repeat. A held R should make one fresh start. Line 220 calls 8100, which waits while INKEY$ is nonempty. Once you release the key, RETURN lets the program restart at 100. GO TO jumps without arranging a return; GO SUB remembers where to come back.
Try every direction, press against a wall, then release all keys. The player should stop. Walk over the entrance and away again: its symbol should survive. Hold R briefly and release it; you should get one reset, not a repeated redraw. If the program stops immediately after drawing, check that line 20 really was deleted.
Sources
Steven Vickers, edited by Robin Bradbeer, ZX Spectrum BASIC Programming, second edition (Sinclair Research, 1983), chapter 5, chapter 18.
Run it here
This unit's program, built for you.
- Program
- night-patrol.tap
- Machine
- ZX Spectrum 48K (PAL)