--- title: "Horse Race" id: 56818 type: "computer_media" slug: "horse-race" url: "http://localhost/computer_media/horse-race/" markdown_url: "http://localhost/computer_media/horse-race.md" published_at: "2024-09-29T02:33:43+00:00" modified_at: "2026-03-30T21:20:54+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/09/307_HR.png" excerpt: "A pixel-based horse race simulation picks a random winner from five horses, each crawling across the screen one dot at a time — place your bets!" 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 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_contents: - id: 56738 title: "Timex Sinclair Public Domain Library Tape 1007" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1007/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/09/307_HR.png" media_type_tags: "Game" --- This program simulates a five-horse race at “Sportsmans Park” using the ZX81’s low-resolution pixel graphics. Each horse is represented by a single lit pixel moving horizontally across one of five fixed pixel rows, with the winning condition triggered when any horse’s x-coordinate reaches 60. A random number in the range 0–4 selects which horse advances one pixel per iteration, producing a simple probabilistic race. After a winner is determined, a flashing “WINNER” message is displayed by alternately printing and erasing the text in a loop before restarting the race. *** ## Program Analysis ### Program Structure The program is divided into three logical phases: 1. **Initialisation (lines 1–20):** Variables are zeroed, the track header and lane markers are printed, and a finish-line is drawn using a `FOR`/`PLOT` loop at x=61. 2. **Race loop (lines 22–93):** Horse positions are plotted, a random horse is chosen, its pixel is unplotted, its coordinate incremented, and replotted, repeating until a horse reaches x=60. 3. **Winner display and restart (lines 200–260):** A flashing “WINNER” banner loops 20 times, then `RUN` restarts the whole program. ### Variable Usage | Variable | Role | | --- | --- | | `A` | Horse 1 x-position (pixel row y=6) | | `B` | Horse 2 x-position (pixel row y=12) | | `E` | Horse 3 x-position (pixel row y=18) | | `F` | Horse 4 x-position (pixel row y=24) | | `G` | Horse 5 x-position (pixel row y=30) | | `C` | Random selector (0–4) choosing which horse advances | | `D` | Loop counter for drawing the finish line | | `X` | Loop counter for flashing the winner message | ### Graphics Technique Each horse is a single pixel, manipulated with `UNPLOT` to erase and `PLOT` to redraw at the incremented position. The pixel rows are spaced 6 units apart (y = 6, 12, 18, 24, 30), neatly separating the five lanes within the ZX81’s 44×64 pixel display. The finish line is drawn as a vertical column of pixels at x=61 using a `FOR D=0 TO 38 / PLOT 61,D / NEXT D` loop, covering the full usable vertical extent. ### FAST/SLOW Mode Usage The program switches to `FAST` mode during initialisation (line 2) to speed up the screen setup, then switches to `SLOW` mode at line 20 before the race begins. This ensures the pixel animation is visible rather than flickering by in a single unobserved burst. ### Race Logic and Dispatch At line 40, `C=INT(RND*5)` generates a value from 0 to 4. A chain of five `IF C=n THEN GOTO` statements (lines 44–52) dispatches to the appropriate horse-advance subroutine at lines 70, 75, 80, 85, or 90. Each of those three-line blocks unplots, increments, replots, and loops back to line 40. This pattern is equivalent to a computed `GO TO`, which the ZX81 lacks natively. ### Win Detection Line 42 checks whether any horse variable equals 60 using a compound `OR` condition. Importantly, this check occurs *before* the dispatch, so as soon as any horse reaches x=60 on the previous turn, the race ends. The winner is not explicitly identified; the program simply displays “WINNER” without stating which horse won, which is a notable functional omission. ### Winner Flash Effect Lines 200–220 implement a simple flash by alternately printing `"WINNER"` and six spaces at the same screen position inside a `FOR X=1 TO 20` loop. This produces a toggling on/off effect at the natural speed of the interpreter. ### Restart Behaviour Line 230 uses `RUN` to restart the program, which on the ZX81 clears all variables and begins from line 1, effectively resetting the race. Lines 240–260 (`CLEAR`, `SAVE`, `RUN`) are unreachable dead code, as `RUN` at line 230 unconditionally restarts execution. ### Anomalies and Notes - The lane markers printed at line 12 (characters “5” through “1” at column 31) label the horses in reverse order (5 at top, 1 at bottom), which may be counterintuitive. - No betting or user interaction is implemented despite the “FAST TRACK $2.00 WINDOW” header suggesting a wagering theme. - The finish line is drawn at x=61, but winning is checked at x=60, meaning a horse stops one pixel short of the drawn line rather than crossing it. - Lines 240–260 are dead code and will never execute during normal program flow. ## Source Code ``` 1 REM HORSE RACE 2 FAST 3 PRINT AT 0,5;"SPORTSMANS PARK" 4 PRINT AT 1,0;"FAST TRACK $2.00 WINDOW" 5 LET A=0 6 LET B=0 7 LET E=0 8 LET F=0 9 LET G=0 12 PRINT AT 6,31;"5";AT 9,31;"4";AT 12,31;"3";AT 15,31;"2";AT 18,31;"1" 14 FOR D=0 TO 38 16 PLOT 61,D 18 NEXT D 20 SLOW 22 PLOT A,6 24 PLOT B,12 26 PLOT E,18 28 PLOT F,24 30 PLOT G,30 40 LET C=INT (RND*5) 42 IF A=60 OR B=60 OR E=60 OR F=60 OR G=60 THEN GOTO 200 44 IF C=0 THEN GOTO 70 46 IF C=1 THEN GOTO 75 48 IF C=2 THEN GOTO 80 50 IF C=3 THEN GOTO 85 52 IF C=4 THEN GOTO 90 70 UNPLOT A,6 71 LET A=A+1 72 PLOT A,6 73 GOTO 40 75 UNPLOT B,12 76 LET B=B+1 77 PLOT B,12 78 GOTO 40 80 UNPLOT E,18 81 LET E=E+1 82 PLOT E,18 83 GOTO 40 85 UNPLOT F,24 86 LET F=F+1 87 PLOT F,24 88 GOTO 40 90 UNPLOT G,30 91 LET G=G+1 92 PLOT G,30 93 GOTO 40 200 FOR X=1 TO 20 201 PRINT AT 21,25;"WINNER" 210 PRINT AT 21,25;" " 220 NEXT X 230 RUN 240 CLEAR 250 SAVE "1030%7" 260 RUN ```