--- title: "Treasure Chase" id: 57536 type: "computer_media" slug: "treasure-chase" url: "http://localhost/computer_media/treasure-chase/" markdown_url: "http://localhost/computer_media/treasure-chase.md" published_at: "2024-10-05T21:37:53+00:00" modified_at: "2026-03-30T21:17:20+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/291_TC.png" excerpt: "A procedurally generated maze-chase game where you collect coins while a relentless pursuer closes in one step at a time — can you beat your high score?" 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/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_contents: - id: 56737 title: "Timex Sinclair Public Domain Library Tape 1006" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1006/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/10/291_TC.png" media_type_tags: "Game, Software" --- Treasure Chase is a cat-and-mouse game in which the player moves a treasure token around a grid while a pursuing “hound” automatically closes in. The 22×32 playing field is populated procedurally: each cell has a 5% chance of becoming a wall (value 2, displayed as inverse asterisk) and a 10% chance of becoming a coin (value 1, displayed as inverse period), stored in a two-dimensional array H(22,32). The player scores 10 points for landing on a wall cell and 1 point for a coin cell, with both clearing on collection; a running high score is preserved across rounds in C1. Movement uses the classic ZX81 key layout (5/8 for left/right, 6/7 for up/down), and pressing 0 teleports the treasure to a random position, while the hound steps one cell closer each tick using simple Chebyshev-style tracking logic. *** ## Program Analysis ### Program Structure The program is divided into four logical phases: 1. **Initialisation (lines 1–13):** Resets player position, places the hound randomly, zeroes the score, and enters FAST mode. 2. **Map generation (lines 20–61):** Fills the 22×32 grid with walls and coins using probabilistic RND checks, storing terrain in array `H` and printing inverse characters. 3. **Game loop (lines 65–160):** Renders player and hound, updates scores, advances the hound one step toward the player, reads keys to move the treasure, clamps positions, and checks for capture. 4. **End / restart (lines 200–240):** Prints a capture message, prompts to play again, and either stops or jumps back to line 5 (preserving high score in `C1`). ### Display and Character Encoding All interactive characters are rendered as ZX81 inverse video. The player token is `%0` (inverse 0), the hound is `%A` (inverse A), walls are `%*` (inverse asterisk), and coins are `%.` (inverse period). The status line at row 0 spells out `%Y%O%U%R` and `%H%I%G%H% %S%C%O%R%E` in inverse characters to give a header-bar effect. Erasing a character is done by printing `"% "` (inverse space). ### Terrain Array and 1-Based Indexing The terrain array `H(22,32)` uses 1-based indices in ZX81 BASIC, so screen positions `(I,J)` — which run 0–21 and 0–31 — are stored as `H(I+1,J+1)`. Cell values encode terrain type: | Value | Meaning | Score | Display | | --- | --- | --- | --- | | 0 | Empty | 0 | inverse space | | 1 | Coin | +1 | inverse period | | 2 | Wall | +10 | inverse asterisk | After the player’s treasure lands on a cell, its value is read, the score updated, and the cell zeroed — preventing double-counting on subsequent passes. ### Hound (Pursuer) AI Lines 81–87 implement simple axis-aligned stepping: the hound’s target coordinates `(X1,Y1)` are incremented or decremented independently on each axis toward the treasure `(A,B)`. This is equivalent to Chebyshev movement — the hound can close diagonally one step per frame and will inevitably catch the treasure on an open field. ### Player Input and Movement Key mapping follows the standard ZX81 numeric-key convention: - `5` — move left (`B=B-1`) - `8` — move right (`B=B+1`) - `6` — move down (`A=A+1`) - `7` — move up (`A=A-1`) - `0` — teleport to random position Position is clamped at lines 132–135 to keep the treasure within the visible grid. There is no boundary check on the hound’s coordinates `X` and `Y`, though in practice the hound is clamped indirectly because it always moves toward a clamped target. ### High Score Persistence The variable `C1` is initialised only once at line 1 and is not reset when the player restarts at line 5. This means the high score accumulates across games within a single session. Line 72 updates `C1` only when the current score `C` exceeds it, providing correct high-score semantics. ### Notable Bugs and Anomalies - **INKEY$ read multiple times per loop:** Lines 89–120 each call `INKEY$` independently. On the ZX81, `INKEY$` is re-evaluated on every reference, so a key held down can trigger multiple branches simultaneously (e.g., both the erase at line 89 and a movement at a later line). - **Row 0 terrain exclusion:** Line 31 skips wall/coin placement when `I=0` or `J=0`, but the condition only catches the first row and first column. This leaves row 0 clear for the score display but means column 0 is also always empty. - **PAUSE 9000:** Line 80 pauses for approximately 9000 display frames before processing input. On the unexpanded ZX81 this is very long; this is the primary pacing mechanism but also means input is only sampled after the pause expires, making the game sluggish. - **Lines 220–240 (CLEAR / SAVE / RUN)** are unreachable during normal gameplay and appear to be a loader/saver block executed manually or at load time. - **Hound erased by INKEY$ check:** Line 89 erases the hound’s current cell (`AT A,B`) if any key is pressed, before movement keys are checked — this means the hound is temporarily invisible for one frame whenever a key is held. ### FAST/SLOW Mode Usage `FAST` is entered at line 13 before the map-drawing loop to suppress the display interrupt and speed up the 704-cell fill operation. `SLOW` is restored at line 61 before the game loop begins, re-enabling the display so the player can see the action. ## Source Code ``` 1 LET C1=0 2 REM TREASURE CHASE 5 LET X=0 6 LET Y=16 7 LET Y1=Y 8 LET X1=X 9 LET A=INT (RND*22) 10 LET B=INT (RND*32) 12 LET C=0 13 FAST 20 DIM H(22,32) 26 FOR I=0 TO 21 28 FOR J=0 TO 31 30 PRINT AT I,J;"% " 31 IF I=0 OR J=0 THEN GOTO 50 32 IF NOT RND<.05 THEN GOTO 40 34 LET H(I+1,J+1)=2 36 PRINT AT I,J;"%*" 40 IF NOT RND<.1 THEN GOTO 50 42 LET H(I+1,J+1)=1 44 PRINT AT I,J;"%." 50 NEXT J 60 NEXT I 61 SLOW 65 PRINT AT X,Y;"%0" 66 PRINT AT A,B;"%A" 67 IF H(A+1,B+1)=2 THEN LET C=C+10 68 IF H(A+1,B+1)=2 THEN LET H(A+1,B+1)=0 69 IF H(A+1,B+1)=1 THEN LET C=C+1 70 IF H(A+1,B+1)=1 THEN LET H(A+1,B+1)=0 72 IF C>C1 THEN LET C1=C 73 PRINT AT 0,0;"%Y%O%U%R";C;AT 0,9;"%H%I%G%H% %S%C%O%R%E";AT 0,21;C1 80 PAUSE 9000 81 IF A>X THEN LET X1=X+1 82 IF AY THEN LET Y1=Y+1 84 IF B21 THEN LET A=21 133 IF A<1 THEN LET A=1 134 IF B>31 THEN LET B=31 135 IF B<0 THEN LET B=0 140 IF X=A AND Y=B THEN GOTO 200 160 GOTO 65 200 PRINT AT 10,10;"**GOT YOU**" 202 PRINT AT A,B;"X" 205 PRINT AT 20,2;"PLAY AGAIN ,INPUT Y OR N" 207 INPUT G$ 208 IF G$="N" THEN STOP 210 GOTO 5 220 CLEAR 230 SAVE "1029%1" 240 RUN ```