--- title: "Fallout" id: 71038 type: "computer_media" slug: "fallout" url: "http://localhost/computer_media/fallout/" markdown_url: "http://localhost/computer_media/fallout.md" published_at: "2026-08-26T01:50:35+00:00" modified_at: "2026-08-26T01:53:24+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/08/fallout.png" alt: "Fallout screen" excerpt: "Rotate rows of a barrier grid to align holes and let numbered tokens fall through in this compact, input-driven puzzle game." 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 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Fallout%20%28198x%29%28-%29%28TS2068%29%28US%29%28Program%29.zip" tsrun_member: "Fallout (198x)(-)(TS2068)(US)(Program).tap" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/08/fallout.png" alt: "Fallout screen" media_type_tags: "Game" --- # Fallout 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: `l` for left, `r` for right - `z$(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)` and `VAL z$(3)` convert single character positions of the string to numeric values without needing separate variables. - The gravity loop uses `GO TO 2040` to continue dropping a single token across multiple rows in one pass, rather than requiring repeated calls. - The move counter `br` tracks 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 same `IF` tests, but the `GO TO 570` in line 630 skips the `d$="r"` check at line 580. If direction is `r`, line 630’s `GO TO 570` will reach line 580’s check and work correctly since `d$` is preserved — so this is functional but could be cleaner. - The gravity subroutine’s inner drop loop condition at line 2040 checks `ty>=9` to 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 1 ```