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:
- Lines 2–4: Initialisation — loads two UDG bitmaps and sets up the display.
- Lines 5–6: Generates a random target range and sets up error-trap flow control.
- Lines 8–14: Subroutine — draws the ground, range readout, and the target UDG.
- Lines 15–26: Subroutine — fires the cannon: triggers sound, then plots a SIN-based arc using OVER 1 (XOR draw).
- Lines 32–56: Main game loop — solicits elevation input, computes range, calls display and fire subroutines, and gives feedback.
- 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 usesSOUND 8,0;9,0;10,0to 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 usesON 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.
Content
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<L
56 GO TO 34
58 PRINT INK 2; FLASH 1;AT 17,L-1;"***"
60 PRINT '"DIRECT HIT"
61 SOUND 6,6;7,7;8,16;9,16;10,16;12,56;13,8: PAUSE 90: SOUND 8,0;9,0;10,0
62 PAUSE 200
63 CLS
64 GO TO 1
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

