This program implements a two-dimensional maze-like movement game where the player navigates a character around a grid bounded by asterisk walls. Player position is controlled by keys 5, 6, 7, and 8 (the standard ZX directional keys), and the program tracks a score countdown from a starting value derived from CODE “%£” (the pound sign character code). A randomly appearing ghost character threatens the player, and boundary detection ends the game if the player hits the edges of the play area. All coordinate limits and initial positions are derived from character CODE values rather than literal numbers, saving memory and providing a degree of platform-adaptive positioning.
Program Analysis
Program Structure
The program is organised into four logical phases:
- Initialisation (lines 10–50): All key constants are derived from
CODEof specific characters rather than hard-coded literals. - Screen draw (lines 60–100): A bordered play field of asterisks is printed, with a title banner.
- Game loop (lines 110–200): A
FORloop counts down the score; inside it, player input is read, the player sprite is moved, boundary and goal checks are made, and a ghost is randomly placed. - End states (lines 210–250): “TIMES UP”,
STOP,CLEAR,SAVE, andRUNprovide restart infrastructure.
Character-Code Constants
Rather than embedding raw numbers, the program derives all key values from CODE of printable characters. This is a common memory-saving idiom on Sinclair machines where short expressions can replace longer literal strings in tokenised BASIC.
| Variable | Expression | Resolved value | Role |
|---|---|---|---|
L | CODE " " | 32 | Space character code; used as a general-purpose constant (column 32, loop start, edge detection) |
A, B, M | CODE "▘" (block graphic char) | 130 | Initial player row/column and step size — but see anomaly note below |
I | CODE "(" | 40 | Right boundary column |
| Loop end/ghost range | CODE "%£" (inverse £) | 96 | Score countdown start and ghost random range |
| Loop bound line 70 | CODE "\~~" | Approximately 14 | Number of rows to draw wall lines |
| Bottom edge | CODE ":" | 58 | Lower boundary row for kill detection |
Note: A and B are initialised to CODE "▘" (130) which far exceeds the ZX81’s screen coordinate space (rows 0–21, columns 0–31). This means the player sprite is placed off-screen at the start, which is a likely bug — the player’s initial position should probably be a small on-screen coordinate.
Key Input and Movement
Movement uses the standard five-key layout. Lines 120–130 update player coordinates:
INKEY$="6"increments rowA(down)INKEY$="7"decrements rowA(up)INKEY$="8"increments columnB(right)INKEY$="5"decrements columnB(left)
The player sprite ("C") is printed at position AT A,B and then erased with a space on the next iteration (line 160), implementing basic sprite flicker movement without any machine code.
Game Mechanics
The score countdown runs via FOR F=CODE "%£" TO L STEP -M (line 110), decrementing from 96 toward 32 with a step of -M (which equals 130, making the step far larger than the range — the loop will execute only once or not at all as intended). This is another consequence of the off-screen initial value of M.
Boundary detection (line 170) kills the player if A=L (row 32), A=CODE ":" (row 58), B=L (column 32), or B=I (column 40). These bounds seem plausible for a sub-region of the display but depend on the player actually reaching on-screen coordinates.
The ghost (line 190–199) is placed when E=A and B<A, where E is a random integer in 0..95. The condition B<A acts as a proximity guard.
A goal condition on line 155 checks A=M AND B=I-M, printing a score if the player reaches a target cell.
Notable Techniques and Anomalies
- The use of
W(which is never initialised) inPRINTstatements at lines 155, 170, and 190 will print a default value of 0, but suggestsWwas intended as a lives counter that was never fully implemented. - Lines 230–250 (
CLEAR,SAVE,RUN) are unreachable during normal execution due toSTOPat line 220, but provide a manual-reset / save block that can be reached by editing the flow. - The score display label
"ZX LIVES"and kill message"ZX KILLED"appear to be formatting strings whereZXis used as a separator or newline substitute — on ZX81 BASIC, these would print as literal text without special meaning. - The play field is drawn using inverse-video block graphic characters mixed with asterisks, creating a bordered arena purely through
PRINTstatements withTABpositioning.
Content
Source Code
10 LET L=CODE " "
20 LET A=CODE "\' "
30 LET B=A
40 LET M=A
50 LET I=CODE "("
60 PRINT "% % % % % % % % % % % % % % % % % ";TAB L;"% \@@***\@@***\@@***\@@$% "
70 FOR G=L TO CODE "\~~"
80 PRINT "% *\@@*\@@*\@@*\@@*\@@*\@@*\@@*% "
90 NEXT G
100 PRINT "% ***\@@***\@@***\@@***% ";TAB L;"% % % % % % %Z%X%-%M%A%N% % % % % "
110 FOR F=CODE "%£" TO L STEP -M
120 LET A=A+(INKEY$="6")-(INKEY$="7")
130 LET B=B+(INKEY$="8")-(INKEY$="5")
140 PRINT AT A,B;"C"
150 IF A=M AND B=I-M THEN PRINT "SCORE ";F;"ZX LIVES";W
160 PRINT AT A,B;" "
170 IF A=L OR A=CODE ":" OR B=L OR B=I THEN PRINT "ZX KILLED";W
180 LET E=INT (RND*CODE "%£")
190 IF E=A AND B<A THEN PRINT AT A,B;"%G";TAB L;"GHOST GOTCHA";W
200 NEXT F
210 PRINT "TIMES UP"
220 STOP
230 CLEAR
240 SAVE "1031%9"
250 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
