Garbage Gobbler

This file is part of and Timex Sinclair Public Domain Library Tape 1004. Download the collection to get this file.
Developer(s): Tim Hartnell, Tony Willing
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Arcade, Game

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:

  1. Title / intro animation (lines 0–11): scrolls an inverse-G across the screen and displays instructions.
  2. Difficulty selection (lines 10–16): prompts for 40, 60, or 80 pieces and validates the input.
  3. Garbage scattering (lines 17–37): uses FAST/SLOW to rapidly plot random block graphics.
  4. Main game loop (lines 40–150): moves the player, detects collection via display-file PEEK, and counts score.
  5. Score display and replay (lines 160–224): calculates a weighted score and offers replay.
  6. 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:

DifficultyMultiplierFormula
40 pieces×1.3V = (1000 - INT((Q/A)*100)) * 1.3
60 pieces×1.0V = 1000 - INT((Q/A)*100)
80 pieces×0.92V = (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

Appears On

Assembled by Tim Ward from many sources. Contains programs 10176 – 10210.

Related Products

Related Articles

Related Content

Image Gallery

Garbage Gobbler

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.

Scroll to Top