This is a city-bombing game in which the player controls a falling bomb across a procedurally generated cityscape, pressing NEWLINE to trigger an explosion before the bomb lands on a building. The city skyline is drawn using block graphics, with building heights randomised using RND across columns 0–31. Collision detection is performed by PEEKing the display file address, derived from system variables at addresses 16398 and 16399, to check whether the bomb character has landed on a solid cell (any non-NEWLINE, non-zero value). Scoring is calculated as H×31+X, rewarding the player for how far into the city they have progressed before crashing.
Program Analysis
Program Structure
The program is divided into four logical sections:
- Lines 10–30: Instructions prompt — checks if the player wants instructions by testing
CODE C$=62(the character>, meaning “skip instructions”). - Lines 40–230: Main game loop — draws the cityscape, animates the bomb across rows 1–19, and checks for a keypress or collision.
- Lines 500–570: Bomb drop sequence — draws an explosion column downward, clears the bomb, then re-enters the scan loop at line 170 (a non-existent line, which falls through to 180).
- Lines 700–730 / 800–890: Crash handler and instructions screen, plus a
SAVEblock at lines 870–890.
City Generation
The skyline is built in lines 50–90. For each column X from 0 to 31, a random height range starting somewhere in rows 11–21 up to row 19 is selected using INT(RND*11)+11. Each cell in that column is filled with the block graphic character \' (▘ followed by space), creating a ragged roofline. The city is drawn before the main loop begins and remains static throughout play.
Bomb Animation
The bomb character is defined in A$ at line 100 as ">=\.:\ '\:.", a string containing block graphic characters to visually represent a falling object. The blank string C$ (five spaces) defined at line 110 is used to erase the bomb at each position. The outer loop (H, step 2) iterates over even rows 1–19; the inner loop (X) sweeps each column left to right, printing and then erasing the bomb character.
Display-File Collision Detection
Lines 150–160 implement collision detection by directly reading the ZX81 display file. The expression PEEK 16398 + 1 + PEEK 16399 * 256 computes the start address of the display file from system variables (D_FILE is stored at addresses 16398–16399 on the ZX81), then adds 1 to skip the leading NEWLINE. The value fetched is checked: if it is not 118 (the ZX81 NEWLINE/halt character) and is greater than 0, the bomb has hit a building and execution jumps to the crash handler at line 700. Note that this peek address is fixed and does not track the current bomb position (H, X), so the collision check is reading a constant memory location rather than the cell under the bomb — this is a bug in the collision logic.
Keypress and Explosion
Line 180 polls INKEY$; any keypress triggers the explosion subroutine at line 500. The explosion loop (lines 500–540) fills each row from H+1 to 19 in column X first with \' (▘) and then immediately overwrites with \@@ — two @ characters — suggesting a flash or rubble effect. After the explosion, X is slightly randomised at line 560 (INT(RND*2)+X, shifting 0 or 1 columns), and the game jumps to line 170 (non-existent), which causes execution to resume at line 180, effectively resuming the inner scan loop mid-row.
Scoring
On a crash, the score is printed as H*31+X, approximating a linearised screen position. Higher values indicate the bomb travelled further across the city before impact.
Notable Techniques and Anomalies
PRINT AT H,X,;at line 140 uses a trailing comma before the semicolon — on the ZX81 this is a syntax oddity but accepted; the semicolon suppresses the trailing newline.- The
GOTO 170at line 570 targets a non-existent line, intentionally falling through to line 180 to re-enter the keypress-check mid-scan. - The display-file PEEK at line 150 does not correctly offset by the current row and column of the bomb, making collision detection unreliable — it always reads near the start of the display file regardless of bomb position.
- Lines 870–890 contain a
CLEAR,SAVE, andRUNsequence that is unreachable during normal play, intended for saving the program to tape. - The instructions check at line 30 uses
CODE C$=62rather than comparing the string directly, testing for the>character to skip to line 800.
Variable Summary
| Variable | Purpose |
|---|---|
A$ | Bomb graphic string |
C$ | Dual-use: input string and blank eraser (5 spaces) |
H | Current row of bomb (outer loop, step 2) |
X | Current column of bomb (inner loop) |
Y | Loop variable for city drawing and explosion |
F | Value fetched from display file for collision check |
Content
Source Code
10 PRINT "DO YOU WISH INSTRUCTINS"
20 INPUT C$
30 IF CODE C$=62 THEN GOTO 800
40 CLS
50 FOR X=0 TO 31
60 FOR Y=INT (RND*11)+11 TO 19
70 PRINT AT Y,X;"\' ";
80 NEXT Y
90 NEXT X
100 LET A$=">=\.:\ '\:."
110 LET C$=" "
120 FOR H=1 TO 20 STEP 2
130 FOR X=0 TO 31
140 PRINT AT H,X,;A$;
150 LET F=PEEK (PEEK 16398+1+PEEK 16399*256)
160 IF NOT F=118 AND F>0 THEN GOTO 700
180 IF INKEY$<>"" THEN GOTO 500
190 PRINT AT H,X,C$;
200 NEXT X
210 NEXT H
220 PRINT AT 0,10;"WELL DONE"
230 STOP
500 FOR Y=H+1 TO 19
510 PRINT AT Y,X;"\' ";
530 PRINT AT Y,X;"\@@";
540 NEXT Y
550 PRINT AT H,X;C$
560 LET X=INT ((RND*2)+X)
570 GOTO 170
700 PRINT AT 0,10;">=YOU CRASHED<=",H*31+X;"POINTS","ANOTHER GO?(Y)"
710 INPUT C$
720 IF C$="Y" THEN GOTO 10
730 STOP
800 PRINT "CITY BOMB BY S.C.ADAMS"
810 PRINT "----------------------"
820 PRINT "YOU MUST BOMB AWAY THE CITY"
830 PRINT "BY PRESSING THE NEW LINE"
840 PRINT "KEY BEFORE LANDING"
850 INPUT C$
860 GOTO 40
870 CLEAR
880 SAVE "1031%2"
890 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
