Fallout is a puzzle game in which the player rotates rows of a grid to create vertical gaps that allow numbered tokens to fall through to the bottom. The grid is 17 columns wide by 9 rows deep, stored in the two-dimensional array h(17,9), with each row (bar) containing four randomly placed holes initialized at startup. Eight numbered tokens, represented as characters using CHR$ (z-52) to map values 101–108 to printable ASCII, are placed across the top row and must be dropped off the bottom edge to score points. Row rotation is implemented as a simple circular shift: left-rotation saves the leftmost cell, shifts all others one position left, and wraps the saved value to the rightmost position, while right-rotation does the reverse. After each rotation the gravity subroutine at line 2000 scans from the bottom upward, dropping any token that has an empty cell below it, and removes tokens that reach row 9 with no cell beneath them, incrementing the score. The game accepts a single INPUT string encoding the target row, direction, and number of repeated turns, allowing multi-step moves in one entry.
Program Structure
The program is organized into a main flow section and four subroutines:
| Lines | Purpose |
|---|---|
| 5–190 | Initialization: dimension arrays, place bars with holes, place tokens |
| 200–220 | Initial display and gravity pass before first move |
| 500–640 | Main game loop: parse input, dispatch left/right rotation, apply gravity, redisplay |
| 1000–1110 | Display subroutine: prints entire grid with row labels |
| 1500–1530 | Cell rendering helper: blank, solid bar, or token character |
| 2000–2150 | Gravity subroutine: drops tokens downward, scores those reaching the bottom |
| 3000–3050 | Left-rotate a single row (circular shift left) |
| 4000–4050 | Right-rotate a single row (circular shift right) |
Grid Representation
The grid is stored in h(17,9) where the first index is the column (1–17) and the second is the row (1–9). Cell values encode three states:
0— empty (hole or cleared space)1— solid bar segment>100— numbered token (values 101–108 for tokens 1–8)
Row 1 is the top “launch” row, rows 2–9 are the barrier rows. Each barrier row is initialized to all-solid (h(x,y)=1) and then four random columns are punched to zero, creating the holes through which tokens must eventually fall.
Token Encoding and Display
Tokens are stored as values 101–108. The display helper at line 1520 prints CHR$ (z-52); subtracting 52 from 101–108 yields ASCII codes 49–56, which are the characters 1 through 8. This is a compact encoding that avoids storing the display character separately. Solid bar cells are printed with PAPER 0 to produce a filled block appearance, while empty cells print a plain space.
Input Parsing
The INPUT at line 500 accepts a three-element string z$ (declared as DIM z$(3), so exactly three characters). The three characters are parsed positionally:
z$(1)— bar number (1–8), converted to row index by adding 1 (since row 1 is reserved for tokens)z$(2)— direction:lfor left,rfor rightz$(3)— number of rotation steps
Validation at lines 520–560 rejects out-of-range bar numbers, invalid step counts, and characters other than l or r. Multi-step rotation is handled by the loop at line 630, which decrements dx and re-dispatches the rotation subroutine until all steps are consumed — note this reuses d$ which is still set from the original input.
Rotation Subroutines
Left rotation (lines 3000–3050) saves h(1,y) into tm, shifts columns 1–16 left by one, then places tm at column 17 — a standard circular buffer shift. Right rotation (lines 4000–4050) is the mirror operation, saving h(17,y) and shifting columns 17 down to 2 rightward. Both operate on a single row y as determined by the parsed input.
Gravity and Scoring
The gravity subroutine (lines 2000–2150) iterates columns within rows, scanning from row 9 upward to row 1. When a token (h(x,c)>=100) is found, it attempts to drop it down through consecutive empty cells using a local variable ty. If ty reaches 9 and the cell below would be off the grid, the token is removed and sc is incremented. The game ends when sc=8 (all eight tokens scored), checked at line 620 with STOP.
Notable Techniques and Idioms
- The
DIM z$(3)declaration constrains input to exactly three characters, combining type safety and length enforcement in a single statement. VAL z$(1)andVAL z$(3)convert single character positions of the string to numeric values without needing separate variables.- The gravity loop uses
GO TO 2040to continue dropping a single token across multiple rows in one pass, rather than requiring repeated calls. - The move counter
brtracks total individual rotations applied across all inputs and is displayed as a “turns” score.
Bugs and Anomalies
- At line 120,
INT (RND*16+1)generates values 1–16, not 1–17, so column 17 of each barrier row is never punched as a hole during initialization — it is always solid. This creates a systematic bias in the grid. - The multi-step loop at line 630 re-evaluates
d$(still valid from line 530) and branches to line 570 or 580 via the sameIFtests, but theGO TO 570in line 630 skips thed$="r"check at line 580. If direction isr, line 630’sGO TO 570will reach line 580’s check and work correctly sinced$is preserved — so this is functional but could be cleaner. - The gravity subroutine’s inner drop loop condition at line 2040 checks
ty>=9to detect the bottom edge, but the grid’s last valid row index is 9, meaning a token sitting exactly on row 9 is immediately scored without checking whether a hole exists below — this is correct behavior since row 10 does not exist, but relies on the boundary condition rather than an explicit hole check.
Source Code
5 REM FALLOUT
10 DIM h(17,9):DIM z$(3)
20 LET sc=0:LET br=0
30 CLS :REM fill with bars
40 FOR x=1 TO 17
50 FOR y=2 TO 9
60 LET h(x,y)=1
70 NEXT y
80 NEXT x
90 REM 4 holes per bar
100 FOR y=2 TO 9
110 FOR b=1 TO 4
120 LET x= INT (RND*16+1)
130 LET h(x,y)=0
140 NEXT b
150 NEXT y
160 REM put 1-8 on top
170 FOR b=1 TO 8
180 LET h(2*b,1)=b+100
190 NEXT b
200 GO SUB 1000
210 GO SUB 2000
220 GO SUB 1000
500 INPUT "bar,left/right,turns: ";z$
510 LET y= VAL z$(1)+1
520 IF (y<2) OR (y>9) THEN GO TO 500
530 LET d$=z$(2)
540 LET dx= VAL z$(3)
550 IF dx=0 THEN GO TO 500
560 IF (d$ <>"l") AND (d$ <>"r") THEN GO TO 500
570 IF d$="l" THEN GO SUB 3000
580 IF d$="r" THEN GO SUB 4000
590 LET br=br+1
600 GO SUB 2000
610 GO SUB 1000
620 IF sc=8 THEN STOP
630 IF dx>1 THEN LET dx=dx-1:GO TO 570
640 GO TO 500
1000 FOR c=1 TO 9
1010 IF c=1 THEN PRINT " ";
1020 IF c>1 THEN PRINT c-1;" >";
1030 FOR x=1 TO 17
1040 LET z=h(x,c)
1050 GO SUB 1500
1060 NEXT x
1070 PRINT
1080 NEXT c
1090 PRINT " score: ";sc;" turns: ";br
1100 PRINT
1110 RETURN
1500 IF z=0 THEN PRINT " ";
1510 IF z=1 THEN PRINT PAPER 0;" ";
1520 IF z>100 THEN PRINT CHR$ (z-52);
1530 RETURN
2000 FOR c=9 TO 1 STEP -1
2010 FOR x=1 TO 17
2020 LET ty=c
2030 IF h(x,c)<100 THEN GO TO 2100
2040 IF ty >=9 THEN GO TO 2130
2050 IF h(x,ty+1) <>0 THEN GO TO 2100
2060 LET h(x,ty+1)=h(x,ty)
2070 LET h(x,ty)=0
2080 LET ty=ty+1
2090 GO TO 2040
2100 NEXT x
2110 NEXT c
2120 RETURN
2130 LET sc=sc+1
2140 LET h(x,ty)=0
2150 GO TO 2100
3000 LET tm=h(1,y)
3010 FOR x=1 TO 16
3020 LET h(x,y)=h(x+1,y)
3030 NEXT x
3040 LET h(17,y)=tm
3050 RETURN
4000 LET tm=h(17,y)
4010 FOR x=17 TO 2 STEP -1
4020 LET h(x,y)=h(x-1,y)
4030 NEXT x
4040 LET h(1,y)=tm
4050 RETURN
9998 SAVE "FALLOUT" LINE 1Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
