Land Mine is a turn-based strategy game in which the player navigates a 10×20 grid of hidden score values, choosing moves of 1–9 steps at a time to accumulate points while avoiding mines. The 200-cell array A() is populated with random integers in the range −10 to +10, then nine cells are zeroed to act as “booby traps.” The player’s position is tracked as a linear index into the array, displayed as an asterisk (inverse video) on the grid using the formula row = INT(J/20), column = J MOD 20. A running average score per move (S/M) is compared against a high-score variable SS, and a congratulations message is shown if the player matches or beats it.
Program Analysis
Program Structure
The program is organized into a main initialization block, several subroutines, and a game loop. Lines 0–19 handle setup; line 40 launches the game loop via GOSUB 200, which is re-entered repeatedly via GOTO 200 at line 280. Subroutine 100 draws the grid header and row labels; subroutine 200 is the main turn handler; subroutine 300 updates the player marker on the grid; subroutine 800 draws the move counter sidebar. Lines 560–582 handle the BOMB (mine) event, and lines 519–540 handle the booby-trap (zero-cell) penalty.
| Line Range | Purpose |
|---|---|
| 0–5 | Title display, variable initialization, array allocation |
| 12–19 | Draw border graphics, call grid subroutine, populate A() |
| 20–24 | Zero out nine random cells as booby traps |
| 35–50 | Switch to SLOW mode, enter game loop |
| 100–150 | Subroutine: draw column numbers and row labels |
| 200–280 | Subroutine: main turn — input, move, score update |
| 300–333 | Subroutine: redraw grid and place player marker |
| 500–540 | Booby-trap handler (reset position, warn player) |
| 560–582 | BOMB animation and end-of-game branch |
| 590–700 | Score averaging, high-score check, end screen |
| 800–810 | Subroutine: draw “MOVE N” sidebar |
| 9996–9999 | High-score save/load scaffold |
Game Mechanics
The game board is a linear array A(200) whose cells hold values from −10 to +10, generated by INT(RND*20)+1-10. Nine cells are subsequently set to 0 at random positions (lines 20–24) to serve as booby traps. The player’s position J advances by 1–9 cells per turn; reaching a cell with value 0 resets position to the start (line 519), while a cell with value 44 — which can never occur under normal initialization — is used as a mine trigger sentinel. In practice the mine trigger at line 265 (IF A(J)=44) is unreachable since values are bounded to −10…+10 and zeroed cells are the only special case; the intended mine event is therefore only triggered by falling off the end of the array at line 260 (IF J>=200 THEN GOTO 583), but line 583 does not exist — control falls through to line 590 instead.
Grid Display and Position Tracking
The grid is drawn at screen rows 3–12, columns 4–24, giving a 10-row × 20-column visual map of the 200-element array. The player marker (inverse asterisk %*) is placed using the conversion at lines 320–330:
K = INT(J/20)— grid row (0-based)L = J-(K*20)+1— grid column (1-based)PRINT AT K+3, L+4; "%*"— offset to screen coordinates
Row labels at lines 110–130 use CHR$(163+I), which on the ZX81 produces graphics characters for rows 3–12, giving a simple visual row indicator along the left edge of the grid.
Move Counter Sidebar
Subroutine 800 prints the word “MOVE” vertically (one letter per row at column 30, rows 3–6) and “NO” at rows 8–9, then prints the move count M at row 11. Lines 806–807 select column 29 or 30 depending on whether M is greater or less than 99, providing crude right-alignment. Note the condition uses M>99 and M<99, so the value 99 exactly prints at column 30, which is correct for a two-digit number, but the logic is slightly asymmetric.
Scoring and High Score
Score S accumulates the raw cell values (positive or negative). At game end, the average score per move SM = S/M is computed and compared to SS. SS is never initialized in the main game path — it is only set at line 9997 (LET SS=0), which is part of the save scaffold and not reached during normal play. This means SS will be undefined on first run, likely defaulting to 0, which could cause erratic high-score comparisons if SM is negative.
Notable Techniques and Idioms
- FAST/SLOW switching:
FASTat line 1 speeds up array initialization and grid drawing;SLOWat lines 35 and 140 restores display for interactive play. - Busy-wait input loop: Lines 220–230 poll
INKEY$continuously and validate the range “1”–”9″ before accepting input, a standard ZX81 input idiom. - BOMB flash animation: Lines 560–580 alternate between printing and immediately clearing inverse-video “BOMB” text in a loop of 25 iterations, creating a flicker effect.
- Save scaffold: Lines 9996–9999 are a developer utility —
STOPhalts execution,LET SS=0resets the high score, andSAVE "LAND MINE"preserves the program withSSat zero, after whichGOTO 1restarts. - Unreachable code: Lines 500 and 519–540 contain a dead branch — line 500 jumps directly to 560, bypassing the booby-trap reset logic at 519–540 entirely. The intended booby-trap path (zero-cell handling at line 266) calls
GOSUB 510, but line 510 does not exist, which would cause an error in practice.
Content
Source Code
0 % % % %L%A%N%D% %M%I%N%E% % % % % %W%R%I%T%T%E%N% % %B%Y% % % % % %G%E%N%E% %B%U%Z%A% % %
1 FAST
2 LET J=0
3 LET M=1
4 LET S=0
5 DIM A(200)
12 PRINT AT 15,0;"\:'\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\':\: ";AT 16,31;"\ :\:.\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\.:"
14 GOSUB 100
15 FOR I=1 TO 200
16 RAND
17 LET A(I)=(INT (RND*20)+1)-10
18 NEXT I
19 PRINT AT 0,0;"% %L%A%N%D% %M%I%N%E% "
20 FOR I=1 TO 9
23 LET A(INT (RND*100)+1)=0
24 NEXT I
31 PRINT AT 16,1;" "
35 SLOW
40 GOSUB 200
50 GOTO 141
100 PRINT AT 2,4;"% %0%1%2%3%4%5%6%7%8%9%0%1%2%3%4%5%6%7%8%9%0"
110 FOR I=3 TO 12
120 PRINT AT I,4;CHR$ (163+I);"%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%."
130 NEXT I
140 SLOW
150 RETURN
200 PRINT AT 16,1;" "
202 GOSUB 800
203 PRINT AT 16,2;"YOUR SCORE IS: ";S
205 GOSUB 300
210 PRINT AT 18,0;"WHAT IS YOUR MOVE? (1-9)"
220 LET R$=INKEY$
225 IF R$="" THEN GOTO 220
230 IF R$<"1" OR R$>"9" THEN GOTO 220
240 LET M=M+1
250 LET R=VAL R$
255 LET J=J+R
260 IF J>=200 THEN GOTO 583
261 LET S=S+A(J)
262 PRINT AT 8,1;" "
263 PRINT AT 8,1;(A(J))
265 IF A(J)=44 THEN GOTO 500
266 IF A(J)=0 THEN GOSUB 510
280 GOTO 200
300 GOSUB 100
320 LET K=INT (J/20)
325 LET L=J-(K*20)+1
330 PRINT AT K+3,L+4;"%*"
333 RETURN
500 GOTO 560
519 LET J=0
520 FOR I=1 TO 20
525 PRINT AT 21,0;" "
530 PRINT AT 21,0;"% %B%O%O%B%Y% %T%R%A%P% %-% %S%T%A%R%T% %A%G%A%I%N% "
535 NEXT I
537 PRINT AT 21,0;" "
540 RETURN
560 FOR I=1 TO 25
570 PRINT AT 20,0;"% % % % % % % % % % % % % %B%O%M%B% % % % % % % % % % % % % % % ";AT 20,0;" "
575 PRINT AT 21,0;"% % % % % % % % % % % % % %B%O%M%B% % % % % % % % % % % % % % % ";AT 21,0;" "
580 NEXT I
582 IF J<200 THEN GOTO 700
590 LET SM=S/M
600 IF SM>SS THEN LET SS=S/M
650 IF SM=SS THEN PRINT AT 2,0;"%C%O%N%G%R%A%D%U%L%A%T%I%O%N%S%,% %Y%O%U% %I%T% %N%O%W% %H%A%V%E%H%I%G%H% %S%C%O%R%E%."
700 PRINT AT 19,0;"%++%++ YOUR AVERAGE PER POINT SCORE IS: ";SM
760 PRINT AT 21,0;"PRESS ENTER FOR NEW GAME :::"
770 PAUSE 40000
780 CLS
790 GOTO 1
800 PRINT AT 3,30;"%M"
801 PRINT AT 4,30;"%O"
802 PRINT AT 5,30;"%V"
803 PRINT AT 6,30;"%E"
804 PRINT AT 8,30;"%N"
805 PRINT AT 9,30;"%O"
806 IF M>99 THEN PRINT AT 11,29;M
807 IF M<99 THEN PRINT AT 11,30;M
810 RETURN
\n9996 STOP
\n9997 LET SS=0
\n9998 SAVE "LAND MIN%E"
\n9999 GOTO 1
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
