FIRE is a maze-building survival game where the player navigates a firefighter (“+”) around a grid while fire (“E” characters, displayed in magenta on red) spreads randomly and an oxygen meter counts down. The 21×31 string array `a$` serves as a collision map, tracking which cells are blocked by fire (represented internally as the block graphic “█”). Each move, one of four adjacent cells is randomly selected via a computed GO SUB (lines 190–220) to receive a new fire tile, gradually surrounding the player. The oxygen display uses PAPER and FLASH attributes triggered by the expression `(e<20)` to create a visual warning when oxygen drops below 20 units.
Program Structure
The program is organized into a main game loop with an initialization subroutine and four fire-spreading subroutines:
- Lines 5–10: Title REM and global initialization (colors, variables, call to setup at line 1000).
- Line 20: Per-level reset — clears the collision array
a$, resets position, increments levelr, replenishes oxygene, and places a new target at random coordinates (m,n). - Lines 30–40: Display pass — prints the HUD (score, oxygen, level) and draws the target “E” tile four times for emphasis, then erases the player’s old position.
- Lines 50–180: Main game loop — reads input, moves the player, checks win/lose conditions, decrements oxygen, then calls a random fire-spread subroutine before looping back to line 30.
- Lines 190–220: Fire-spread subroutines, one per cardinal direction, each marking a cell in
a$and printing a colored block character. - Lines 1000–1060: Setup subroutine that defines the target character
b$as “E”.
Collision Detection via String Array
The 21×31 string array a$(21,31) acts as a 2D collision map. Fire-spread subroutines write the block graphic "█" into the relevant cell, and movement checks (lines 60–90) test adjacent cells in a$ before allowing motion. This avoids any need for SCREEN$ reads and is efficient for a BASIC collision system.
Computed GO SUB
Line 170 picks a random direction index rl from 1 to 4, and line 180 dispatches with GO SUB (rl*10)+180, targeting lines 190, 200, 210, or 220. This is a compact dispatch table idiom that avoids a chain of IF statements.
Key Variables
| Variable | Role |
|---|---|
x, y | Player row and column |
e | Oxygen level (starts at 50, +25 per level) |
r | Level counter |
s | Score (100 per target found, +1 per move) |
m, n | Column and row of the target tile |
rl | Random direction index (1–4) |
a$ | 21×31 collision map string array |
b$ | Target character (“E”), set in the setup subroutine |
HUD and Attribute Tricks
Line 30 uses the Boolean expression (e<20), which evaluates to 1 (true) or 0 (false), directly inside PAPER and FLASH to activate a red flashing oxygen warning without any IF statement. PAPER (e<20)*2 gives PAPER 2 (red) when oxygen is critical, and FLASH (e<20) enables flashing simultaneously.
Fire Spread Subroutines
Lines 190–220 each handle one direction. They write into a$, emit a short BEEP, and print a block graphic in a different INK color per direction (cyan, green, red, magenta), creating a colorful fire effect. No bounds checking is performed before writing adjacent cells, which can cause an index-out-of-range error if the player is at the edge of the screen (row 0, row 20, column 0, or column 30) when a fire tile is placed adjacent to them.
Trapping Detection
Line 130 checks all four immediate neighbors of the player in a$ for the fire block character. If all four are blocked, the game declares the player trapped and stops. This is a simple but effective dead-end detection that matches the game’s stated lose condition.
Bugs and Anomalies
- The collision array
a$is declared asDIM a$(21,31)inside line 20, which is inside the main game loop.DIMis legal here and reinitializes the array each level, but it is unusual placement. - The fire-spread subroutines (lines 190–220) do not guard against out-of-bounds array indices. If
xis 1, accessinga$(x-1,y)(row 0) will cause an error, and similarly for the other boundaries. - Line 40 draws the target tile four times with a short delay loop between each draw (
FOR a=1 TO 3: NEXT a), but the practical visual effect is negligible at normal Spectrum speeds — it appears to be vestigial animation code. - Line 180 uses
GO TO 30immediately after theGO SUBdispatch, so it acts as a fall-through back to the display loop rather than a true subroutine call structure; the RETURN in each fire subroutine correctly returns to line 180, which then immediately jumps to 30. - The setup subroutine at line 1000 defines
b$="E"but spans from 1000 to 1060 with only a RETURN at 1060, leaving lines 1010–1059 undefined. This is harmless but wastes line-number space.
Source Code
5 REM "FIRE"
10 INK 7: PAPER 0: BORDER 0: CLS : GO SUB 1000: LET e=50: LET r=0: LET s=0
20 DIM a$(21,31): CLS : LET c=0: LET r=r+1: LET x=10: LET y=15: LET e=e+25: LET m=INT (RND*28)+2: LET n=INT (RND*18)+2
30 PRINT AT x,y; INK 5;"+";AT 0,0; INK 7;"SCORE="; PAPER (e<20)*2; FLASH (e<20);" OXYGEN=";e; PAPER 0; FLASH 0;" level=";r;" "
40 FOR b=1 TO 4: LET a$(n,m)=b$: PRINT AT n,m; INK 5; PAPER 1;b$: FOR a=1 TO 3: NEXT a: NEXT b: PRINT AT x,y;" "
50 LET f$=INKEY$
60 IF a$(x,y-1)<>"█" AND f$="5" AND y>2 THEN LET y=y-1
70 IF a$(x,y+1)<>"█" AND f$="8" AND y<39 THEN LET y=y+1
80 IF a$(x+1,y)<>"█" AND f$="6" AND x<20 THEN LET x=x+1
90 IF a$(x-1,y)<>"█" AND f$="7" AND x>2 THEN LET x=x-1
100 IF n=x AND m=y THEN LET s=s+100: PRINT AT 21,0;"WELL DONE !!": FOR m=10 TO 40: BEEP .01,m: NEXT m: GO TO 20
110 IF e<=0 THEN PRINT AT 21,0;"OUT OF OXYGEN : GAMEOVER": STOP
120 LET e=e-1
130 IF a$(x-1,y)="█" AND a$(x+1,y)="█" AND a$(x,y-1)="█" AND a$(x,y+1)="█" THEN PRINT AT 21,0;"YOU ARE TRAPPED : GAMEOVER": STOP
140 IF f$="" THEN GO TO 30
150 LET s=s+1
160 LET rl=INT (RND*4)+1
170 GO SUB (rl*10)+180
180 GO TO 30
190 LET a$(x-1,y)="█": BEEP .01,40: PRINT AT x-1,y; INK 6;"█": RETURN
200 LET a$(x+1,y)="█": BEEP .01,40: PRINT AT x+1,y; INK 3;"█": RETURN
210 LET a$(x,y-1)="█": BEEP .01,42: PRINT AT x,y-1; INK 4;"█": RETURN
220 LET a$(x,y+1)="█": BEEP .01,43: PRINT AT x,y+1; INK 5;"█": RETURN
1000 LET b$="E"
1060 RETURN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
