SNAKES

Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Arcade

SNAKES is a single-player dodging game in which the player controls a horizontal position on a fixed row, moving right by pressing “8” while the position automatically drifts left each frame. Obstacles scroll down the screen from row 21 upward, and collision is detected using SCREEN$ to read character data directly from the display. Three UDGs (\a, \b, \c) are defined via POKEs into USR memory using 24 bytes of DATA, representing the snake-head obstacle and the player’s character in two halves. The score increments each time the player successfully avoids an obstacle, and a high score is tracked across rounds within the same session using the variable HI.


Program Structure

The program is organized into a main game loop, two subroutines, and a UDG initialization block. Control flow is as follows:

  1. Lines 10–20: REM header; call UDG setup (line 260) and initialize high score.
  2. Lines 30–120: Game initialization subroutine call (line 220) and the main play loop.
  3. Lines 130–190: Game-over screen, score display, and restart logic.
  4. Lines 220–250: Initialization subroutine — sets border, paper, ink, clears screen, resets variables, dimensions V$.
  5. Lines 260–310: UDG definition subroutine — reads 24 bytes of DATA and POKEs them into the UDG area starting at USR "\a".

Game Mechanics

The player character occupies column H on row 9/10 of the screen. Movement is entirely horizontal: pressing “8” increments H by 2 (subject to a right-edge guard of V<29, though V is actually the vertical position variable used during init — this guard condition is likely a copy-paste anomaly), and each frame H is unconditionally decremented by 1 if positive, creating automatic leftward drift. The player must press “8” repeatedly to stay in place or move right.

Obstacles (UDG \a) are printed at a random column on row 21. Because the program never explicitly moves them upward, the scrolling effect is achieved entirely by the ZX Spectrum’s built-in scroll triggered by PRINT AT 21,0; followed by a newline via PRINT on line 110, which advances the display and naturally scrolls all content up one row.

Collision Detection

Collision is checked on line 60 using SCREEN$ (10,h). If the character at the player’s position on row 10 is not a space ("" here standing in for a blank cell), the game branches to the game-over routine. This is a common ZX Spectrum BASIC technique that avoids maintaining a separate data structure for object positions, instead reading the display file directly.

UDG Definitions

Three UDGs are defined via 24 bytes of DATA across lines 290–310, covering characters \a, \b, and \c (8 bytes each). The DATA lines contain the literal token U in several positions, which in this context appears to be used as a numeric value. In Spectrum BASIC, an unquoted U in a DATA statement would be evaluated as a variable — if U is uninitialized or zero, those bytes would be 0. Line 320 documents the mapping: A=\a (the falling obstacle), B=\b and C=\c (the two-row player sprite).

Key BASIC Idioms and Techniques

  • POKE 23692,255 on line 100 resets the scroll counter, suppressing the “scroll?” prompt that would otherwise appear after 22 lines of output, allowing uninterrupted scrolling.
  • The PAUSE 0:IF INKEY$ <>"" THEN INPUT 1:GO TO 180 idiom on line 180 waits for ENTER specifically: PAUSE 0 holds until any key, but the subsequent INKEY$ check re-runs the loop unless the key released was nothing (i.e., after ENTER is released). INPUT 1 discards the buffered keypress.
  • DIM V$(704) allocates a 704-character string array. Its role is not immediately obvious from the loop logic — it may be intended as a buffer or leftover from a version that stored the screen state. V$ is printed in the game-over sequence (line 130), but it is never assigned content, so it will display as 704 spaces.
  • INK 9 in the initialization subroutine uses a transparent ink value, a quirk of the Spectrum’s attribute system.

Bugs and Anomalies

  • Line 50 uses AND v<29 as a right-boundary guard, but v (lowercase) at this point in the game holds the value 10 (set in line 220 as LET V=10) and never changes during play. The guard is therefore always true (10 < 29), meaning there is no effective right-edge clamp and H can exceed column 31, potentially causing an out-of-range PRINT error.
  • Line 250 contains a bare RETURN with no preceding GO SUB path that would naturally reach it — it is a dead code stub, likely a remnant of editing.
  • As noted, U in the DATA statements (lines 290–310) is treated as a variable reference. If U is zero at the time of reading, those UDG rows will be blank (all pixels off), which may produce incomplete sprite graphics.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

Source Code

  10 REM SNAKES
  20 GO SUB 260:LET HI=0
  30 GO SUB 220
  40 PRINT AT 9,H;" "
  50 LET h=h+2*(INKEY$="8" AND v<29):IF h>0 THEN LET h=h-1
  60 IF SCREEN$ (10,h)="" THEN GO TO 130
  70 PRINT AT 9,h; INK 6;"\b"; AT 10,h;"\c"
  80 PRINT AT 21,0;
  90 PRINT TAB INT (RND*31); INK 1;"\a"
 100 POKE 23692,255
 110 LET sc=sc+1:PRINT 
 120 GO TO 40
 130 PRINT AT 0,0; OVER 1; PAPER 8; INK 2;v$
 140 PRINT AT 0,10;"\{18}\{1}GAME OVER\{18}\{0}"
 150 PRINT AT 5,7;"YOU SCORED ";SC
 160 IF SC>HI THEN LET HI=SC
 170 PRINT AT 10,5;"HIGHEST SCORE TODAY ";HI
 180 PRINT #0;"PRESS "; PAPER 1;"ENTER"; PAPER 0;" TO PLAY AGAIN ":PAUSE 0:IF INKEY$ <>"" THEN INPUT 1:GO TO 180
 190 GO TO 30
 200 STOP 
 210 REM 
 220 BORDER 0:PAPER 0:INK 9:CLS :LET V=10:LET H=15
 230 LET SC=0:RANDOMIZE 
 240 DIM V$(704):RETURN 
 250 RETURN 
 260 FOR A=0 TO 23
 270 READ U:POKE USR "\a"+A,U
 280 NEXT A:RETURN 
 290 DATA 255,126,U,60,U,24,U,0
 300 DATA 0,99,119,127,62,28,0,U,U
 310 DATA 99,119,73,U,127,82,28,0
 320 REM A=\a B=\b C=\c
 330 SAVE "SNAKES" LINE 10

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top