Wagoner’s Walk is a horse-racing simulation — here with slow scrapyard wagons — in which the player starts with $200, views the four contestants in an animated paddock sequence, places a bet on one wagon, then watches a text-mode race unfold. The race engine works by randomly incrementing each wagon’s horizontal screen position (array B) one step per turn, firing a BEEP for each move, until the first wagon reaches column 24. A time-bonus mechanism using random targets Y and Z rewards fast finishes, while a computed GO TO at line 1560 selects one of five random taunting messages before each replay. The program was adapted from Tim Hartnell’s book “51 Game Programs for TS1000,” with color attributes and BEEP sound calls added for the TS2068.
Program Analysis
Program Structure
The program is divided into clearly separable phases, each occupying a distinct line-number range:
- Lines 1–35: Initialization, border/ink/paper setup, and rules display.
- Lines 40–250: Data setup — cash (
CR), wagon names (N$), sprite frames (A$), starting positions (A), progress counters (B), and decorative strings. - Lines 480–570: Paddock animation — scrolling each wagon across the screen.
- Lines 580–820: Betting input and validation.
- Lines 825–889: Pre-race countdown sequence with BEEP sound effects.
- Lines 1000–1145: Race track setup and the core race subroutine at
GO SUB 1100. - Lines 1150–1210: Main race loop — incrementing wagon positions and updating the display.
- Lines 1300–1390: Winner announcement with flashing text.
- Lines 1400–1665: Result calculation, play-again logic, and random taunt selection.
- Lines 3000–3110: Win payout with optional time bonus.
- Lines 5000–5010: Short delay subroutine.
- Lines 6000–8200: End-game conditions (bust, rich, quit).
Sprite and Animation System
Each wagon is represented as a 4-row × 7-column sprite stored in the three-dimensional string array A$(4,4,7) — four wagons, four rows each, seven characters wide. The four rows encode the wagon body (A$(N,1)), driver name (A$(N,2)), undercarriage (A$(N,3)), and wheels (A$(N,4)). Block graphic escapes such as \:: (█) and \..O produce the visual wagon shape. The paddock display loops over columns 0 to 31−(7×N) with FOR O, printing all four rows at each position, creating a simple scroll effect for each wagon.
Race Engine
The race itself uses array B(4) to track how far each wagon has advanced horizontally. On each iteration of the main loop (lines 1160–1210), a random wagon index P is selected with INT(RND*4)+1, its position B(P) is incremented by 1, and the sprite drawing subroutine at line 1100 is called. The subroutine checks whether any wagon has reached column 24 (IF B(N)=24 THEN GO TO 1300) and triggers the winner sequence if so. The winner’s wagon index is captured in X=N at line 1300 before N is reused in the victory loop.
Computed GO TO for Random Taunts
At line 1560, the program uses a computed GO TO to select one of five sarcastic messages for the player who chooses to play again:
LET P=INT(RND*5)+1generates a value 1–5.GO TO 1560+(10*P)branches to lines 1570, 1580, 1590, 1600, or 1610.
Each branch prints its message, pauses, then falls through or jumps to line 1650 to reset wagon positions. This is a compact alternative to a series of IF checks.
Time Bonus Mechanism
Before the race, lines 887–889 generate two random values: Y = INT(RND*20)+10 (bonus amount, $10–$29) and Z = INT(RND*20)+60 (time threshold, 60–79 units). After the race, if the player’s wagon won and the elapsed time T is less than Z, the bonus Y is added to CR (line 3100–3105). Otherwise no bonus is awarded (line 3060).
Payout Logic
A winning bet pays 2-to-1 plus the returned stake, effectively tripling the bet: CR = CR + (M*3) at line 3050. The betting limit is enforced as M <= INT(CR/2)+1, allowing the player to bet just over half their cash. End-game conditions are:
| Condition | Line | Outcome |
|---|---|---|
CR <= 0 | 1480 | Bust — GO TO 7000 |
CR >= 500 | 1490 | House limit exceeded — GO TO 6000 |
| Player quits | 1520 | GO TO 8000 |
Screen Layout and Color
Lines 1 and 5 set BORDER 2 (red), INK 1 (blue), and PAPER 6 (yellow) for the entire display. The POKE 23609,50 at line 1 sets the system variable ATTR-P (permanent attribute byte) to color value 50, which encodes paper 6 / ink 2. During the winner announcement, FLASH 1 is applied to the “A WINNER” text and then cancelled with FLASH 0 at line 1321. POKE 16418 at lines 1330 and 1410 manipulates the display file pointer — this is a TS2068/Spectrum system variable (BORDCR or equivalent) used here to alter the border color between red and black during the winner sequence.
Delay Subroutine
The subroutine at line 5000 is a simple busy-wait loop of 25 iterations with no body (FOR N=1 TO 25: NEXT N: RETURN). It is called multiple times (lines 890, 900, 1153, 1155, 1157, 1659–1665) as a short pause between display events. Because it reuses N, callers must not rely on N being preserved across the call.
Notable Bugs and Anomalies
- Input validation gap (line 630):
IF W>0 AND W<5 AND W=INT W THEN GO TO 700— a non-integer input such as 1.5 falls through to the “does not run” message at line 650, which printsW— potentially a non-integer value — as a wagon number, which is mildly confusing but harmless. - Winner variable collision (line 1300): The winner’s wagon index is captured as
LET X=Nimmediately beforeNis reused in the flash loop at line 1305. This is handled correctly. - UDG escape
\fat line 1040:PRINT AT N,30;"\: \f"— the\fescape is not a standard ZX Spectrum block graphic; it would print UDG ‘f’ (char 150), whose appearance depends on whether that UDG has been defined. No UDG definitions appear in the program, so it would display as an undefined graphic. - Paddock scroll asymmetry (line 505): The scroll range
FOR O=0 TO 31-(7*N)means wagon 1 scrolls 24 columns, wagon 2 scrolls 17, wagon 3 scrolls 10, and wagon 4 scrolls only 3 — so later wagons receive progressively shorter paddock sequences. - A$(3,2) content (line 140):
" \jAC\k\. \.."mixes a lower-case escape\jwith literal uppercaseACfor wagon 3 (“JACK”), while wagons 1, 2, and 4 use all lower-case escapes. This is inconsistent but functional if\jmaps to a block graphic that visually completes the name.
Content
Source Code
1 CLS : POKE 23609,50
2 REM TRANSLATED FOR 2068 WITH COLOR AND SOUND ADDED
3 REM PLEASE,SOMEBODY, PUT SOME FIRE INTO THE CHARIOTS.
4 REM P.56 OF"51 GAME PROGRAMS FOR TS1000" BY TIM HARTNELL
5 BORDER 2: INK 1: PAPER 6
10 PRINT AT 3,10;"WAGONER'S WALK": REM TROT ANYONE?
11 PRINT "################################"
12 PRINT AT 5,12;"RULES"
15 PRINT ,,"YOU HAVE $200. YOU HAVE BEEN","INVITED TO A DAY AT THE RACES","-SO WATCH YOUR MONEY.THERE ARE"
20 PRINT "4 WAGONS IN THE RACE, ALL FROM ANEARBY SCRAPYARD-SO THEY DO TEND TO BE RATHER SLOW."
25 PRINT ,,"YOU ARE INVITED TO BET ON","ONE OF THEM TO WIN. FIRST,","HOWEVER, YOU MAY SEE THEM IN THE PADDOCK."
30 PRINT ,,"PRESS""C""TO CONTINUE"
35 IF INKEY$<>"C" THEN GO TO 35
40 CLS
45 LET CR=200
50 DIM N$(4,4)
60 LET N$(1)="JIM"
70 LET N$(2)="JOE"
80 LET N$(3)="JACK"
90 LET N$(4)="JOHN"
100 DIM A$(4,4,7)
105 FOR N=1 TO 4
110 LET A$(N,1)=" \::\::\::\: "
115 LET A$(N,3)=" \::\::\::\::\::"
120 LET A$(N,4)="\..\..O\..\..O\.."
125 NEXT N
130 LET A$(1,2)=" \j\i\m \. \.."
135 LET A$(2,2)=" \j\o\e \. \.."
140 LET A$(3,2)=" \jAC\k\. \.."
145 LET A$(4,2)=" \j\o\h\n\. \.."
150 LET B$="################################"
155 LET C$="::::::::::::::::::::::::::::::::"
160 DIM A(4)
170 LET A(1)=2
180 LET A(2)=7
190 LET A(3)=12
200 LET A(4)=17
210 DIM B(4)
220 FOR N=1 TO 4
230 LET B(N)=0
240 NEXT N
250 LET X$="\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'"
480 PRINT AT 7,0;"WAGON:","DRIVER:"
490 PRINT AT 3,0;C$;B$
500 FOR N=1 TO 4
502 PRINT AT 8+N,0;N,N$(N)
505 FOR O=0 TO 31-(7*N)
510 FOR P=1 TO 4
515 PRINT AT 0+P-1,O;A$(N,P)
520 NEXT P
525 NEXT O
535 NEXT N
537 PRINT AT 15,0;
540 PRINT ,,B$
550 PRINT ,,"WHEN YOU HAVE SEEN ENOUGH OF","THEM, PRESS ""C"""
560 IF INKEY$<>"C" THEN GO TO 560
570 CLS
580 PRINT "ALL RIGHT, YOU HAVE $"; CR
590 PRINT " -REMEMBER, THE WINNER PAYS AT 2 TO 1 (+ A BONUS ?);BUT IF YOU LOSE, YOUR STAKE IS DEDUCTED"
600 PRINT ,,"PRESS THE NO. CORRESPONDING TO"," THE WAGON YOU WISH TO BET ON"," + <ENTER>"
610 PRINT "(1,2,3, OR 4)"
620 INPUT W
630 IF W>0 AND W<5 AND W=INT W THEN GO TO 700
640 CLS
650 PRINT " ? -BUT WAGON ";W;" DOES NOT ","RUN IN THIS RACE--DO NOT CHEAT THE BOOKIES"
660 PRINT
670 GO TO 600
700 CLS
710 PRINT "YOU BACKED WAGON ";W
720 PRINT "- ";N$(W);" WILL BE PLEASED"
730 PRINT ,,"BUT HOW MUCH DO YOU WISH TO BET?(LIMIT:$";INT (CR/2)+1;")"
765 PRINT ,,"-SAME PROCEDURE AS BEFORE"
770 INPUT M
775 CLS
780 IF M<1 THEN GO TO 800
785 IF M>CR/2+1 THEN GO TO 805
790 IF M>CR THEN GO TO 810
795 GO TO 820
800 PRINT "- WHAT THE HECK ARE YOU PLAYING AT?"
802 PRINT "-COMMON SENSE SHOULD TELL YOU TO BET AT LEAST $1"
803 PRINT "HOW MUCH DO YOU REALLY MEAN?"
804 GO TO 770
805 PRINT "DON'T BE GREEDY"
806 GO TO 803
810 PRINT "BUT YOU HAVE ONLY $";CR
815 GO TO 803
820 PRINT "$";M;" BET"
825 PRINT "THE RACE STARTS SHORTLY...","THE RACERS ARE TUNING UP","THEIR ENGINES..."
830 PRINT ,,B$,,
835 FOR N=1 TO 60
840 NEXT N
845 FOR N=1 TO 4
850 PRINT "PHUT..";: BEEP .5,-30
855 FOR O=1 TO 30
860 NEXT O
865 NEXT N
870 PRINT "BANGGGG": BEEP 1,-40
875 FOR N=1 TO 50
880 NEXT N
885 CLS
887 LET Y=INT (RND*20)+10
888 LET Z=INT (RND*20)+60
889 PRINT AT 10,0;"BONUS $ ";Y;" IF YOUR WAGON WINS","IN LESS THAN ";Z;" TIME UNITS": PAUSE 300
890 GO SUB 5000
900 GO SUB 5000
905 CLS
1000 FOR N=1 TO 21 STEP 5
1010 PRINT AT N,0;B$
1015 PRINT AT N-1,0;C$
1020 NEXT N
1030 FOR N=1 TO 21
1040 PRINT AT N,7;"S";AT N,30;"\: \f"
1050 NEXT N
1060 GO SUB 1100
1070 GO TO 1150
1100 FOR N=1 TO 4
1110 FOR O=1 TO 4
1120 PRINT AT A(N)+(O-1),B(N);A$(N,O)
1130 NEXT O
1135 IF B(N)=24 THEN GO TO 1300
1140 NEXT N
1145 RETURN
1150 LET T=0
1151 PRINT AT 0,0;"$";M;" ON ";W;" ";N$(W)
1152 BEEP .05,20: PRINT AT 4,10;"GET READY"
1153 GO SUB 5000
1154 BEEP .05,30: PRINT AT 4,14;"SET "
1155 GO SUB 5000
1156 BEEP .05,40: PRINT AT 4,11;"O "
1157 GO SUB 5000
1158 PRINT AT 4,10;" "
1160 PRINT AT 0,15;"TIME ";T
1170 LET P=INT (RND*4)+1
1175 BEEP .005,P*10
1180 LET B(P)=B(P)+1
1190 GO SUB 1100
1200 LET T=T+1
1210 GO TO 1160
1300 LET X=N
1305 FOR N=1 TO 60
1310 PRINT AT 0,20;"A WINNER";AT 0,20; FLASH 1;"A WINNER": BEEP .01,N
1320 NEXT N
1321 FLASH 0
1330 POKE 16418,0
1340 FOR N=0 TO 20
1350 PRINT AT N,0;X$
1360 NEXT N
1370 PRINT "WINNER ";X;" ";N$(X);" TIME ";T
1380 FOR N=1 TO 240
1390 NEXT N
1400 CLS
1410 POKE 16418,2
1420 IF X=W THEN GO TO 3000
1430 PRINT "*********YOU LOST****************"
1440 PRINT ,,"YOU MUST PAY YOUR DEBT"
1450 PRINT AT 10,0;"YOU HAD:","$";CR
1460 PRINT "YOU LOST :","$";M
1465 LET CR=CR-M
1470 PRINT ,,"YOU NOW HAVE:","$";CR
1480 IF CR<=0 THEN GO TO 7000
1490 IF CR>=500 THEN GO TO 6000
1500 PRINT ,,B$,,
1510 PRINT "PRESS""C""TO PLAY AGAIN","...OR""S""TO QUIT"
1520 IF INKEY$="S" THEN GO TO 8000
1530 IF INKEY$<>"C" THEN GO TO 1520
1540 CLS
1550 LET P=INT (RND*5)+1
1560 GO TO 1560+(10*P)
1570 PRINT "GULLIBLE, AREN'T YOU?"
1573 PAUSE 180
1575 GO TO 1650
1580 PRINT "FORTUNE FAVORS THE BRAVE"
1583 PAUSE 180
1585 GO TO 1650
1590 PRINT "OK--,BUT YOU MUST PHONE HOME TO TELL YOUR MOTHER"
1593 PAUSE 180
1595 GO TO 1650
1600 PRINT "TUT,TUT, GAMBLING ADDICT"
1603 PAUSE 180
1605 GO TO 1650
1610 PRINT "OH, WELL, I'M GAME IF YOU ARE."
1650 FOR N=1 TO 4
1651 LET B(N)=0
1652 NEXT N
1653 PRINT AT 15,0;"BUT YOU DON'T GET TO SEE THEM IN THE PADDOCK THIS TIME"
1655 PAUSE 180
1659 GO SUB 5000
1660 GO SUB 5000
1665 GO SUB 5000
1670 GO TO 570
3000 PRINT "***********YOU WON**************"
3010 PRINT ,,"NOW YOU COLLECT YOUR WINNINGS"
3020 PRINT AT 10,0;"YOU HAD:","$";CR
3030 PRINT "WIN AT 2 TO 1:","$";M*2
3040 PRINT "+ STAKE:","$";M
3050 LET CR=CR+(M*3)
3055 IF T<Z THEN GO TO 3100
3060 PRINT "NO TIME BONUS:","$0"
3070 GO TO 1470
3100 PRINT "TIME BONUS:","$";Y
3105 LET CR=CR+Y
3110 GO TO 1470
5000 FOR N=1 TO 25
5005 NEXT N
5010 RETURN
6000 PRINT ,,"YOU HAVE EXCEEDED THE HOUSE","LIMITS OF $500 AND HAVE BEEN"
6010 PRINT "FORCED TO RETIRE FROM THE GAME WITH YOUR WEALTH",,,"WILL YOU MARRY ME?"
6020 STOP
7000 PRINT "YOU ARE SHORT. REMEMBER YOU OWE THE COMPUTER $200. YOU MAY LEAVE AN I.O.U."
7010 STOP
8000 CLS
8010 FOR N=1 TO 15
8020 PRINT "CHICKEN"
8030 NEXT N
8040 PRINT AT 15,0;B$,,
8050 IF CR>200 THEN GO TO 8100
8060 IF CR=200 THEN GO TO 8200
8070 PRINT "BUT YOU STILL OWE THE COMPUTER","$";200-CR
8080 STOP
8100 PRINT "BUT YOU CAN FORFEIT YOUR $ "; CR-200;" PROFIT AS A TIP TO THE COMPUTER"
8110 STOP
8200 PRINT "BUT YOU ONLY BROKE EVEN"
9997 STOP
9998 SAVE "WAGONERS" LINE 1
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.


