Explosion is a two-player strategy board game where a human competes against the computer on a 3×4 or 4×4 grid, placing counters in cells that explode and distribute to neighbors when they exceed the cell’s capacity. The grid is drawn using PLOT and DRAW commands with INK 2 (red) for the border lines, and player pieces are color-coded using PAPER attributes stored in the array z(). The computer’s AI evaluates all possible moves using a scoring subroutine (line 5000) that rewards threatening positions and selects the move with the lowest score, with tie-breaking by RND. A separately LOADed machine code block (referenced by the CODE load at line 44 and saved at line 9998 as 3200 bytes from address 28000) handles character set modification, with POKEs at 23606/23607 pointing to an alternate character set. The program includes explicit compatibility notes distinguishing behavior between two different hardware configurations in the instructions at lines 34–38.
Program Structure
The program is organized into a main game loop and a set of numbered subroutine blocks. Control begins at line 8000, which initializes arrays and prompts for board size and starting player, then alternates between the human’s turn (lines 8600–8730) and the computer’s turn (lines 8800–9000). Key subroutine groups are:
- Lines 100–210: Main explosion propagation loop — iterates the board until no further explosions occur.
- Lines 500–520: Cell capacity calculator — returns
a= 2 for corners, 3 for edges, 4 for center cells. - Lines 1000–1190: Explosion distributor — adds 1 to each orthogonal neighbor and resets the exploding cell to 0.
- Lines 1500–1530: Scoring update — multiplies board values by
t(±1) into the cost arrayc. - Lines 2000–2030: Restore board from
ctob. - Lines 2300–2350: Win-detection — checks whether any cell in array
ehas fewer than 3 explosions; if all have ≥ 3, the current player has won. - Lines 3000–3030 / 4000–4030: Copy
f→candc→frespectively (board state save/restore for AI lookahead). - Lines 5000–5180: AI evaluation — scores the board state for the computer’s move selection.
- Lines 7000–7030: Zeroes the dirty-flag arrays
dande. - Lines 8000–8090: Initialization — CLears screen, DIMensions arrays, sets display constants.
- Lines 9498–9530: Win/lose display and replay prompt.
- Lines 9900–9910: Single-cell display update using
PAPER z(p)attribute. - Lines 9996–9999: Utility lines — restore character set POKEs, save machine code, save the BASIC program with autostart.
Machine Code and Character Set
Line 4 POKEs addresses 23606 and 23607 (the system variable CHARS) to point to a custom character set at address 28000+256 (i.e., base 28000, offset by 256 so that character 32 maps to address 28256). A 3200-byte machine code/data block is saved separately via SAVE "EXP" CODE 28000,3200 at line 9998 and loaded at line 44 with LOAD "EXP" CODE. Line 9996 restores CHARS to its default value (23607=60, giving base address 15360) before stopping, which is provided as a recovery route documented in the on-screen instructions.
Board Representation
Five parallel 4×4 arrays are used throughout:
| Array | Purpose |
|---|---|
b(x,y) | Current live board — absolute counter counts during explosion resolution |
c(m,n) | Signed board state — positive = computer’s pieces, negative = human’s pieces (×t) |
d(m,n) | Dirty flag — marks cells touched during the current explosion wave |
e(m,n) | Explosion counter — incremented each time a cell explodes; used for win detection |
f(m,n) | Persistent board — the “committed” state; copied to/from c for AI lookahead |
The sign convention in c and f is notable: t=1 for the human and t=-1 for the computer, so each player’s pieces are stored as positive values in their own frame of reference. The display always shows ABS f(g,h) (line 9900) to hide the sign from the player.
AI Move Selection
The computer’s AI (lines 8820–8930) is a shallow one-ply minimax variant. For every cell not already owned by the human (f(q,w) <= 0), it tentatively decrements c(q,w) by 1, runs the explosion propagation via GO SUB 105 (line 2000), evaluates the resulting position with GO SUB 5000, and records the move with the lowest score st. Tie-breaking uses RND > 0.5 to randomly select among equally scored moves.
The scoring function (lines 5000–5180) sums all values in c, then adds a 10-point bonus for each neighbor of a near-capacity friendly cell that is also near capacity — rewarding cluster formation that is one move away from a chain explosion.
Explosion Propagation
The main propagation loop (lines 100–210) is a fixed-point iteration: it scans the entire board looking for cells where the absolute count b(x,y) exceeds capacity a. When found, subroutine 1000 distributes +1 to each orthogonal neighbor, zeros the exploded cell, increments e(x,y), and sets the chain-continue flag i=1. The outer loop (line 190) repeats until a full pass finds no overflows. Variable u is set by subroutine 2300 to signal whether play should continue or trigger the win/lose screen.
Display and Layout
The grid is drawn with PLOT/DRAW at lines 8230–8270, using pixel coordinates derived from constants xp, yp, and cell spacing of 16 pixels. BASIC text is overlaid using PRINT AT with x0, xk, y0, yk as origin and stride. Player 1 uses PAPER 5 (cyan) and player 2 uses PAPER 6 (yellow), stored in z(1) and z(2). The variable pl gates all screen updates during the AI’s lookahead phase — when pl=0, no PRINT statements in subroutines 1000 and 100 execute, keeping the display clean during evaluation.
Input Validation and Compatibility
Human input is restricted to strings “1”, “2”, “3”, or the value of k$ (the board size), enforced by multi-branch IF chains at lines 8620 and 8650. An attempt to play in a cell owned by the computer (f(g,h) < 0) triggers a BEEP and re-prompts. Lines 34–38 and the dual-path initialization (lines 10, 32–44, 50, 60) reflect explicit design for two different hardware targets, with line 10 jumping directly to the game setup at line 8000 for one configuration and the instructions block serving the other.
Notable Anomalies
- Line 8320 contains a bare
\{16}\{2}\{16}\{0}color sequence before printingiwithout anATposition reset guard, which may produce minor display glitches depending on current cursor position. - The variable
zis used both as the arrayz()holding PAPER colors and as a scalar at line 8920 (LET z=w) to store the best AI column. This dual use does not cause a runtime error because BASIC treatszandz()as distinct, but it is potentially confusing. - Win detection via array
e(requiring each cell to have exploded at least 3 times) is an unconventional criterion; in typical chain-reaction games the win condition is ownership of all cells. This may result in games that play longer than expected. - Lines 44 and 50 (
LOAD "EXP" CODEandSAVE "LOADING" LINE 10) are embedded in the middle of the instruction block and will execute if the program is ever RUN from line 1, which aligns with the compatibility warning at lines 34–38.
Content
Source Code
2 REM ROBERT GILDER 1984
4 POKE 23606,48:POKE 23607,116:REM calls character change
5 REM EXPLOSION
10 GO TO 8000
32 PRINT
34 PRINT "For Spectrum:RUN and ENTER."
36 PRINT "For TS 2068: GOTO 5 and ENTER."
38 PRINT "2068-if you RUN by mistake,"'"characters will corrupt. key"'"CAPSHIFT 1, SYMBOLSHIFT a, GOTO 9996."
40 PRINT ' TAB 9;"instructions"
42 PRINT '"You play against the computer."'"Each box has the capacity of 2, except the center box(s). The"'"capacity is indicated in the "'"boxes and you must force an"'"EXPLOSION. Enter co-ordinates"'"in a box previously occupied"'"with 1 or 2, in a blue box."'"\{16}\{2}**** E X P L O S I O N ****\{16}\{0}"
44 LOAD "EXP"CODE
50 SAVE "LOADING" LINE 10
60 GO TO 10
100 GO SUB 3000
105 GO SUB 2000
110 LET i=0:FOR x=1 TO k
120 FOR y=1 TO k
130 GO SUB 500
140 IF a>b(x,y) THEN GO TO 170
150 IF pl=1 THEN PRINT AT x0+xk*x,y0+yk*y;" ";
160 GO SUB 1000
165 IF u=0 THEN RETURN
170 NEXT y
180 NEXT x
190 IF i=1 THEN GO TO 110
200 GO SUB 1500
210 RETURN
500 IF x <>1 AND x <>k AND y <>1 AND y <>k THEN LET a=4:RETURN
510 IF x=y OR x+y=k+1 THEN LET a=2:RETURN
520 LET a=3:RETURN
1000 IF y=k THEN GO TO 1040
1010 LET b(x,y+1)=b(x,y+1)+1
1020 LET d(x,y+1)=1
1030 IF pl=1 THEN PRINT AT x0+xk*x,y0+yk*(y+1); PAPER z(p);b(x,y+1);
1040 IF y=1 THEN GO TO 1080
1050 LET b(x,y-1)=b(x,y-1)+1
1060 LET d(x,y-1)=1
1070 IF pl=1 THEN PRINT AT x0+xk*x,y0+yk*(y-1); PAPER z(p);b(x,y-1);
1080 IF x=k THEN GO TO 1120
1090 LET b(x+1,y)=b(x+1,y)+1
1100 LET d(x+1,y)=1
1110 IF pl=1 THEN PRINT AT x0+xk*(x+1),y0+yk*y; PAPER z(p);b(x+1,y)
1120 IF x=1 THEN GO TO 1160
1130 LET b(x-1,y)=b(x-1,y)+1
1140 LET d(x-1,y)=1
1150 IF pl=1 THEN PRINT AT x0+xk*(x-1),y0+yk*y; PAPER z(p);b(x-1,y)
1160 LET i=1:LET b(x,y)=0
1170 LET e(x,y)=e(x,y)+1
1180 GO SUB 2300
1190 RETURN
1500 FOR m=1 TO k:FOR n=1 TO k
1510 IF e(m,n) <>0 OR d(m,n)=1 THEN LET c(m,n)=b(m,n)*t
1520 NEXT n:NEXT m
1530 RETURN
2000 FOR m=1 TO k:FOR n=1 TO k
2010 LET b(m,n)= ABS (c(m,n))
2020 NEXT n:NEXT m
2030 RETURN
2300 LET u=0
2310 FOR m=1 TO k:FOR n=1 TO k
2320 IF e(m,n)<3 THEN LET u=1:LET m=k:LET n=k
2330 NEXT n:NEXT m
2340 IF u=0 AND pl=1 THEN GO TO 9498
2350 RETURN
3000 FOR m=1 TO k:FOR n=1 TO k
3010 LET c(m,n)=f(m,n)
3020 NEXT n:NEXT m
3030 RETURN
4000 FOR m=1 TO k:FOR n=1 TO k
4010 LET f(m,n)=c(m,n)
4020 NEXT n:NEXT m
4030 RETURN
5000 LET so=0
5010 FOR x=1 TO k:FOR y=1 TO k
5020 LET so=so+c(x,y):GO SUB 500
5030 IF -c(x,y) <>a-1 THEN GO TO 5170
5040 LET so=so-2
5050 IF x=k THEN GO TO 5080
5060 LET x=x+1:GO SUB 500:LET x=x-1
5070 IF c(x+1,y)=a-1 THEN LET so=so+10
5080 IF x=1 THEN GO TO 5110
5090 LET x=x-1:GO SUB 500:LET x=x+1
5100 IF c(x-1,y)=a-1 THEN LET so=so+10
5110 IF y=k THEN GO TO 5140
5120 LET y=y+1:GO SUB 500:LET y=y-1
5130 IF c(x,y+1)=a-1 THEN LET so=so+10
5140 IF y=1 THEN GO TO 5170
5150 LET y=y-1:GO SUB 500:LET y=y+1
5160 IF c(x,y-1)=a-1 THEN LET so=so+10
5170 NEXT y:NEXT x
5180 RETURN
7000 FOR m=1 TO k:FOR n=1 TO k
7010 LET d(m,n)=0:LET e(m,n)=0
7020 NEXT n:NEXT m
7030 RETURN
8000 CLS :RANDOMIZE
8010 PRINT AT 1,8;"\{18}\{1}\{16}\{2}***EXPLOSION***\{16}\{0}\{18}\{0}"
8020 DIM b(4,4):DIM c(4,4):DIM d(4,4):DIM e(4,4):DIM f(4,4):DIM z(2)
8030 LET k=4:GO SUB 7000
8040 FOR m=1 TO 4:FOR n=1 TO 4
8050 LET f(m,n)=0
8060 NEXT n:NEXT m
8070 LET x0=4:LET xk=2:LET y0=11:LET yk=2
8080 LET xp=8*y0+12:LET yp=175-(8*x0+12)
8090 LET z(1)=5:LET z(2)=6
8200 INPUT "\{16}\{1}ENTER THE SIZE OF THE BOARD\{16}\{0}"; TAB 32;"\{16}\{1}3 OR 4 :\{16}\{0} ";k$;
8210 IF k$ <>"3" AND k$ <>"4" THEN GO TO 8200
8220 LET k= VAL k$
8230 FOR i=0 TO k
8240 PLOT xp+16*i,yp:DRAW INK 2;0,-16*k
8250 PLOT xp,yp-16*i:DRAW INK 2;16*k,0
8260 NEXT i
8270 PLOT xp,yp:DRAW INK 2;-12,12
8280 PRINT AT x0+1,y0;"\{16}\{2}X\{16}\{0}";
8290 PRINT AT x0,y0+1;"\{16}\{2}Y\{16}\{0}";
8300 FOR i=1 TO k
8310 PRINT AT x0+xk*i,y0;i;
8320 PRINT AT x0,y0+yk*i;\{16}\{2}\{16}\{0}i\{16}\{0};
8330 NEXT i
8400 INPUT "\{16}\{1}WHO STARTS? YOU (Y) OR ME (M)?\{16}\{0}"; TAB 32;b$
8410 IF b$="M" OR b$="m" THEN GO TO 8600
8420 IF b$="Y" OR b$="y" THEN GO TO 8800
8430 GO TO 8800
8600 PRINT AT 16,6;"\{16}\{1}NOW IT'S YOUR TURN!\{16}\{0}":PRINT AT 18,0; TAB 31;"":PRINT AT 19,0; TAB 31;""
8610 INPUT "\{16}\{1}ENTER YOUR MOVE\{16}\{0}"; TAB 32;"X: ";g$
8620 IF g$ <>"1" AND g$ <>"2" AND g$ <>"3" AND g$ <>k$ THEN GO TO 8610
8630 PRINT AT 18,14;"X: ";g$;
8640 INPUT "\{16}\{1}ENTER YOUR MOVE\{16}\{0}"; TAB 32;"Y: ";h$
8650 IF h$ <>"1" AND h$ <>"2" AND h$ <>"3" AND h$ <>k$ THEN GO TO 8640
8660 PRINT AT 19,14;"Y: ";h$
8670 LET g= VAL g$:LET h= VAL h$
8680 IF f(g,h)<0 THEN BEEP 1,3:GO TO 8600
8690 LET f(g,h)=f(g,h)+1:LET t=1:LET p=1:LET pl=1
8700 GO SUB 9900
8710 GO SUB 100
8720 GO SUB 7000
8730 GO SUB 4000
8800 LET t=-1:LET p=2:LET pl=0
8810 PRINT AT 16,6;"\{16}\{1}NOW IT'S MY TURN!\{16}\{0} ":PRINT AT 18,0; TAB 31;"":PRINT AT 19,0; TAB 31;""
8820 LET st=1000
8830 FOR q=1 TO k:FOR w=1 TO k
8840 IF f(q,w)>0 THEN GO TO 8930
8850 GO SUB 3000
8860 LET c(q,w)=c(q,w)-1
8870 GO SUB 105
8880 GO SUB 7000
8890 GO SUB 5000
8900 IF so<st THEN LET st=so:LET v=q:LET z=w:GO TO 8930
8910 IF so <>st THEN GO TO 8930
8920 IF RND>.5 THEN LET st=so:LET v=q:LET z=w
8930 NEXT w:NEXT q
8940 PRINT AT 18,14;"X: ";v;:PRINT AT 19,14;"Y: ";z;
8950 GO SUB 3000:BEEP 1,1:LET f(v,z)=f(v,z)-1
8960 LET g=v:LET h=z:GO SUB 9900
8970 LET pl=1:GO SUB 100
8980 GO SUB 7000
8990 GO SUB 4000
9000 GO TO 8600
9498 IF t=1 THEN PRINT AT 20,8;"\{16}\{2}\{16}\{0}\{18}\{1}\{16}\{2}***\{16}\{2}EXPLOSION***\{16}\{0}\{18}\{0}"
9500 IF t=1 THEN INPUT "\{16}\{2}YOU WIN\{16}\{0}"; TAB 32;"\{16}\{2}ANOTHER GAME? Y OR N :\{16}\{2}\{16}\{0}";A$:GO TO 9520
9505 PRINT AT 20,8;"\{18}\{1}\{16}\{2}***\{16}\{2}EXPLOSION***\{16}\{0}\{18}\{0}"
9510 INPUT "\{16}\{2}YOU LOSE!\{16}\{0}"; TAB 32;"\{16}\{2}ANOTHER GAME? Y OR N :\{16}\{0} ";a$
9520 IF a$="y" OR a$="Y" THEN RUN
9530 STOP
9900 PRINT AT x0+xk*g,y0+yk*h; PAPER z(p); ABS f(g,h);
9910 RETURN
9996 POKE 23606,0:POKE 23607,60:REM Return to normal characters
9997 STOP
9998 SAVE "EXP"CODE 28000,3200
9999 SAVE "Explosion" LINE 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
