Garbage Gobbler is a maze-free collect-em-up where the player navigates a character around the screen using keys 5, 6, 7, and 8 to eat randomly placed block-graphic pieces before a countdown timer expires. The program scatters garbage using CHR$ codes 128–138 (the ZX81 block graphics set) and detects collection by PEEKing the display file address held in system variables 16398–16399, comparing the character code at the player’s current position. Scoring applies a multiplier based on the difficulty level chosen (40, 60, or 80 pieces), with time-per-piece ratio used to calculate the final score. An animated title sequence moves an inverse-G character across the screen, and a decorative border animation frames the game-over screen. The FAST/SLOW pair wraps the garbage-scattering loop to speed up screen plotting before returning to normal display mode.
Program Analysis
Program Structure
The program is divided into clearly recognisable phases:
- Title / intro animation (lines 0–11): scrolls an inverse-G across the screen and displays instructions.
- Difficulty selection (lines 10–16): prompts for 40, 60, or 80 pieces and validates the input.
- Garbage scattering (lines 17–37): uses
FAST/SLOWto rapidly plot random block graphics. - Main game loop (lines 40–150): moves the player, detects collection via display-file PEEK, and counts score.
- Score display and replay (lines 160–224): calculates a weighted score and offers replay.
- Goodbye animation (lines 230–280): draws a border animation and displays “COME AGAIN” in inverse video.
Movement and Input Handling
Player movement is handled entirely within the main timer loop (lines 75–150). Lines 100–110 use a compact BASIC idiom where boolean expressions (returning 1 or 0) are added and subtracted to update the X and Y coordinates in a single LET statement:
LET X=X+(INKEY$="8" AND X<30)-(INKEY$="5" AND X>0)— horizontal movement with boundary clamping.LET Y=Y+(INKEY$="6" AND Y<20)-(INKEY$="7" AND Y>0)— vertical movement with boundary clamping.
The standard ZX81 cursor-key mapping of 5/6/7/8 is used throughout.
Display-File Collision Detection
The most technically interesting element is the garbage-eating detection at line 130. Rather than maintaining an array of garbage positions, the program reads directly from the display file:
IF PEEK (PEEK 16398+256*PEEK 16399)>=128 AND PEEK (PEEK 16398+256*PEEK 16399)<=138 THEN LET A=A+1
System variables at addresses 16398 (low byte) and 16399 (high byte) hold the address of the current print position in the display file. After PRINT AT Y,X; (line 120) moves the print position without printing anything, the PEEK reads whatever character code is already at that cell. Character codes 128–138 correspond to ZX81 block graphics, which were used to scatter the garbage at line 20. This is an elegant, memory-efficient collision technique that avoids any separate data structure.
Garbage Scattering
Line 20 uses CHR$ (INT (RND*11)+128) to select randomly from the 11 block-graphic characters (codes 128–138) and plots each at a random screen position. The loop is wrapped in FAST (line 17) and SLOW (line 35) to accelerate plotting, which would otherwise be visibly slow in normal display mode.
Timer and Scoring
A random time limit Q is chosen at line 70 (INT (RND*110)+30, giving 30–139 units), counted down with a FOR T=Q TO 0 STEP -1 loop. The scoring formula (lines 165–169) is:
| Difficulty | Multiplier | Formula |
|---|---|---|
| 40 pieces | ×1.3 | V = (1000 - INT((Q/A)*100)) * 1.3 |
| 60 pieces | ×1.0 | V = 1000 - INT((Q/A)*100) |
| 80 pieces | ×0.92 | V = (1000 - INT((Q/A)*100)) * 0.92 |
The ratio Q/A (time per piece collected) rewards fast collection. Counterintuitively, the 80-piece difficulty carries a lower multiplier than 60 pieces, making it harder to maximise score despite the greater number of targets.
Animation Techniques
Both the title screen and the goodbye screen use a simple trail-erasing animation: the character (%G, inverse G) is printed at position S, then a dot is printed at S-1 to erase the previous frame. This gives a smooth single-character scrolling effect across a row. The goodbye screen extends this to all four sides of a rectangular border using separate loops (lines 242–266), effectively drawing the player character around the perimeter of the screen.
Input Validation Bug
Line 15 contains a logical error in the validation condition:
IF BB<>40 OR BB<>60 OR BB<>80 THEN GOTO 2
Because a number cannot simultaneously equal 40, 60, and 80, this condition is always true for any input (e.g., if BB=40, then BB<>60 is true). The intended logic should use AND rather than OR. In practice, line 14 catches valid inputs first, so line 15 acts as a catch-all fallback, but the condition as written is a tautology.
Division-by-Zero Risk
At line 165, LET TT=(Q/A) will cause an error if the player collects no garbage (A=0). No guard is present for this case.
Unused and Dead Code
Lines 300 (STOP), 310 (CLEAR), 320 (SAVE), and 330 (RUN) are never reached during normal execution, as line 280 halts the program. These are utility lines likely intended to be run manually for saving the program.
Content
Source Code
0 REM GARBAGE GOBBLER CORE PROGRAM BY TIM HARTNELL MOVING GRAPHIC SCREENS AND INSTRUCTIONS BY TONY WILLING
2 PRINT AT 2,7;"GARBAGE GOBBLER",,,,,"USE THE ARROW KEYS (5,6,7,8) TO MOVE AROUND AND EAT AS MUCH GARBAGE AS YOU CAN"
3 FOR S=1 TO 30
4 PRINT AT 2,S;"%G"
5 PRINT AT 2,S-1;"."
6 PRINT AT 11,8;"YOU ARE THE %G"
7 PRINT AT 11,8;"%Y%O%U% %A%R%E% %T%H%E% %G"
8 NEXT S
9 RAND
10 PRINT AT 15,0;"HOW MUCH GARBAGE DO YOU WANT?"
11 PRINT AT 18,4;"(40,60, OR 80 PIECES?)"
12 INPUT BB
13 CLS
14 IF BB=40 OR BB=60 OR BB=80 THEN GOTO 16
15 IF BB<>40 OR BB<>60 OR BB<>80 THEN GOTO 2
16 PAUSE 50
17 FAST
18 FOR A=1 TO BB
20 PRINT AT INT (RND*21),INT (RND*31);CHR$ (INT (RND*11)+128)
30 NEXT A
35 SLOW
37 PAUSE 200
40 LET A=0
50 LET X=INT (RND*31)
60 LET Y=INT (RND*21)
70 LET Q=INT (RND*110)+30
71 PRINT AT 0,18;"TIME: ";Q
75 FOR T=Q TO 0 STEP -1
80 LET X1=X
90 LET Y1=Y
100 LET X=X+(INKEY$="8" AND X<30)-(INKEY$="5" AND X>0)
110 LET Y=Y+(INKEY$="6" AND Y<20)-(INKEY$="7" AND Y>0)
120 PRINT AT Y,X;
130 IF PEEK (PEEK 16398+256*PEEK 16399)>=128 AND PEEK (PEEK 16398+256*PEEK 16399)<=138 THEN LET A=A+1
140 PRINT AT Y1,X1;"." AND (X<>X1 OR Y<>Y1);AT Y,X;"%G"
150 NEXT T
160 PRINT AT 20,0;"YOU COLLECTED ";A
165 LET TT=(Q/A)
166 LET V=1000-(INT (TT*100))
167 IF BB=40 THEN LET V=V*1.3
168 IF BB=60 THEN LET V=V
169 IF BB=80 THEN LET V=V*.92
170 PRINT AT 21,14;"SCORE: ";V
180 PAUSE 400
190 CLS
200 PRINT AT 15,2;"DO YOU WANT TO PLAY AGAIN?"
205 PRINT AT 18,2;"ENTER 1 FOR YES, 0 FOR NO"
210 INPUT HH
220 IF HH=1 THEN CLS
222 IF HH=1 THEN PAUSE 200
224 IF HH=1 THEN GOTO 10
230 IF HH=0 THEN CLS
233 PRINT AT 8,10;"THANK YOU"
237 PRINT AT 14,1;"% \ .% \.'\@@\:'\:.\.:\,,\!!\;;\'.\: \. \ :\ .\ '\;;\!!\@@\!!\,,\:'\:.\.:\ .\'.\.'\'.\;;"
242 FOR W=0 TO 30
243 PRINT AT 14,W;"%G"
244 PRINT AT 14,W-1;"."
248 NEXT W
249 FOR O=14 TO 8 STEP -1
250 PRINT AT O,30;"%G"
252 PRINT AT O,30;"."
254 NEXT O
255 FOR O=30 TO 0 STEP -1
257 PRINT AT 8,O;"%G"
259 PRINT AT 8,O;"."
261 NEXT O
262 FOR O=8 TO 14
263 PRINT AT O,0;"%G"
264 PRINT AT O,0;"."
266 NEXT O
268 PRINT AT 14,0;"."
269 PRINT AT 11,10;"%C%O%M%E% %A%G%A%I%N"
270 FOR Z=1 TO 125
272 NEXT Z
275 CLS
280 STOP
300 STOP
310 CLEAR
320 SAVE "1019%7"
330 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
