--- title: "Tank" id: 56320 type: "computer_media" slug: "tank" url: "http://localhost/computer_media/tank/" markdown_url: "http://localhost/computer_media/tank.md" published_at: "2024-08-04T10:50:00+00:00" modified_at: "2026-03-30T21:45:53+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/08/SCR-20240803-hklq.png" excerpt: "Enter an elevation angle and watch your shell arc across the battlefield — but can you calculate the range before your target escapes?" 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_contents: - id: 56277 title: "Timex Sinclair Public Domain Library Tape 2001" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-2001/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Tank%20%28198x%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/08/SCR-20240803-hklq.png" - url: "http://localhost/wp-content/uploads/2024/08/SCR-20240803-hkzx.png" media_type_tags: "Game" --- # Tank This program implements a tank gunnery game in which the player adjusts the elevation angle of a cannon to hit a target at a randomly chosen range between 10,000 and 29,000 yards. Two User-Defined Graphics characters are defined via POKE into USR “A” and USR “B” to draw a tank body and a target respectively. The trajectory arc is rendered using SIN-based plotting with OVER 1 (XOR mode) to animate the shell’s path without permanently overwriting the battlefield display. SOUND drives multi-channel sound effects for the firing sequence and explosion, and ON ERR / RESET are used for unconventional control-flow handling around input validation. *** ## Program Analysis ### Program Structure The program is organised into a short main loop and several subroutines: 1. **Lines 2–4:** Initialisation — loads two UDG bitmaps and sets up the display. 2. **Lines 5–6:** Generates a random target range and sets up error-trap flow control. 3. **Lines 8–14:** Subroutine — draws the ground, range readout, and the target UDG. 4. **Lines 15–26:** Subroutine — fires the cannon: triggers sound, then plots a SIN-based arc using OVER 1 (XOR draw). 5. **Lines 32–56:** Main game loop — solicits elevation input, computes range, calls display and fire subroutines, and gives feedback. 6. **Lines 58–64:** Hit detection — displays a flashing hit indicator, plays an explosion sound, pauses, and restarts. ### User-Defined Graphics Lines 2–3 define two UDGs. `RESTORE` resets the DATA pointer; 16 bytes are then READ and POKEd into `USR "A"` and `USR "B"` consecutively. UDG “A” (`\a` in the PRINT at line 10) draws the tank, and UDG “B” (`\b` at line 12) draws the target. The bitmap values `0,1,18,44,40,126,129,126` for UDG A and `56,55,49,57,39,32,32,32` for UDG B are defined inline in the single DATA statement on line 2. ### Ballistic Arc Calculation The shell trajectory is drawn in the subroutine at lines 15–26. The horizontal range in screen columns is computed as `L = INT(N * 0.68)` where `N` is the input elevation. The arc height at each point `I` is `B * SIN(1.57 * I / L / 4)`, where `B` stores the raw elevation value and `1.57` approximates π/2. This scales a quarter-sine wave over the horizontal range, giving a plausible parabolic appearance. The angle symmetry on line 40 — `IF N>45 THEN LET N=90-N` — ensures that complementary angles (e.g. 30° and 60°) produce the same horizontal range `L`, mimicking real ballistic symmetry while keeping the screen range within bounds. Note that `B` retains the original elevation for arc height, while `N` is adjusted for range. ### OVER 1 (XOR) Drawing Lines 17–22 use `OVER 1` before each PLOT pair so that each new pixel XORs with the existing display. This means redrawing the same pixels erases them, producing a simple animation trail. `OVER 0` is restored at line 24. The loop steps by 2 and explicitly erases the previous point with a second PLOT at `I-2`, creating a moving two-pixel “shell” dot. ### TS2068 Extensions The program makes extensive use of TS2068-specific keywords: - `SOUND` (}`)` — multi-channel AY sound at lines 15 and 61. Line 61 also uses `SOUND 8,0;9,0;10,0` to silence channels after the explosion. - `ON ERR` ({}) — used at line 6 to redirect to the INPUT line (34) on any BASIC error, providing a crude way to loop back if an error occurs during the GO TO 32 call. Line 36 uses `ON ERR RESET` (©) to reset error handling if a negative elevation is entered. - `RESET` (©) — resets the ON ERR trap (line 36), guarding against negative input. ### Control Flow Idioms | Line | Technique | | --- | --- | | `6` | `ON ERR GO TO 34` — sets an error handler before the first GO SUB 8 call, so any error drops into the input prompt. | | `32` | `GO SUB 8` — draws initial battlefield before the first INPUT. | | `36` | `IF N<0 THEN ON ERR RESET` — clears the error trap for invalid input, allowing normal error reporting. | | `64` | `GO TO 1` — full restart, re-initialising UDGs and selecting a new range. | ### Hit Detection and Feedback Line 50 checks `IF A=L` for an exact hit. Since both `A` and `L` are integers (A via `INT(RND*20)+10`; L via `INT(N*0.68)`), an exact match is possible but requires precise input. On a miss, line 54 prints whether the shot fell short or long using the Boolean-arithmetic idiom: the string `"SHORT"` or `"LONG"` is appended conditionally using `AND` with a Boolean expression (which evaluates to 1 or 0), a classic Sinclair BASIC technique to avoid IF/ELSE branching inside a PRINT statement. ### Notable Anomaly The variable `B` serves dual purpose: it is set to the raw elevation `N` at line 38 (before `N` may be modified at line 40), and is later used both as the arc amplitude in the SIN formula (line 18/20) and as the label in the miss-feedback PRINT at line 54. This works correctly because line 38 assigns `B` before line 40 adjusts `N`, preserving the original angle for display and arc scaling. ## Source Code ``` 1 REM SAVE "TANK" LINE 1 2 RESTORE : DATA 0,1,18,44,40,126,129,126,56,55,49,57,39,32,32,32 3 FOR I=0 TO 7: READ A: POKE I+USR "A",A: NEXT I: FOR I=0 TO 7: READ A: POKE I+USR "B",A: NEXT I 4 BORDER 6: PAPER 6: CLS 5 LET A=10+INT (RND*20) 6 ON ERR GO TO 34: GO TO 32 8 PRINT AT 1,0;"RANGE = ";A;"000 YDS." 10 PRINT AT 17,0; INK 0;"\a"; INK 4'"████████████████████████████████" 12 PRINT INK 1;AT 17,A;"\b" 14 RETURN 15 SOUND 6,30;7,7;8,16;9,16;10,16;12,16;13,0 16 PLOT 8,39 17 FOR I=10 TO 8*L STEP 2 18 OVER 1: PLOT I,34+B*SIN (1.57*I/L/4) 20 PLOT I-2,34+B*SIN (1.57*(I-2)/L/4) 22 NEXT I 24 OVER 0 26 RETURN 32 GO SUB 8 34 INPUT " INPUT ELEVATION (0 TO 90) ";N 36 IF N<0 THEN ON ERR RESET 38 LET B=N 40 IF N>45 THEN LET N=90-N 42 CLS 44 LET L=INT (N*.68) 46 GO SUB 8 48 GO SUB 15 50 IF A=L THEN GO TO 58 52 PRINT INK 2;AT 17,L;"*": BEEP 1,-12 54 PRINT AT 19,0;B;" DEG IS ";INT (.5+1000*ABS (A-N*.68));" YARDS ";"SHORT" AND A>L;"LONG" AND A