--- title: "Tollbooth" id: 57652 type: "computer_media" slug: "tollbooth" url: "http://localhost/computer_media/tollbooth/" markdown_url: "http://localhost/computer_media/tollbooth.md" published_at: "2024-10-06T01:31:11+00:00" modified_at: "2026-04-03T07:58:09+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/toll-booth.png" excerpt: "Watch cars and trucks navigate toward toll booths while the program tallies revenue in real time, using block graphics and trigonometry to build a surprisingly detailed road scene." 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/" indiv: - name: "Gene G. Buza" slug: "gene-g-buza" taxonomy: "indiv" url: "http://localhost/indiv/gene-g-buza/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_contents: - id: 56728 title: "Synchro-Sette September 1983" type: "computer_media" url: "http://localhost/computer_media/synchro-sette-september-1983/" media_type: "Program" programmers: - name: "Gene G. Buza" slug: "gene-g-buza" taxonomy: "indiv" url: "http://localhost/indiv/gene-g-buza/" mediadate: "September 1983" images: - url: "http://localhost/wp-content/uploads/2024/10/toll-booth.png" media_type_tags: "Game" --- This program simulates a toll booth traffic scene, animating vehicles moving down the screen toward toll booths and then being directed into lanes. Each vehicle is randomly assigned as either a car (“%C”) or a truck (“%T”), and the program tracks cumulative toll revenue — 30 cents per car and 60 cents per truck — stored in array element S(32). The road scene is drawn using block graphics characters to depict booth structures, lane dividers, and a curved on-ramp plotted pixel by pixel with PLOT and SIN. After all vehicles have been processed, the simulation pauses and then restarts with RUN. *** ## Program Structure The program is divided into clearly separated routines accessed via `GOSUB`: 1. **Initialisation (lines 10–180):** Sets display mode, prompts for vehicle count, draws the static scene (booths, road markings, curved ramp). 2. **Main loop (lines 185–399):** Iterates `HH` times, each iteration spawning one vehicle, animating it down the screen, directing it to a lane, and updating the score. 3. **Vehicle approach from top (lines 2000–2550):** Animates the vehicle from row 20 down to row 9, with a random or type-forced lane-change decision at the midpoint. 4. **Lane wander during descent (lines 300–360):** Moves the vehicle from row 8 to row 2 with bounded random horizontal drift. 5. **Toll lane assignment (lines 4000–4130):** Snaps the vehicle’s column to the nearest lane, increments that lane’s counter, flashes a symbol, and updates the revenue display. 6. **Revenue formatting (lines 5000–5030):** Converts the running total to a string and pads it to two decimal places. 7. **Reset subroutine (line 3000):** Resets position variables `I` and `II` to column 15 for each new vehicle. ### Scene Construction The static road scene is assembled entirely from block graphics literals embedded in `PRINT AT` statements. The three booth structures (lines 75–90 and 120) use `▌`, `▐`, `▄`, `▀`, and `▟` characters to create box outlines. The curved on-ramp is drawn pixel-by-pixel in two loops (lines 130–180) using `PLOT 24-24*SIN(N/72*PI),N` and `PLOT 39+24*SIN(N/72*PI),N`, producing sinusoidal merge curves for each carriageway. ### Vehicle Representation Vehicles are represented as two-character strings stored in `A$`. The token `%T` represents a truck and `%C` a car. These are printed at a screen position and the previous position is erased by printing a space at the trailing coordinate stored in `II`. | Token | Type | Toll | Lane behaviour | | --- | --- | --- | --- | | `%T` | Truck | £0.60 | Always forced right (RR=1) | | `%C` | Car | £0.30 | Random left or right lane | ### Lane Boundary Enforcement During the descent (lines 305–308) the column variable `I` is clamped with four conditional guards: - `IF I<4 THEN LET I=4` — left road edge - `IF RR=0 AND I>13 THEN LET I=13` — right edge of left carriageway - `IF I<18 AND RR=1 THEN LET I=18` — left edge of right carriageway - `IF I>27 THEN LET I=27` — right road edge This dual-carriageway model means lane direction (`RR`) is decided before the wander phase and then enforced throughout. ### Toll Lane Snapping At line 4000–4002, the vehicle’s column is snapped to one of several discrete lane positions using arithmetic rounding: - Left lanes: `I = 3*INT(I/3 + 1.5) - 2` - Right lanes: `I = 3*INT(I/3 + 1.5) - 3` This maps any column within a 3-cell band to the same lane peg, giving deterministic booth assignment from approximate positions. The per-lane count is stored in array `S()`, indexed by column, and printed at row 0 above the booth. ### Revenue Formatting The subroutine at lines 5000–5030 converts the float `S(32)` (the accumulator element) to a string and patches missing decimal places manually: if the string has length 1 it appends `".00"`; if the second-to-last character is `"."` it appends `"0"`. This is necessary because `STR$` does not guarantee two decimal digits for monetary values like 0.3, 0.6, 0.9. ### Notable Techniques - **FAST/SLOW switching:**`FAST` is used for drawing the static scene; `SLOW` is restored before animation so the display refreshes visibly. - **Accumulator in array tail:** Using `S(32)` as a revenue accumulator within the same lane-count array is compact but relies on column indices never legitimately reaching 32. - **Flash effect:** Lines 4050–4080 print `%*` then a space at the booth position, with short busy-wait loops (lines 4030–4070), simulating a flash to acknowledge payment. - **Auto-restart:** Lines 396–399 pause, switch to FAST, clear the screen, and issue `RUN` to restart continuously without user intervention. ## Source Code ``` 10 FAST 20 DIM S(32) 30 PRINT AT 10,0;"HOW MANY VEHICLES?" 40 SLOW 50 INPUT HH 60 FAST 70 CLS 75 PRINT AT 6,12;":'''''''''''''':";AT 7,12;": $ :";AT 8,12;":..............:" 80 PRINT AT 18,1;":'''''''''':";AT 19,1;": TOLL :";AT 20,1;":..........:" 90 PRINT AT 18,25;":'''''''''''':";AT 19,25;": BOOTH :";AT 20,25;":............:" 100 LET A$=":''''': :: :: :: :@@@@: :: :: :: :''''':" 110 PRINT AT 1,0;A$ 120 PRINT AT 21,11;"'''': :''''" 130 FOR N=2 TO 40 140 PLOT 24-24*SIN (N/72*PI),N 150 NEXT N 160 FOR N=2 TO 40 170 PLOT 39+24*SIN (N/72*PI),N 180 NEXT N 185 FOR Q=1 TO HH 190 GOSUB 3000 195 SLOW 200 LET R=RND 210 IF R>.9 THEN LET A$="%T" 220 IF R<.9 THEN LET A$="%C" 230 GOSUB 2000 300 FOR N=8 TO 2 STEP -1 305 IF I<4 THEN LET I=4 306 IF RR=0 AND I>13 THEN LET I=13 307 IF I<18 AND RR=1 THEN LET I=18 308 IF I>27 THEN LET I=27 310 PRINT AT N,I;A$;AT N+1,II;" " 320 LET II=I 330 LET I=I+(INT (RND*3)-1) 350 NEXT N 355 IF II=0 THEN STOP 360 PRINT AT 2,II;" " 370 GOSUB 4000 390 NEXT Q 396 PAUSE 40000 397 FAST 398 CLS 399 RUN 1000 IF A$="%T" THEN GOTO 1500 1010 LET RRR=INT (2*RND) 1020 IF RRR=1 THEN GOTO 1500 1030 LET I=I+(INT (RND*3)-1) 1100 RETURN 1500 LET I=I+(INT (RND*3)-1) 1510 RETURN 2000 FOR N=20 TO 16 STEP -1 2010 PRINT AT N,I;A$;AT N+1,II;" " 2020 NEXT N 2100 LET RR=INT (2*RND) 2110 IF A$="%T" THEN LET RR=1 2115 IF A$="%T" THEN GOTO 2500 2120 IF RR=1 THEN GOTO 2500 2130 FOR N=15 TO 9 STEP -1 2140 PRINT AT N,I;A$;AT N+1,II;" " 2150 LET II=I 2160 LET I=I-1 2170 NEXT N 2180 RETURN 2500 FOR N=15 TO 9 STEP -1 2510 PRINT AT N,I;A$;AT N+1,II;" " 2520 LET II=I 2530 LET I=I+1 2540 NEXT N 2550 RETURN 3000 LET I=15 3010 LET II=15 3020 RETURN 4000 IF RR=0 THEN LET I=3*INT ((I/3)+1.5)-2 4002 IF RR=1 THEN LET I=3*INT ((I/3)+1.5)-3 4005 LET S(I)=S(I)+1 4010 PRINT AT 1,I;A$ 4030 FOR N=1 TO 10 4040 NEXT N 4050 PRINT AT 1,I;"%*" 4060 FOR N=1 TO 10 4070 NEXT N 4080 PRINT AT 1,I;" " 4090 PRINT AT 0,I;S(I) 4100 IF A$="%C" THEN LET S(32)=S(32)+.3 4110 IF A$="%T" THEN LET S(32)=S(32)+.6 4115 GOSUB 5000 4120 PRINT AT 7,14;S$ 4130 RETURN 5000 LET S$=STR$ S(32) 5010 IF LEN S$=1 THEN LET S$=S$+".00" 5020 IF S$(LEN S$-1)="." THEN LET S$=S$+"0" 5030 RETURN 9998 SAVE "TOLLBOOT%H" 9999 RUN ```