Brick-Yard Bill is a maze-navigation game in which the player steers a character (UDG “b”, a stick figure) around a yard filled with randomly placed bricks (UDG “a”) using the cursor keys 5–8, trying to avoid becoming completely surrounded. The playing field is a 20×32 bordered arena drawn with repeated UDG “a” brick characters; obstacle placement uses ATTR reads to detect occupied cells before randomly positioning each brick, ensuring the field is navigable at start. Scoring is calculated as a percentage of the yard covered with bricks, derived from the formula INT ((score*100)/(599-h)), where h controls difficulty and increases by 10 each round if the player scores 80% or above. The title screen features a scrolling marquee implemented by rotating a long string one character at a time with a$(2 TO )+a$(1), with BEEP pitch derived from CODE a$(28)/4 to produce a musical accompaniment. A cumulative score variable fr accumulates percentage scores across rounds, and the hi-score persists for the session.
Program Analysis
Program Structure
The program is organized into clearly separated functional blocks, each introduced with a REM comment:
- Lines 11–17: UDG definition, subroutine call for instructions, variable initialization
- Lines 18–55: Game setup — draws border, places bricks randomly, plays intro tune
- Lines 60–500: Main game loop — draws player, waits for keypress, dispatches to movement routines
- Lines 1000–1090: LEFT movement (key 5)
- Lines 2000–2090: DOWN movement (key 6)
- Lines 3000–3090: UP movement (key 7)
- Lines 4000–4090: RIGHT movement (key 8)
- Lines 5000–5095: End-of-game scoring and round transition
- Lines 6000–7000: Instructions subroutine
- Lines 9998–9999: SAVE/VERIFY
UDG Definitions
Two UDGs are defined at the start via READ/POKE loops:
| UDG | Character | Data bytes | Role |
|---|---|---|---|
\a | Brick | 0,119,119,119,0,238,238,238 | Wall/obstacle tile |
\b | Bill (stick figure) | 24,24,60,90,153,36,36,102 | Player character |
The brick UDG uses alternating byte patterns (119 = 01110111, 238 = 11101110) to create a half-brick offset pattern. The stick figure bytes sketch a recognizable humanoid: head (24=00011000), arms (60=00111100), body (90=01011010), legs (36=00100100), feet (102=01100110).
Arena Construction
The border is drawn by printing a full row of 32 \a bricks at rows 0 and 21, and single bricks at columns 0 and 31 for rows 1–20. Bricks are placed randomly in the interior with the following constraints enforced in the placement loop (lines 45–50):
- Row must not be 10 (reserved for possible player start area)
- The cell must have ATTR value ≤ 100 (unoccupied) — the ATTR of a placed brick with PAPER 7, INK 2, BRIGHT 1 is above 100
hbricks are placed per round, starting at 20 and increasing by 10 each time the player scores ≥ 80%
Movement and Collision Detection
Each directional routine checks the target cell using ATTR before moving. If the attribute exceeds 32 (indicating any non-default coloring, i.e., a brick or border), movement is blocked and control returns to line 100. After each move, the old position is overprinted with \a (a brick), effectively leaving a trail and permanently reducing the navigable space.
The entrapment check at line 455 uses a compound AND condition testing all four neighbors:
ATTR (x+1,y)>32— belowATTR (x-1,y)>32— aboveATTR (x,y+1)>32— rightATTR (x,y-1)>32— left
If all four are blocked, the game ends via GO TO 5000.
Scoring Formula
The percentage score is calculated as INT ((score*100)/(599-h)). The denominator 599-h approximates the total number of moves available in the interior. With h=20 (round 1), this gives a divisor of 579. The cumulative score fr accumulates these percentages across rounds and is used as the displayed running total. A hi-score hi tracks the maximum fr achieved in the session.
Scrolling Marquee Technique
The instructions screen at line 6095–6130 implements a character-by-character horizontal scroll by rotating the string a$ with a$(2 TO )+a$(1), then printing a 28-character window at AT 10,2. The BEEP pitch is generated from CODE a$(28)/4, producing a melody derived from the ASCII values of the scrolling text — a common technique for “typing” sound effects. The loop runs 136 iterations (0 TO 135), cycling the 136-character message string exactly once.
Notable Bugs and Anomalies
- Line ordering anomaly: Line 1024 appears after line 1030 in the listing. In BASIC, lines are executed in numerical order, so 1024 executes between 1020 and 1025 — the listing is misleadingly formatted but functionally correct as entered.
- Boundary clamping: Lines 1035, 2035, 3035, 4035 clamp coordinates but allow the player to overlap with the border row/column, which may cause the player to appear inside the border.
- Unreachable lines: Lines 5160 and 5170 (the in-game description text) are never called from the main program flow and appear to be dead code from an earlier version.
- Typo in string: Line 5160 contains the misspelling “PRECENTAGE” (should be “PERCENTAGE”), which is unreachable anyway.
- BEEP duration at line 2050:
BEEP .00,21-xuses a duration of zero, producing no audible sound during downward movement, unlike the other directions which use.01. - Screen 1 score display: The score is printed to
#1(the lower screen) but positionAT 0,1addresses a row/column within the two-line lower screen area — row 0 of stream #1 maps to the first line of the lower display.
Key BASIC Idioms
- ATTR-based collision detection throughout — avoids maintaining a separate map array
- PAUSE 0 at lines 80, 5069, 6135, 6180 for clean keypress gating
- Directional routines as separate line-number blocks (1000/2000/3000/4000), cross-jumping between them to allow diagonal-feel movement when a key is held
- PRINT #1 for the status bar, keeping it separate from the main play area
Content
Source Code
11 FOR n=0 TO 7: READ z: POKE USR "a"+n,z: NEXT n
12 DATA 0,119,119,119,0,238,238,238
13 FOR n=0 TO 7: READ z: POKE USR "b"+n,z: NEXT n
14 DATA 24,24,60,90,153,36,36,102
15 GO SUB 6000
16 LET hi=0: LET fr=0
17 LET h=20
18 LET score=0
20 LET x=10: LET y=15
30 LET a$="\a"
32 PRINT BRIGHT 1; PAPER 7; INK 2;AT 0,0;"\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a"
33 FOR n=1 TO 20
34 PRINT BRIGHT 1; PAPER 7; INK 2;AT n,0;"\a";AT n,31;"\a"
35 NEXT n
36 PRINT BRIGHT 1; PAPER 7; INK 2;AT 21,0;"\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a"
38 PRINT #1; PAPER 1; INK 7;AT 0,1;"SCORE=";AT 0,15;"HI SCORE="
40 FOR b=1 TO h
45 LET c=INT (RND*20)+1
46 IF c=10 THEN GO TO 45
47 LET d=INT (RND*30)+1
48 IF ATTR (c,d)>100 THEN GO TO 45
49 BEEP .01,d
50 PRINT PAPER 7; INK 2; BRIGHT 1;AT c,d;a$: NEXT b
55 FOR n=-20 TO 20: BEEP .01,ABS n+15: NEXT n
60 PRINT AT x,y;"\b"
80 PAUSE 0
100 IF INKEY$="5" THEN GO TO 1000
200 IF INKEY$="6" THEN GO TO 2000
300 IF INKEY$="7" THEN GO TO 3000
400 IF INKEY$="8" THEN GO TO 4000
450 PRINT AT x,y;"\b"
455 IF ATTR (x+1,y)>32 AND ATTR (x-1,y)>32 AND ATTR (x,y+1)>32 AND ATTR (x,y-1)>32 THEN GO TO 5000
500 GO TO 100
1000 REM ++++++++LEFT++++++++
1010 IF ATTR (x,y-1)>32 THEN GO TO 100
1020 PRINT PAPER 7; INK 2; BRIGHT 1;AT x,y;"\a"
1025 PRINT #1; PAPER 1; INK 7;AT 0,7;INT ((score*100)/(599-h))+fr
1030 LET y=y-1
1035 IF y<=0 THEN LET y=0
1024 PRINT AT x,y;"\b"
1050 BEEP .01,21-x
1055 LET score=score+1
1060 IF INKEY$="6" THEN GO TO 2000
1070 IF INKEY$="7" THEN GO TO 3000
1090 GO TO 1000
2000 REM ++++++++DOWN++++++++
2010 IF ATTR (x+1,y)>32 THEN GO TO 100
2020 PRINT PAPER 7; INK 2; BRIGHT 1;AT x,y;"\a"
2025 PRINT #1; PAPER 1; INK 7;AT 0,7;INT ((score*100)/(599-h))+fr
2030 LET x=x+1
2035 IF x>=21 THEN LET x=21
2040 PRINT AT x,y;"\b"
2050 BEEP .00,21-x
2055 LET score=score+1
2060 IF INKEY$="5" THEN GO TO 1000
2080 IF INKEY$="8" THEN GO TO 4000
2090 GO TO 2000
3000 REM +++++++++UP+++++++++
3010 IF ATTR (x-1,y)>32 THEN GO TO 100
3020 PRINT PAPER 7; INK 2; BRIGHT 1;AT x,y;"\a"
3025 PRINT #1; PAPER 1; INK 7;AT 0,7;INT ((score*100)/(599-h))+fr
3030 LET x=x-1
3035 IF x<=0 THEN LET x=0
3040 PRINT AT x,y;"\b"
3050 BEEP .01,21-x
3055 LET score=score+1
3060 IF INKEY$="5" THEN GO TO 1000
3080 IF INKEY$="8" THEN GO TO 4000
3090 GO TO 3000
4000 REM +++++++RIGHT++++++++
4010 IF ATTR (x,y+1)>32 THEN GO TO 100
4020 PRINT PAPER 7; INK 2; BRIGHT 1;AT x,y;"\a"
4025 PRINT #1; PAPER 1; INK 7;AT 0,7;INT ((score*100)/(599-h))+fr
4030 LET y=y+1
4035 IF y>=31 THEN LET y=31
4040 PRINT AT x,y;"\b"
4050 BEEP .01,21-x
4055 LET score=score+1
4070 IF INKEY$="6" THEN GO TO 2000
4080 IF INKEY$="7" THEN GO TO 3000
4090 GO TO 4000
5000 REM +++++++SCORE++++++++
5025 LET pc=INT ((score*100)/(599-h))
5030 LET fr=fr+pc
5035 IF fr>hi THEN LET hi=fr
5050 PRINT #1; PAPER 1; INK 7;AT 0,1;"SCORE=";INT pc;" ";AT 0,15;"HI SCORE=";hi;" "
5053 IF pc>=80 THEN GO TO 5060
5054 LET fr=0: LET pc=0: LET h=20
5055 PRINT PAPER 6; INK 0; FLASH 1;AT 2,1;" PRESS ANY KEY TO PLAY AGAIN. "
5059 GO TO 5069
5060 LET pc=0: LET h=h+10
5063 PRINT FLASH 1; PAPER 6; INK 0;AT 2,3;" Press key for next round "
5069 PAUSE 0
5070 FOR n=1 TO 20
5080 PRINT PAPER 4;AT n,1;" ": BEEP .01,n
5090 NEXT n
5093 PRINT #1; PAPER 1; INK 7;AT 0,7;fr;" "
5095 GO TO 18
5160 PRINT PAPER 4; INK 0;AT 6,2;"AT THE END OF EACH GAME YOU WILL BE GIVEN THE APPROX. PRECENTAGE OF THE YARD WHICH IS COVERED WITH BRICKS."
5170 PRINT PAPER 4; INK 0; BRIGHT 1;AT 15,4;"PRESS ANY KEY TO START."
6000 REM +++++++INSTR++++++++
6010 BORDER 6: PAPER 4: CLS
6015 DRAW 255,0: DRAW 0,175: DRAW -255,0: DRAW 0,-175
6020 FOR n=1 TO 9
6030 PRINT PAPER 7; INK 2; BRIGHT 1;AT n,1;"\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a"
6040 NEXT n
6050 PRINT PAPER 7; INK 2; BRIGHT 1;AT 10,1;"\a \a "
6060 FOR n=11 TO 20
6070 PRINT PAPER 7; INK 2; BRIGHT 1;AT n,1;"\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a"
6080 NEXT n
6090 LET a$=" BRICK-YARD BILL HELP BILL STACK THE BRICKS BUT BE CAREFUL NOT TO GET TRAPPED \b\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a"
6095 FOR n=0 TO 135
6100 LET a$=a$(2 TO )+a$(1)
6110 BEEP .05,CODE a$(28)/4
6120 PRINT PAPER 7; INK 2; BRIGHT 1;AT 10,2;A$(1 TO 28)
6130 NEXT n
6134 PRINT BRIGHT 1; PAPER 1; INK 7;AT 10,5;"press key to continue"
6135 PAUSE 0
6140 PAPER 4: CLS
6150 PRINT PAPER 4; INK 0;AT 2,2;"USE THE CURSOR KEYS TO STEER BILL AROUND THE BRICK-YARD."
6175 DRAW 255,0: DRAW 0,175: DRAW -255,0: DRAW 0,-175
6180 PAUSE 0
6190 FOR n=0 TO 40 STEP 5
6200 BEEP .03,n
6210 NEXT n
6220 CLS
7000 RETURN
9998 SAVE "Bricks" LINE 0: BEEP .4,15
9999 VERIFY ""
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

