This ZX81/TS1000 BASIC program implements a horizontal slalom skiing game in which the player steers a dot through six gates displayed across the screen. Gates are randomly positioned using an array of six Y-coordinates, each drawn as two pixels with a one-pixel gap between them. The player uses keys “7” and “6” to move the dot up and down respectively, with movement handled by subtracting the INKEY$ comparisons directly in arithmetic. Line 100 tests gate collisions using a compact Boolean expression: `30 AND V>=C(B/10) AND V<=C(B/10)+1` routes to line 110 (continue) or line 138 (a non-existent line, triggering a BASIC error/stop) depending on whether the dot passes cleanly through the gate gap.
Program Analysis
Program Structure
The program is divided into three logical phases: setup, play loop, and restart.
- Setup (lines 10–70): Dimensions array
C(6), clears the screen, then randomly places six gates. Each gate occupies columnA*10and consists of two pixels atC(A)-1andC(A)+2, leaving a one-pixel gap atC(A)andC(A)+1for the player to pass through. - Play loop (lines 80–150): Iterates
Bfrom 3 to 63 (the horizontal pixel range), moving the player dot column by column. At every gate column (B/10is an integer), a collision check is performed. - Restart (line 160):
RUNloops the game indefinitely with fresh random gates each time.
Gate Drawing
Each gate is drawn with two PLOT calls: one at C(A)-1 (below the gap) and one at C(A)+2 (above the gap). This leaves exactly two pixels of clear passage at Y positions C(A) and C(A)+1, which is the window the player’s dot must occupy. Gate X positions are 10, 20, 30, 40, 50, 60, all within the ZX81’s 64×44 pixel display.
Collision Detection Technique
Line 100 uses a compact boolean arithmetic trick for gate collision:
100 IF B/10=INT(B/10) THEN GOTO 80+(30 AND V>=C(B/10) AND V<=C(B/10)+1)
On the ZX81, boolean expressions evaluate to 1 (true) or 0 (false). The sub-expression 30 AND V>=C(B/10) AND V<=C(B/10)+1 evaluates to 30 if the player is inside the gate gap, or 0 if not. This is added to 80, producing either GOTO 110 (pass — continue plotting) or GOTO 80… wait, actually 80+0=80 sends execution back to line 80 which resets V to C(1), effectively resetting the player to the first gate’s Y position rather than stopping play. When the player is safely through the gap, the target is 80+30=110, which falls through to the next line normally.
Player Movement
Line 130 handles input using arithmetic on INKEY$ comparisons:
LET V=V+(INKEY$="7")-(INKEY$="6")
This is a standard ZX81 BASIC idiom. If “7” is held, the boolean true (1) is added, moving the dot up. If “6” is held, 1 is subtracted, moving it down. Both keys pressed simultaneously cancel out. There is no boundary clamping, so the dot can wander off-screen.
Animation Method
The dot is animated by plotting at the new position (PLOT B,V) and then unplotting the previous position (UNPLOT B,X) using the saved value X=V. Since B advances by one pixel per iteration, this produces a smooth single-pixel trail-free movement across the screen.
Variable Summary
| Variable | Role |
|---|---|
C(6) | Array of gate Y-coordinates |
A | Gate index (1–6) during setup |
B | Current horizontal pixel column (3–63) |
V | Current vertical position of player dot |
X | Previous vertical position (for UNPLOT) |
Notable Anomalies
- When a gate is missed (
GOTO 80), rather than ending the game, the player’s Y position is silently reset toC(1)(the first gate’s Y value) and the loop continues. This may be an unintended consequence of the80+0arithmetic rather than a deliberate design choice — a “game over” would more typically jump to a non-existent line. - Gate Y-coordinates range from 13 to 25 (
INT(RND*12)+14), keeping them well within the lower half of the 44-pixel-high display. - The play loop starts at
B=3, giving the player a small lead before the first gate at column 10.
Content
Source Code
5 REM "SLALOM"
10 DIM C(6)
20 CLS
30 FOR A=1 TO 6
40 LET C(A)=INT (RND*12)+14
50 PLOT A*10,C(A)-1
60 PLOT A*10,C(A)+2
70 NEXT A
80 LET V=C(1)
90 FOR B=3 TO 63
100 IF B/10=INT (B/10) THEN GOTO 80+(30 AND V>=C(B/10) AND V<=C(B/10)+1)
110 PLOT B,V
120 LET X=V
130 LET V=V+(INKEY$="7")-(INKEY$="6")
140 UNPLOT B,X
150 NEXT B
160 RUN
170 SAVE "1022%9"
180 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
