--- title: "Derby Day" id: 71018 type: "computer_media" slug: "derby-day" url: "http://localhost/computer_media/derby-day/" markdown_url: "http://localhost/computer_media/derby-day.md" published_at: "2026-08-26T01:18:15+00:00" modified_at: "2026-08-26T01:20:20+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/08/derby-day-1.png" alt: "Derby Day screen" excerpt: "A five-race horse racing game where up to five players bet their $50 stakes against randomly generated odds, with animated UDG horses galloping across the screen." 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_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Derby%20Day%20%28198x%29%28-%29%28TS2068%29%28US%29%28Program%29.zip" tsrun_member: "Derby Day (198x)(-)(TS2068)(US)(Program).tap" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/08/derby-day-1.png" alt: "Derby Day screen" - url: "http://localhost/wp-content/uploads/2026/08/derby-day-2.png" alt: "Derby Day screen" media_type_tags: "Game" --- # Derby Day Derby Day is a multi-player horse racing game for up to five players, spanning five races with betting, odds, and a cumulative money system. Each player starts with $50 and places bets before each race; winnings are calculated by multiplying the stake by the horse’s randomly generated odds. The race animation uses two alternating sets of UDG (User Defined Graphics) characters—17 UDGs loaded via POKE USR in a DATA-driven setup loop—to simulate a galloping horse moving across the screen. Horse positions are tracked in array c(p) and advanced each iteration by a combination of the inverse of the odds (1/d(a)) plus a random integer, so higher-odds (longer-shot) horses advance more slowly on average. After all five races, the player with the most money is declared the overall winner. *** ## Program Analysis ### Program Structure The program is organized into a main loop and several subroutines. Initialization is handled by two subroutines called at startup: line 750 loads UDG data, and line 570 sets up screen colors, collects player count, names, and assigns horse names from a DATA statement at line 950. The main game loop (lines 40–340) runs five races (FOR r=1 TO 5). Within each race, subroutine 460 handles the betting phase and subroutine 140–260 manages the race animation. After all races, lines 350–430 tally totals and declare a winner. ### UDG Horse Animation Lines 750–770 poke 137 bytes (0 to 136, covering 17 UDGs: A through Q) into UDG memory using `POKE USR "[UDG-A]"+a` inside a READ loop. The DATA at lines 780–940 contains the pixel patterns. The variable `u` appears in several DATA lines without being defined as a numeric literal; it is an undefined variable that the BASIC interpreter will treat as 0, effectively acting as a zero-byte placeholder in the UDG patterns. Two sets of three-line sprite rows are defined in string variables: - `a$`, `b$`, `c$` — first animation frame (lines 580–600) - `d$` (reusing b$ row top), `e$` — second animation frame (lines 610–620) The race loop alternates between printing frame 1 (lines 170) and frame 2 (lines 220) at successive horizontal positions, giving the impression of galloping motion. ### Race Mechanics Each horse’s position is stored in `c(a)`, initialized to 0 (via `DIM c(p)` at line 150). Each iteration advances the position by `1/d(a) + INT(RND*2)`, where `d(a)` is the horse’s odds. This means a horse at 1:1 odds gains between 1 and 2 units per step, while a 10:1 longshot gains only 0.1 to 1.1 units, giving favorites a statistical advantage. The finish line is at column 25 (`IF c(a)>25 THEN GO TO 270`), checked after each movement step in both frame loops. ### Betting System Subroutine 460 iterates through players, printing each one’s current balance and prompting for a bet. If a player has less than $1, they skip betting (line 520). The input is validated so a player cannot bet more than they have (line 530). The stake is subtracted immediately from `m(a)` (line 540); on a win, the payout `d(a)*s(a)` plus the original stake is added back (line 320). Players who run out of money continue to participate but cannot bet. ### Notable Techniques and Idioms - The BEEP calls in the betting subroutine (line 460) scale duration with player count (`.002*p`), giving a slightly longer fanfare for more players. - `PAUSE 0` at line 740 followed by a RETURN is used as a “press any key to continue” gate, a standard idiom. - Horse names are stored in a DATA block at line 950 and READ into `h$(p,15)` via RESTORE/READ at lines 710–730, allowing easy customization. - The overall winner check at line 390 uses a running maximum (`tot`) initialized to `p` (the number of players, a very low threshold), which works correctly as long as any player has more money than the player count—a fragile but functional approach. - `CIRCLE INK 2;240,165,10` and a vertical DRAW at line 140 draw a finish-post graphic before each race. - Line 670 uses `PI` as a column argument to `PRINT AT`; since PI ≈ 3.14159, it truncates to column 3, centering the prompt. ### Bugs and Anomalies - The variable `u` is never assigned a value and appears in DATA statements (e.g., lines 780, 790, 810, etc.). When READ into a numeric variable, an uninitialized `u` evaluates to 0, so these entries silently become zero bytes. This is almost certainly intentional shorthand for 0 in the UDG data. - Line 500 prints `"Qwner:-"` — a typo for “Owner:-“. - The race animation loop (lines 160–260) does not erase the previous sprite position before drawing the new one; it relies on the sprite moving far enough right that the old image is left behind, which is acceptable for a scrolling race but means multiple ghost images accumulate on screen during the race. - The winning player determination at line 390 initializes `tot=p` rather than a sentinel like 0 or -1. If all players finish with $p or less in money, the winner variable `win` may be uninitialized, causing unpredictable output at lines 410–430. - After line 440, the program jumps back to line 30 (GO SUB 570), which re-initializes all player data including names and money, effectively starting a completely new game rather than continuing with existing players—despite the prompt saying “another game,” this is consistent behavior. ### Data Summary | Array | Size | Purpose | | --- | --- | --- | | `d(p)` | p elements | Odds for each horse in current race | | `c(p)` | p elements | Horizontal screen position of each horse | | `s(p)` | p elements | Current race stake per player | | `m(p)` | p elements | Cumulative money per player | | `n$(p,10)` | p×10 chars | Player names | | `h$(p,15)` | p×15 chars | Horse names | ## Source Code ``` 10 REM Derby Day 20 GO SUB 750 30 GO SUB 570 40 FOR r=1 TO 5 50 CLS 60 PRINT "Race Number ";r 70 DIM d(p) 80 FOR a=1 TO p:LET d(a)= INT (RND*10)+1 90 PRINT '"The Odds On ";h$(a) 100 PRINT "to win are ";d(a);":1" 110 NEXT a 120 GO SUB 460 130 GO SUB 740 140 CLS :CIRCLE INK 2;240,165,10:PLOT 240,155:DRAW INK 2;0,-140:FOR a=1 TO p:PRINT AT a*3+3,31;a:NEXT a 150 DIM c(p) 160 FOR a=1 TO p 170 PRINT AT a*3+2,c(a);a$; AT a*3+3,c(a);b$; AT a*3+4,c(a);c$ 180 LET c(a)=c(a)+(1/d(a)+ INT (RND*2)) 190 IF c(a)>25 THEN GO TO 270 200 NEXT a 210 FOR a=1 TO p:BEEP .008,c(a) 220 PRINT AT a*3+2,c(a);a$; AT a*3+3,c(a);d$; AT a*3+4,c(a);e$ 230 LET c(a)=c(a)+(1/d(a)+ INT (RND*2)) 240 IF c(a)>25 THEN GO TO 270 250 NEXT a 260 GO TO 160 270 LET w$=h$(a) 280 PAUSE 100:CLS 290 PRINT "The Winner is ";w$ 300 PRINT "Owned by ";n$(a) 310 LET ws=d(a)*s(a) 320 PRINT '"Who Wins $";ws:LET m(a)=m(a)+ws+s(a) 330 FOR z=1 TO 50:BEEP .008,z:BEEP .008,-z:NEXT z 340 NEXT r 350 CLS 360 LET tot=p:PRINT "At the end of the game " 370 FOR a=1 TO p 380 PRINT n$(a);" has ";m(a) 390 IF m(a)>tot THEN LET tot=m(a):LET win=a 400 NEXT a 410 PRINT '"So the winner is ";n$(win) 420 PRINT "On ";h$(win) 430 PRINT "with $";m(win) 440 INPUT "Press ENTER for another game "; LINE a$:GO TO 30 450 STOP 460 FOR z=1 TO 50:BEEP .002*p,z:BEEP .008,-z:NEXT z 470 FOR a=1 TO p 480 CLS 490 PRINT "Horse:- ";h$(a) 500 PRINT "Qwner:- ";n$(a) 510 PRINT '"You have $";m(a) 520 IF m(a)<1 THEN PRINT "You have no money so you cannot place a bet ":PAUSE 150:NEXT a:RETURN 530 INPUT "How much money will you bet on the next race? $";s(a):IF s(a)>m(a) THEN GO TO 530 540 LET m(a)=m(a)-s(a) 550 NEXT a 560 RETURN 570 BORDER 4:PAPER 4:INK 9:CLS :BEEP .1,10:BEEP .2,15 580 LET a$=" [UDG-A][UDG-B][UDG-C][UDG-D]" 590 LET b$=" [UDG-E][UDG-F][UDG-G][UDG-H]" 600 LET c$=" [UDG-I][UDG-J][UDG-K][UDG-L]" 610 LET d$=" [UDG-E][UDG-M][UDG-N][UDG-O]" 620 LET e$=" [UDG-I][UDG-P][UDG-Q]" 630 PRINT AT 1,12;"ASCOT" 640 INPUT "How many players? (max 5)"; LINE p$:IF p$<"1" OR p$>"5" THEN GO TO 640 650 LET p= VAL p$:DIM s(p):DIM m(p):DIM n$(p,10):DIM h$(p,15) 660 FOR a=1 TO p 670 PRINT AT 5, PI;"Type in name of player #";a 680 INPUT "Max 10 letters "; LINE n$(a) 690 LET m(a)=50:NEXT a 700 CLS 710 RESTORE 950:FOR a=1 TO p 720 READ h$(a):PRINT n$(a);" now owns "'h$(a)'' 730 NEXT a 740 PRINT #1;" Press any key to continue":PAUSE 0:RETURN 750 FOR a=0 TO 136 760 READ u:POKE USR "[UDG-A]"+a,u 770 NEXT a:RETURN 780 DATA 0,u,u,u,u,u,u, PI 790 DATA 0,u,u,u,u,1,113,207 800 DATA 0,28,18,42,87,132,15,238 810 DATA 0,u,16,248,60,124,199,131 820 DATA 5,13,u,9,u,u,u,0 830 DATA 9,16,0,144,157,178,192,192 840 DATA 221,209,33,1,194,242,11,10 850 DATA 128,0,u,u,u,u,u,128 860 DATA PI,2,u,u,u,1,0,u 870 DATA 192,u,96,32,16,32,0,u 880 DATA 1,28,25,19,18,8,0,u 890 DATA 128,u,u,0,u,u,u,u 900 DATA 16,0,16,144,177,167,64,128 910 DATA 69,1,u,u,194,246,20,20 920 DATA 128,0,u,u,u,u,u,u 930 DATA 128,u,u,u,u,84,0,u 940 DATA 28,u,24,u,u,20,12,10,0 950 DATA "Red Gin","Sumley Gilds","Sparkle","Danny Boy","Shergart" 960 SAVE "Derby Day" LINE 0:BEEP .4,15 ```