--- title: "Land-Mine" id: 57617 type: "computer_media" slug: "land-mine" url: "http://localhost/computer_media/land-mine/" markdown_url: "http://localhost/computer_media/land-mine.md" published_at: "2024-10-06T00:34:13+00:00" modified_at: "2026-04-03T07:58:14+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/land-mine.png" excerpt: "Navigate a hidden minefield one step at a time, balancing risk and reward across 200 cells — but one wrong move triggers a flashing BOMB screen." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" indiv: - name: "Gene G. Buza" slug: "gene-g-buza" taxonomy: "indiv" url: "http://localhost/indiv/gene-g-buza/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_contents: - id: 56725 title: "Synchro-Sette March 1984" type: "computer_media" url: "http://localhost/computer_media/synchro-sette-march-1984/" media_type: "Program" programmers: - name: "Gene G. Buza" slug: "gene-g-buza" taxonomy: "indiv" url: "http://localhost/indiv/gene-g-buza/" mediadate: "March 1984" images: - url: "http://localhost/wp-content/uploads/2024/10/land-mine.png" media_type_tags: "Game" --- 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:**`FAST` at line 1 speeds up array initialization and grid drawing; `SLOW` at 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 — `STOP` halts execution, `LET SS=0` resets the high score, and `SAVE "LAND MINE"` preserves the program with `SS` at zero, after which `GOTO 1` restarts. - **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. ## 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 9996 STOP 9997 LET SS=0 9998 SAVE "LAND MIN%E" 9999 GOTO 1 ```