--- title: "3 Games" id: 70996 type: "computer_media" slug: "3-games-2" url: "http://localhost/computer_media/3-games-2/" markdown_url: "http://localhost/computer_media/3-games-2.md" published_at: "2026-08-25T13:48:39+00:00" modified_at: "2026-08-25T13:52:14+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/08/3-games.png" alt: "3 Games screen" excerpt: "Three games in one listing—navigate a minefield, rally a Pong paddle, and steer a pixel car down a converging road—all from a single menu." 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/3%20Games%20%28198x%29%28-%29%28TS2068%29%28US%29%28Program%29.zip" tsrun_member: "3 Games (198x)(-)(TS2068)(US)(Program).tap" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/08/3-games.png" alt: "3 Games screen" media_type_tags: "Game" --- # 3 Games This program bundles three separate games—Minefield, a simple Pong clone, and a Night Driver–style 3D driving game—into a single BASIC listing with a menu system starting at line 1500. Minefield moves up to three player tokens along a track divided into multiples of four, where landing on such positions triggers a “mine” flag stored in a two-dimensional array. The Pong game uses a single-character ball and a paddle controlled by keys 5 and 8, with BEEP calls for audio feedback on wall bounces and paddle hits. The Night Driver segment defines a custom four-character UDG car sprite via POKEd DATA bytes and draws converging road lines using PLOT/DRAW, adjusting a horizontal position variable to simulate steering and detecting crashes when the position drifts outside bounds. *** ### Program Structure The listing is organized into four distinct regions, each entered via `RUN` with an explicit line number rather than `GO TO`, which restarts the interpreter and clears variables each time: | Lines | Section | | --- | --- | | 10–330 | Minefield game | | 500–690 | Pong game | | 1000–1340 | Night Driver game | | 1500–1560 | Main menu / dispatcher | Line 5 (`RUN 1500`) ensures the menu is shown on program load. The menu at line 1530 validates input in-line with `IF (a<1) OR (a>3) THEN RUN`, which re-runs from the top of the program (line 5), looping back to the menu. ### Minefield — Key Mechanics State for the three player tokens is kept in array `a(PI,2)`, which on the Spectrum evaluates `PI` as 3, giving a 3×2 array. Column 1 (indexed via `SGN PI` = 1) holds each man’s current position; column 2 holds a dead flag. - A random dice roll `x` (1–6) is generated each turn. - Mine detection at line 150: a position is mined if it is an exact multiple of 4 (`p = INT p` where `p = pn/4`) or equals 25 specifically. Landing there sets `a(m,2)=1` (dead). - The finish square is column 28; reaching it increments the win counter `w`. - Win/loss checks at lines 220–250 cover all-dead, all-arrived, and the mixed game-over case. - Invalid moves (selecting a dead or already-finished man) jump to line 280 and display an error for a short busy-loop delay before clearing it. - The idiom `IF INKEY$=i$ THEN GO TO 260` at line 260 debounces the key held from the previous input. A notable anomaly: `DIM c$(32)` is declared but used only at line 290 as a 32-space string to blank the “INVALID MOVE” message — a clean erase technique. ### Pong — Key Mechanics The ball is a single `"."` character. Position is tracked by `x` (row) and `y` (column); direction by `ud` (±1 vertical) and `lr` (±1 horizontal). The paddle is at fixed row `A=20`, column `b`, drawn as `CHR$ 95` (underscore). - The subroutine at lines 660–690 reads keys 8 (right) and 5 (left) and redraws the paddle each frame — called twice per loop iteration (before and after moving the ball) for smoother response. - Wall bounces at `ny=0` or `ny=31` reverse `lr` and set flag `w=10` (used to trigger a BEEP on the next frame via `IF w THEN BEEP .01,30`). - A miss (ball reaches row 22) plays a low BEEP and restarts the ball via `GO TO 550`, preserving the paddle position. Line 510 contains a developer note embedded in a REM: `REM LINE 50, value of w unknown:LET w=?`. This references the Minefield section’s variable `w` and flags that because each game is entered with `RUN`, variables are reset, but the comment appears to document a concern that was ultimately moot. ### Night Driver — UDGs and Graphics The car sprite is four UDG characters (a–d), arranged in a 2×2 block, defined by POKEing 32 bytes of DATA into `USR "a"` through `USR "d"+7` via the subroutine at lines 1270–1290. Road perspective is simulated with two pairs of PLOT/DRAW calls that draw converging lines from the bottom of the screen toward a vanishing region, using the horizontal position variable `p` (nominally centered at 127): - `PLOT p-10,159: DRAW -170+(p-10),-159` — left road edge - `PLOT p+10,159: DRAW -70+(p-10),-159` — right road edge (asymmetric offset creates a subtle skew) Each game tick erases the previous lines using `PLOT OVER 1` / `DRAW OVER 1` (XOR mode), then redraws at the new `p`. The crash condition checks whether `p` has drifted outside the range 108–150 (line 1040). When a crash occurs, lines 1140–1150 draw the final road position without erasing, then play an ascending BEEP sweep at line 1170. The score `sc` increments by 1 each loop iteration (line 1110), giving a simple survival-time score. Steering input moves `p` by ±4 pixels per key press, and a random drift of ±10 pixels is added each frame (`INT(RND*20)-10`), making the road progressively harder to follow. ### Notable Techniques and Idioms - `SGN PI` is used throughout as a constant 1, avoiding the literal digit to save a byte per occurrence. - `NOT PI` evaluates to 0, used as a column argument in `PRINT AT` statements for left-aligned output. - `VAL i$` converts the single-character key input to a numeric man-selector without an explicit variable assignment step. - `RUN 10`, `RUN 500`, `RUN 1000` as game launchers cleanly reset all variables without needing explicit initialization in each game section (except for the Night Driver which uses its own `GO SUB 1220` init routine). - The `INPUT "" LINE a$` at line 1190 waits for ENTER without displaying a prompt variable — the prompt text is embedded directly in the INPUT string. ### Bugs and Anomalies - In Pong, the bounce flag `w` is set to 10 on a side-wall hit but only 1 on a top-wall hit (line 590). Since the BEEP check at line 560 is `IF w` (any nonzero), both trigger a beep — the value 10 has no additional effect, suggesting a copy or edit artifact. - The Night Driver road line geometry is asymmetric: the right-edge DRAW uses `-70+(p-10)` rather than the expected mirror of the left edge’s `-170+(p-10)`. This means the right road line converges less steeply, producing a slightly off-center vanishing point. - Line 1200 (`GO TO 1040`) is unreachable dead code, sitting after the `INPUT` / `RUN` sequence in the crash handler. - The menu’s instruction at line 1520 prints `" 2 & 3 use 5 for right"` — but key 5 moves the paddle *left* in Pong (decrements `b`) and steers left in Night Driver. The label appears inverted relative to screen coordinates. ## Source Code ``` 5 RUN 1500 10 REM MINEFIELD 20 BORDER 6:PAPER 6:INK 9:CLS 30 DIM c$(32):DIM a(PI,2):FOR j= SGN PI TO PI:LET a(j, SGN PI)=1:NEXT j 40 PRINT AT 4, SGN PI;:FOR j= SGN PI TO 6:PRINT INK 4;"---"; INK 2;"-";:NEXT j 50 PRINT INK 2;"-"; INK 4;"--"; INK 7; CHR$ 143 60 FOR j= SGN PI TO PI:PRINT AT j, SGN PI;"*":NEXT j 70 RANDOMIZE 80 LET x= INT (RND*6)+1 90 PRINT AT 10, NOT PI;"MOVE ";x;" PACE";:IF x <>1 THEN PRINT "S" 100 PRINT AT 15, NOT PI;"Which Man (1-3)" 110 LET i$= INKEY$:IF i$<"1" OR i$>"3" THEN GO TO 110 120 LET m= VAL i$ 130 IF a(m,2) OR a(m, SGN PI)=28 THEN GO TO 280 140 LET pn=a(m, SGN PI)+x 150 LET p=pn/4:IF pn<28 AND p= INT p OR pn=25 THEN LET a(m,2)=1 160 IF pn>28 THEN LET pn=28 170 PRINT AT m,a(m, SGN PI); CHR$ 32; TAB pn; FLASH a(m,2);"*" 180 LET a(m, SGN PI)=pn 190 LET w=0:LET d=w:FOR j= SGN PI TO 3:IF a(j,2) THEN LET d=d+1 200 IF a(j, SGN PI)=28 THEN LET w=w+1 210 NEXT j 220 IF d=3 THEN PRINT AT 19,10;"ALL MEN DEAD!":GO TO 300 230 IF w=3 THEN PRINT AT 19,10; INK 2; PAPER 7;"CONGRATULATIONS":GO TO 300 240 LET d$=" MAN":IF d <>1 THEN LET d$(3)="E" 250 IF d+w=3 THEN PRINT AT 19,4; FLASH 1;"GAME OVER : ";d;d$;" KILLED!":GO TO 300 260 IF INKEY$=i$ THEN GO TO 260 270 GO TO 80 280 PRINT AT 20,10;"INVALID MOVE":FOR j= SGN PI TO 45:NEXT j 290 PRINT AT 20, NOT PI;c$:GO TO 110 300 PRINT AT 21, NOT PI;"Press P to play : X to stop" 310 IF INKEY$="p" THEN RUN 320 IF INKEY$="x" THEN RUN 1500 330 GO TO 310 500 REM PONG 510 REM LINE 50, value of w unknown:LET w=? 520 BORDER 4:PAPER 4:BRIGHT 1:INK 9 530 CLS 540 LET A=20:LET B=15:LET W=0 550 LET x=0:LET y= INT (RND*31):LET ud=1:LET lr= INT (RND*2):IF lr=0 THEN LET lr=-1 560 PRINT AT x,y;".":IF w THEN BEEP .01,30:LET w=0 570 GO SUB 660 580 LET nx=x+ud 590 IF nx=0 THEN LET ud=-ud:LET w=1 600 GO SUB 660 610 LET ny=y+lr:IF ny=0 OR ny=31 THEN LET lr=-lr:LET w=10 620 IF nx=a AND ny=b THEN LET ud=-ud:BEEP .01,50 630 PRINT AT x,y; CHR$ 32:LET x=nx:LET y=ny 640 IF x=22 THEN BEEP .3,0:GO TO 550 650 GO TO 560 660 LET n=b+(INKEY$="8" AND b<31)-(INKEY$="5" AND b>0) 670 IF n <>b THEN PRINT AT a,b; CHR$ 32:LET b=n 680 PRINT AT a,b; CHR$ 95 690 RETURN 1000 REM 3D DRIVER from Games for Your Timex-Sinclair 2000, p.74 1010 GO SUB 1270 1020 GO SUB 1220 1030 PRINT AT 15,15; INK 4;"[UDG-A][UDG-B]"; AT 16,15;"[UDG-C][UDG-D]" 1040 IF p<108 OR p>150 THEN GO TO 1140 1050 PLOT p-10,159:DRAW -170+(p-10),-159 1060 PLOT p+10,159:DRAW -70+(p-10),-159 1070 PLOT OVER 1;p-10,159:DRAW OVER 1;-170+(p-10),-159 1080 PLOT OVER 1;p+10,159:DRAW OVER 1;-70+(p-10),-159 1090 LET p=p+4*(INKEY$="5")-4*(INKEY$="8") 1100 LET p=p+(INT (RND*20)-10) 1110 LET sc=sc+1 1120 GO TO 1040 1130 STOP 1140 PLOT p-10,159:DRAW -170+(p-10),-159 1150 PLOT p+10,159:DRAW -70+(p-10),-159 1160 PRINT AT 15,15; FLASH 1; INK 2;"[UDG-A][UDG-B]"; AT 16,15;"[UDG-C][UDG-D]" 1170 FOR a=0 TO 50:BEEP .05,a:BEEP .0008,a:NEXT a 1180 PRINT AT 1,10; PAPER 1;"You scored ";sc 1190 INPUT "Press "; INK 6;"ENTER"; INK 7;" to play again "; LINE a$:FOR z=1 TO 120:NEXT z:RUN 1200 GO TO 1040 1210 REM 1220 BORDER 0:PAPER 0:INK 7:CLS 1230 LET p=127 1240 LET sc=0 1250 PRINT AT 0,0; PAPER 1;"________________________________" 1260 RETURN 1270 FOR a= USR "a" TO USR "d"+7 1280 READ user:POKE a,user 1290 NEXT a:RETURN 1300 DATA 0,0,0,0,13,11,13,3 1310 DATA 0,0,0,0,176,208,175,192 1320 DATA 6,117,207,223,208,240,12,3 1330 DATA 102,174,243,251,19,15,48,192 1340 REM ab= [UDG-A][UDG-B] cd= [UDG-C][UDG-D] 1500 BORDER 6:PAPER 7:INK 9:CLEAR 1510 PRINT ''' TAB 12;"3 Games" 1520 PRINT ''" 1 Mine Field"''" 2 Simple Pong"''" 3 Night Driver"''''" 2 & 3 use 5 for right"',"8 for left" 1530 INPUT "Select 1, 2, 3, ";a:IF (a<1) OR (a>3) THEN RUN 1540 IF a=1 THEN RUN 10 1550 IF a=2 THEN RUN 500 1560 RUN 1000 9900 SAVE "Games 3" LINE 1 ```