Slalom

This file is part of Timex Sinclair Public Domain Library Tape 1005. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Game

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.

  1. Setup (lines 10–70): Dimensions array C(6), clears the screen, then randomly places six gates. Each gate occupies column A*10 and consists of two pixels at C(A)-1 and C(A)+2, leaving a one-pixel gap at C(A) and C(A)+1 for the player to pass through.
  2. Play loop (lines 80–150): Iterates B from 3 to 63 (the horizontal pixel range), moving the player dot column by column. At every gate column (B/10 is an integer), a collision check is performed.
  3. Restart (line 160): RUN loops 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

VariableRole
C(6)Array of gate Y-coordinates
AGate index (1–6) during setup
BCurrent horizontal pixel column (3–63)
VCurrent vertical position of player dot
XPrevious 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 to C(1) (the first gate’s Y value) and the loop continues. This may be an unintended consequence of the 80+0 arithmetic 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.

Appears On

Tape 1005 of the Timex Sinclair Public Domain Library. Assembled by Tim Ward from many sources.

Image Gallery

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.