Racer

Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Game

This program simulates a nine-lane racing game with betting mechanics, where the player wagers dollars on one of nine numbered racers. It defines six UDG characters (spanning character slots “a” through “m” and “h”) by POKEing 48 bytes of bitmap data to represent racer sprites, track graphics, and animation frames. The main race loop uses computed GO TO via the expression `r*1000` to dispatch randomly to one of nine racer-advance routines (lines 1000–9030), each of which moves a different racer across its screen row until it reaches column 31. SOUND commands with multiple channel parameters provide engine noise and race atmosphere, while BEEP produces pitch-varying tones tied to each racer’s current position. A world-record timer tracks elapsed tenths-of-seconds, and a short melody plays from DATA statements at race end using a READ/BEEP loop.


Program Analysis

Program Structure

The program divides into several logical phases:

  1. Initialization (lines 1–110): Sets paper/border/bright attributes, then POKEs UDG bitmap data for six character definitions covering slots "a" through "f" (48 bytes, 6 UDGs), "m" (8 bytes), and "h" (8 bytes).
  2. Track setup and betting (lines 132–138): Draws lane dividers with dashes, prompts for a chosen racer (1–9), and accepts a wager with a guard preventing over-betting.
  3. Race animation intro (lines 140–208): Displays a starting grid graphic, animates a flashing start sequence using UDG characters with SOUND effects, plots side boundary lines, and draws lane numbers.
  4. Main race loop (lines 209–220): Maintains a seconds/tenths timer, plays tick sounds, and uses GO TO r*1000 to randomly dispatch to one of nine racer routines.
  5. Racer advance routines (lines 1000–9030): Nine blocks, each handling one racer lane, advancing its sprite one column and checking for a finish at column 32.
  6. Finish sequence and scoring (lines 9500–9730): Announces the winner, plays a melody from DATA, checks/updates the world record, evaluates the bet, and offers replay.

UDG Definitions

Three separate FOR/READ/POKE loops load custom character bitmaps:

Loop (lines)Slots coveredBytes
10–70"a" through "f"48
80–90"m"8
100–110"h"8

The DATA statements use a variable n at several positions, but n is never initialized before the READ loops execute. This is a latent bug: n will default to 0 in most implementations, so those entries silently become 0, likely giving correct zero-byte rows intentionally or by convention.

Computed GO TO Dispatch

The core routing mechanism at line 220 is GO TO r*1000, where r is an integer from 1 to 9 produced by INT(RND*9+1) at line 210. This jumps to lines 1000, 2000, …, 9000 — one block per racer. Each block prints the racer’s UDG sprite at its current column, increments the column counter, checks for reaching column 32 (finish), and loops back to line 210. This is an efficient alternative to a long IF/THEN chain.

Race Timer

Lines 209–214 implement a software timer. Variable t counts tenths and s counts whole seconds. Each pass through the main loop increments t; when t reaches 9, it resets and s increments. The elapsed time is assembled at line 9508 as rt = s + (t/10), giving a single decimal value used for world-record comparison and display.

SOUND and BEEP Usage

SOUND commands appear extensively with multi-channel parameters (channels 6–13) to produce engine noise during race startup and running. BEEP is used for per-tick clicks and for the victory melody. The melody at lines 9521–9528 reads pairs of duration/pitch values from DATA, divides the duration by 16 to get fractional seconds, and calls BEEP in a loop until sentinel value 999 is encountered. The DATA spans five lines (9524–9528) covering two melodic phrases plus a terminating 999,999.

Betting and Scoring

The player’s bankroll is held in o (initialized to 10 at line 1). Variable l is the bet amount, validated at line 137. Winnings are calculated at line 9515 as b = INT((l*5) - (3*RND)), giving approximately 5× the stake with slight random variation. Line 9600 adds winnings if the chosen racer k equals r; line 9601 deducts the bet otherwise. Line 9610 stops the program if o drops to zero or below.

World Record Tracking

Variables wr (initialized to 100) and w track the best race time and winning racer number across games. Line 9530 updates the record if the current race time rt beats wr. The condition at line 9520 (IF wr>=rt THEN GO SUB 9509) triggers a celebratory UDG animation routine whenever a record is equaled or beaten.

Notable Techniques and Anomalies

  • Line 132 uses FOR x=PI TO 19 STEP 2, starting the loop at approximately 3.14159. Since the loop variable is used only as an AT row index, this effectively starts at row 3 (truncated), which is an unusual but functional choice.
  • The RESTORE 9529 / GO TO 9529 / RESTORE 9524 sequence at lines 9529 means the melody DATA is re-read from line 9524 after the first play, enabling replay across multiple race rounds.
  • Line 9511 contains NEXT g: RETURN, but the FOR loop for g at line 9509 has no corresponding NEXT that would be reached normally — line 9510 NEXTs and line 9511’s NEXT would fire only if control falls through, which it cannot due to PAUSE. The RETURN suggests this block was intended as a subroutine, but it is only ever reached via GO SUB 9509 which calls into the middle of a FOR loop structure — a structural oddity.
  • The replay loop at lines 9720–9730 animates a wipe effect then prints 350 space-asterisk pairs before clearing the screen and saving the program with SAVE "RACER" LINE 1, ensuring auto-restart on reload.
  • Variable reuse is notable: f, g, and b are used both as racer position counters in the mid-race routines and as general loop/calculation variables in the finish sequence, relying on the race being over before those variables are reused.

Content

Appears On

Pilot a flight from London, lay pipes against an AI opponent, find planets in the night sky, or teach a computer to guess animals — ISTUG Library 7 mixes strategy and science with some of the most inventive programs in the series.

Related Products

Related Articles

Related Content

Image Gallery

Source Code

    1 LET o=10: LET wr=100
    5 PAPER 7: BORDER 7: BRIGHT 0: CLS 
   10 FOR x=0 TO 47: READ n: POKE USR "a"+x,n: NEXT x
   20 DATA 12,n,120,94,90,48,36,n
   30 DATA 48,n,30,120,90,24,36,n
   40 DATA 48,n,31,249,24,120,78,194
   50 DATA 24,n,189,219,24,n,n,60
   60 DATA 153,n,255,24,n,36,66,195
   70 DATA 28,12,8,60,n,254,24,60
   80 FOR x=0 TO 7: READ n: POKE USR "m"+x,n: NEXT x
   90 DATA 12,n,248,159,24,30,114,67
  100 FOR x=0 TO 7: READ n: POKE USR "h"+x,n: NEXT x
  110 DATA 0,6,n,60,n,36,228,132
  132 FOR x=PI TO 19 STEP 2: PRINT AT x,0; BRIGHT 0; INK 0;"------------------------------": NEXT x
  134 INPUT "Who do you want to win 1 TO 9 ";k
  135 PRINT AT 0,0;"You have ";o;" dollars to bet.",,,
  136 INPUT "PLACE YOUR BETTS ";l
  137 IF l>o THEN GO TO 135
  138 PRINT AT 1,0;"YOU BET ";l;" on ";k;"   ",
  140 PRINT AT 0,0; BRIGHT 0; INK 2;"\: \..\..\..\: \..\..\..\..\..\..\: \..\..\..\.:\..\..\..\.:\..\..\..\.:\..\..\..\.:\..\..\..\.:\:.\..\..\..\..\.:\..\..\..\..\.:\..\..\..\..\.:\..\..\..\.:\..\..\..\.:\..\..\..\.:\..\..\..\.:": PAUSE 100
  190 RANDOMIZE : LET j=3: LET a=j: LET b=j: LET c=j: LET d=j: LET e=j: LET f=j: LET g=j: LET h=j: LET i=j
  200 FOR x=30 TO 0 STEP -1: SOUND 6,20;7,7;8,16-(x/2);9,16-(x/2);10,16-(x/2);12,255;13,1: PAUSE 10
  201 PAPER 6: PRINT AT 0,x;"\c";AT 1,30-x;"\a": PAUSE 5: PRINT AT 0,x;"\d";AT 1,30-x;"\d": PRINT AT 1,30-x*RND;"\f";AT 0,x*RND;"\f";AT 0,30-x*RND;"\f";AT 1,x*RND;"\f": NEXT x
  202 FOR x=1 TO 31: PAPER 6: BRIGHT 1: PRINT AT 0,x*RND;"\f";AT 1,x*RND;"\f": RANDOMIZE : PRINT AT 0,x*RND;"\f";AT 1,x*RND;"\f": NEXT x
  203 PRINT AT 0,0; BRIGHT 0; PAPER 6;"\:.\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\.:";AT 1,0;"\:.\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\.:_"
  205 FOR x=2 TO 18 STEP 2: PRINT AT x,0; INK x/6; PAPER 7; BRIGHT 1;x/2;" \d",,: PAUSE 5: NEXT x
  206 FOR y=10 TO 159: PLOT 24,y: PLOT 245,y: NEXT y
  207 FOR x=2 TO 18 STEP 2: PRINT AT x,0; INK x/6; PAPER 7; BRIGHT 1;x/2;" \h": NEXT x
  208 PAUSE 40: SOUND 6,15;7,7;8,16;9,16;10,16;12,10;13,0
  209 LET t=0: LET s=t
  210 LET r=INT (RND*9+1)
  211 LET t=t+1: IF t=9 THEN LET t=0: LET s=s+1
  212 PRINT AT 20,0;"SEC. TENTHS "
  213 PRINT AT 21,0;" \.'";s;"   : ";t;"\.'"
  214 IF t=9 THEN LET t=0: LET s=s+1
  215 BEEP .001,50
  216 SOUND 6,20;7,7;8,5;9,3;10,8;12,255;13,1:
  217 PRINT AT 0,31*RND; BRIGHT 0; PAPER 6; FLASH 1;"\f";AT 1,31*RND;"\f"
  218 PRINT AT 0,31*RND; BRIGHT 0; PAPER 6; FLASH 0;"\f";AT 1,31*RND;"\f"
  220 GO TO r*1000
 1000 PAPER 7: BRIGHT 1: INK 0: PRINT AT 2,a-1;"\m": BEEP .001,60-a: PRINT AT 2,a-1;" \a"
 1020 LET a=a+1: IF a=32 THEN GO TO 9500
 1030 GO TO 210
 2000 INK 3: PAPER 7: BRIGHT 1: PRINT AT 4,b-1;"\m": BEEP .001,60-b: PRINT AT 4,b-1;" \a"
 2020 LET b=b+1: IF b=32 THEN GO TO 9500
 2030 GO TO 210
 3000 INK 1: PAPER 7: BRIGHT 1: PRINT AT 6,c-1;"\m": BEEP .001,60-c: PRINT AT 6,c-1;" \a"
 3020 LET c=c+1: IF c=32 THEN GO TO 9500
 3030 GO TO 210
 4000 INK 3: PAPER 7: BRIGHT 1: PRINT AT 8,d-1;"\m": BEEP .001,40: PRINT AT 8,d-1; INK 0;" \a"
 4020 LET d=d+1: IF d=32 THEN GO TO 9500
 4030 GO TO 210
 5000 INK 0: PAPER 7: BRIGHT 1: PRINT AT 10,e-1;"\m": BEEP .001,45: PRINT AT 10,e-1;" \a"
 5020 LET e=e+1: IF e=32 THEN GO TO 9500
 5030 GO TO 210
 6000 PAPER 7: INK 2: BRIGHT 1: PRINT AT 12,f-1;"\m": BEEP .001,35: PRINT AT 12,f-1;" \a"
 6020 LET f=f+1: IF f=32 THEN GO TO 9500
 6030 GO TO 210
 7000 INK 1: PAPER 7: BRIGHT 1: PRINT AT 14,g-1;"\m": BEEP .001,60: PRINT AT 14,g-1;" \a"
 7020 LET g=g+1: IF g=32 THEN GO TO 9500
 7030 GO TO 210
 8000 INK 3: PAPER 7: BRIGHT 1: PRINT AT 16,h-1;"\m": BEEP .001,50-h: PRINT AT 16,h-1;" \a"
 8020 LET h=h+1: IF h=32 THEN GO TO 9500
 8030 GO TO 210
 9000 PAPER 7: BRIGHT 1: PRINT AT 18,j-1; INK 2;"\m": BEEP .001,60-j: PRINT AT 18,j-1;" \a"
 9020 LET j=j+1: IF j=32 THEN GO TO 9500
 9030 GO TO 210
 9500 BEEP .1,45: PRINT AT r*2,31; FLASH 1;"\m": PAUSE 30
 9501 PRINT AT r*2,31;" ": LET x=r*2: FOR u=x TO 21
 9502 BEEP .001,u+30: PRINT AT u,31;"\m": PAUSE 10: BEEP .001,u+33: PRINT AT u,31;"\a": BEEP .001,50: PAUSE 10: PRINT AT u,31;" "
 9505 NEXT u
 9507 FOR y=30 TO 16 STEP -1: PRINT AT 21,y;"\b ": BEEP .001,y+30: PAUSE 10: PRINT AT 21,y;"\c ": BEEP .001,40: PAUSE 10: NEXT y
 9508 LET rt=s+(t/10): GO TO 9512
 9509 PRINT AT 0,0;"\a";:: FOR g=0 TO 17: PRINT ; INK RND*3; PAPER 6; BRIGHT 1*RND; FLASH 1*RND;"\a\b\e \c\c\a\m\c \a\b\c\d\e\d\c \b\b \b\b\c\c\d\d\a\a\e\m\a\e\b\d\a";
 9510 PAUSE 10: SOUND 6,13;7,7;8,16;9,16;10,16;12,255;13,1: NEXT g
 9511 PAUSE 10: SOUND 6,15;7,7;8,16;9,16;10,16;12,255;13,1: NEXT g: RETURN 
 9512 LET rt=s+(t/10)
 9514 FOR f=1 TO 10: PRINT AT 20,16;"\e";AT 21,16;" ": BEEP .1,20+(f*3): PRINT AT 21,0;".The winner is  \d ";r;" in ";rt;"sec";AT 20,16;" ": BEEP .1,40: NEXT f
 9515 LET b=INT ((l*5)-(3*RND))
 9520 IF wr>=rt THEN GO SUB 9509
 9521 READ d,p: LET d=d/16
 9522 IF p=999 THEN GO TO 9529
 9523 BEEP d,p: GO TO 9521
 9524 DATA 4,7,8,7,2,4,4,4,4,7,8,7,2,2,4,2,4,4,4,5,4,7,4,9,4,11,8,7,8,69
 9525 DATA 4,7,8,7,2,4,4,4,4,7,8,7,2,2,4,2,4,14,4,13,4,14,4,16,4,9,8,14,8,69
 9526 DATA 4,7,8,16,2,16,4,14,4,12,8,12,2,11,4,11,4,12,4,14,4,11,4,9,4,7,8,12,8,69
 9527 DATA 4,12,8,12,2,9,4,9,4,12,8,12,2,7,4,7,4,7,4,9,4,12,4,7,4,14,16,12
 9528 DATA 999,999
 9529 RESTORE 9524: PAUSE 100
 9530 IF wr>rt THEN LET wr=rt: PRINT AT 19,0; FLASH 1;"#";r;" has set a World Record": LET w=r
 9540 PRINT AT 20,0;"The WORLD RECORD IS ";wr;" by #";w: PAUSE 200
 9600 IF r=k THEN PRINT AT 0,0;"YOU HAVE WON- ";b;"          ": LET o=o+b
 9601 IF r<>k THEN PRINT AT 0,0;"You lost $";l;".You have ";o-l;" left.": LET o=o-l
 9610 IF o<=0 THEN PRINT AT 0,10; FLASH 1;"You are busted!!!": STOP 
 9700 INPUT "Do you want to play again?  ";i$
 9711 IF i$="n" THEN STOP 
 9720 PRINT AT 21,0; INK 2;"________________"
 9721 FOR y=16 TO 0 STEP -1: PRINT AT 21,y;"\b ": BEEP .001,y+30: PAUSE 10: PRINT AT 21,y;"\c ": BEEP .001,40: PAUSE 10: NEXT y:
 9730 PRINT AT 0,0;" ";: FOR x=0 TO 350: PRINT " *";: BEEP .001,50: NEXT x: CLS 
 9740 SAVE "RACER" LINE 1

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top