--- title: "SNAKES" id: 71348 type: "computer_media" slug: "snakes" url: "http://localhost/computer_media/snakes/" markdown_url: "http://localhost/computer_media/snakes.md" published_at: "2026-09-02T06:52:54+00:00" modified_at: "2026-09-02T06:52:54+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/09/Snakes.png" excerpt: "Dodge falling snake-head obstacles by sliding left and right — collision detection reads directly from the screen in this fast-paced single-variable reflex game." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" genre: - name: "Arcade" slug: "arcade" taxonomy: "genre" url: "http://localhost/type/arcade/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/SNAKES%20(198x)(-)(TS2068)(US)(Program).zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/09/Snakes.png" media_type_tags: "Arcade" --- # SNAKES 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. ## 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 ```