--- title: "Sniper" id: 57279 type: "computer_media" slug: "sniper" url: "http://localhost/computer_media/sniper/" markdown_url: "http://localhost/computer_media/sniper.md" published_at: "2024-10-04T08:01:19+00:00" modified_at: "2026-03-30T21:18:42+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/167_Snip.png" excerpt: "A quick-fire reaction game where a target figure flashes on screen and you must hit the right key before time runs out — and it only gets faster." 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 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_contents: - id: 56734 title: "Timex Sinclair Public Domain Library Tape 1003" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1003/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/10/167_Snip.png" media_type_tags: "Game" --- Sniper is a reaction-based shooting game where a figure appears at a random horizontal position on screen and the player must press the correct number key before it disappears. The figure is drawn using block graphics and inverse-video characters across four rows, giving it a simple but recognizable silhouette. The target position variable X is multiplied by 3 to space figures across the screen in columns, while T is computed as (X/3 + 1) × SGN(9 − X/3) to map each position to a unique digit key the player must press. The window of opportunity shrinks as the counter C increases, since PAUSE 90−C gives progressively less time to react. POKE 16437,255 is used repeatedly to clear the keyboard buffer before checking INKEY$, preventing stale keypresses from registering as hits. *** ## Program Analysis ### Program Structure The program is structured as a single main loop running from line 70 to line 300. Initialization (score and counter) happens once at lines 50–60, and the game resets when the counter `C` reaches 40 at line 260, which loops back to line 40 to re-initialize everything. The overall flow is: 1. Initialize score `S=0` and counter `C=0` (lines 50–60) 2. Choose a random column position `X` and compute the expected key `T` (lines 70–80) 3. Draw the target figure at column `X*3` (lines 90–130) 4. Pause for a decreasing time window, then test for the correct keypress (lines 140–160) 5. If correct, draw a “hit” figure, update and display score, and pause (lines 170–240) 6. Clear screen, increment counter, pause a random interval, and repeat (lines 250–300) ### Position and Key Mapping The random column index is generated as `X = INT(RND * 9.9)`, giving values 0–9. This is then scaled to screen columns with `X = X * 3`, spacing figures across 30 columns in steps of 3. The expected key digit `T` is calculated at line 80 as `(X+1) * SGN(9-X)` (using the pre-scaled X). For values 0–8 this yields digits 1–9 since SGN(9−X) = 1; for X=9 it yields 0 since SGN(0)=0. This neatly maps each of the ten positions to a unique digit key 1–9 and 0. ### Difficulty Progression The reaction window is controlled by `PAUSE 90-C` at line 140, where `C` increments by 1 each round (line 290) and resets to 0 every 40 rounds. This means the display time shrinks from approximately 1.5 seconds at the start of a cycle down to about 0.8 seconds by round 40, creating a gradual difficulty ramp within each 40-round cycle. ### Keyboard Buffer Management `POKE 16437,255` appears at lines 150, 240, and 280. Address 16437 is the LAST K system variable, which holds the last key pressed. Poking it with 255 effectively invalidates the stored keypress, ensuring that `INKEY$` only returns a fresh keypress made during the current window. This prevents a key held down from a previous round from accidentally scoring a hit. ### Graphics Techniques The target figure spans four PRINT AT rows and uses a combination of block graphics escapes and inverse-video characters. The head is drawn as `" O"`, the body uses inverse-space characters (shown as filled blocks) for a torso, and the legs use block graphic characters. The “hit” animation at lines 170–200 replaces the figure with a different arrangement suggesting a falling or exploding character, providing visual feedback for a successful shot. | Line | Row offset | Content description | | --- | --- | --- | | 100 | Row 4 | Head: space + “O” | | 110 | Row 5 | Shoulders: block graphics with inverse space (torso) | | 120 | Row 6 | Body: space + inverse-space + two spaces | | 130 | Row 7 | Legs: block graphics with inverse space | ### Notable Idioms and Anomalies - `STR$ T` at line 160 converts the numeric digit T to a string for comparison with `INKEY$`, which always returns a string — a necessary type-matching technique. - The inter-target pause at line 270, `PAUSE INT(RND*120)+30`, adds 30–149 frames of random delay between figures, preventing the player from anticipating timing. - The `REM "SNIPER"` at line 10 serves as the program title; lines 40–300 form the actual code, with the gap from 10 to 40 being cosmetic. - Line 310 (`SAVE "1016%7"`) and line 320 (`LIST`) are utility lines appended after the main program body and are not part of normal execution flow. - There is no explicit “Game Over” message or final score display when the 40-round cycle completes — the game simply resets silently at line 260. ## Source Code ``` 10 REM "SNIPER" 40 CLS 50 LET S=0 60 LET C=0 70 LET X=INT (RND*9.9) 80 LET T=(X+1)*SGN (9-X) 90 LET X=X*3 100 PRINT AT 4,X;" O" 110 PRINT AT 5,X;"\''% \''" 120 PRINT AT 6,X;" % " 130 PRINT AT 7,X;"\ .% \. " 140 PAUSE 90-C 150 POKE 16437,255 160 IF INKEY$<>STR$ T THEN GOTO 250 170 PRINT AT 4,X;"\'.O\.'" 180 PRINT AT 5,X;" % " 190 PRINT AT 6,X;" % " 200 PRINT AT 7,X;"\.' \'." 210 LET S=S+1 220 PRINT AT 15,0;"SCORE";S 230 PAUSE 60 240 POKE 16437,255 250 CLS 260 IF C=40 THEN GOTO 40 270 PAUSE INT (RND*120)+30 280 POKE 16437,255 290 LET C=C+1 300 GOTO 70 310 SAVE "1016%7" 320 LIST ```