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:
- Initialize score
S=0and counterC=0(lines 50–60) - Choose a random column position
Xand compute the expected keyT(lines 70–80) - Draw the target figure at column
X*3(lines 90–130) - Pause for a decreasing time window, then test for the correct keypress (lines 140–160)
- If correct, draw a “hit” figure, update and display score, and pause (lines 170–240)
- 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$ Tat line 160 converts the numeric digit T to a string for comparison withINKEY$, 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
