Gobbler is a dot-eating game in which the player navigates a cursor character (“k”) around the screen, collecting asterisks scattered at random positions. One hundred asterisks are placed using RND-based AT coordinates before play begins. Movement is controlled by four keys (5, 6, 7, 8 — the standard ZX Spectrum directional keys), and the screen wraps toroidally so the player re-enters from the opposite edge when moving off any side. A short BEEP sounds when an asterisk is consumed. The game uses SCREEN$ to detect collisions with asterisk characters rather than maintaining a separate data structure.
Program Structure
The program is short and self-contained, divided into three logical phases:
- Initialization (lines 20–30): 100 asterisks are printed at random screen positions using
PRINT AT INT(RND*22), INT(RND*32);"*". - Player setup (lines 40–50): The player character
"k"is placed at row 10, column 15. - Game loop (lines 60–150): Reads input, computes new position, handles wrapping, moves the player, and loops back to line 50.
Input Handling
Line 60 busy-waits with IF INKEY$="" THEN GO TO 60 until a key is pressed. Line 70 then captures the keypress into m$. The movement keys follow the standard layout:
| Key | Direction |
|---|---|
5 | Left |
6 | Down |
7 | Up |
8 | Right |
Notable Techniques
Lines 80 and 90 use a compact Boolean arithmetic idiom to compute the new row and column in a single expression:
LET nr=r+(1 AND m$="6")-(1 AND m$="7")— adds 1 if moving down, subtracts 1 if moving up.LET nc=c+(1 AND m$="8")-(1 AND m$="5")— adds 1 if moving right, subtracts 1 if moving left.
This avoids a multi-branch IF ladder and is a common efficiency idiom in Sinclair BASIC, exploiting the fact that a true Boolean expression evaluates to 1.
Collision detection on line 100 uses SCREEN$(nr,nc)="*" to test whether the destination cell contains an asterisk, triggering a BEEP .05,0 if so. No separate array of dot positions is maintained; the screen itself serves as the game state.
Screen Wrapping
Lines 110–140 implement toroidal wrapping. Because the new position is computed before boundary checking, the comparisons use >21, >31, <0 rather than equality tests, which correctly handles the single-step movement. However, wrapping is applied to nr/nc before the SCREEN$ collision check on line 100, meaning the check is performed on the pre-wrap (potentially out-of-range) coordinates — a minor ordering anomaly. In practice, moving off the edge while an asterisk sits at the wrapped target would be missed for that step, though this is unlikely to affect gameplay significantly.
Bugs and Anomalies
- Collision check order:
SCREEN$(nr,nc)on line 100 is evaluated before wrapping occurs on lines 110–140, so a position ofnr=-1ornr=22would cause an error or an incorrect check rather than wrapping first and then testing. Under normal movement of one step at a time,SCREEN$with an out-of-range coordinate will produce an error — this is a genuine bug if the player is at the edge and moves off it. - No win condition: The game has no end state; once all asterisks are eaten, the player continues moving on a blank screen indefinitely.
- Asterisk overlap: Random placement may cause some asterisks to overwrite others, so the actual count of visible dots may be fewer than 100.
Source Code
10 REM *** "GOBBLER"
20 FOR a=1 TO 100
30 PRINT AT INT (RND*22), INT (RND*32);"*":NEXT a
40 LET r=10:LET c=15
50 PRINT AT r,c;"k"
60 IF INKEY$="" THEN GO TO 60
70 LET m$= INKEY$
80 LET nr=r+(1 AND m$="6")-(1 AND m$="7")
90 LET nc=c+(1 AND m$="8")-(1 AND m$="5")
100 PRINT AT r,c;" ":IF SCREEN$ (nr,nc)="*" THEN BEEP .05,0
110 IF nr>21 THEN LET nr=0
120 IF nc>31 THEN LET nc=0
130 IF nr<0 THEN LET nr=21
140 IF nc<0 THEN LET nc=31
150 LET r=nr:LET c=nc:GO TO 50Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
