This program implements a simple Galaxian-style shoot-’em-up in BASIC. The player controls a cannon (rendered with block graphics) at the bottom of the screen using Z and C keys to move left and right, and M to fire. A single alien descends from the top of the screen, occasionally firing back at the player. The program uses PI/PI as a constant 1 throughout, a common memory-saving idiom, and employs block graphic characters to render the cannon, alien, and laser bolts. The score variable S increments each time an alien is hit, and the game ends—displaying the score and restarting—when the player is destroyed or five aliens are defeated.
Program Analysis
Program Structure
The program is a compact, single-file action game with no subroutines. Execution flows mostly through a main loop centred on lines 19–30, with branching to an end/reset block at lines 36–41. The overall structure is:
- Initialisation (lines 5–14): Sets up speed constant
V=10(player row), scoreS=1(viaPI/PI), gun columnG=5, and alien positionX,Y. - Draw alien row header (lines 15–18): Prints a row of block-graphic shapes at the top.
- Main loop (lines 19–30): Reads keys, moves the gun, moves the alien down, optionally fires an alien shot, and checks collisions.
- Player fire (lines 31–34): Animates a bullet upward when M is pressed and tests for a hit.
- Score/reset block (lines 35–41): Increments score, clears screen, checks win/death condition, prints score, pauses, and restarts.
Key Variables
| Variable | Role |
|---|---|
V | Player’s fixed row (10) |
S | Score / kill count (starts at 1 via PI/PI) |
G | Gun column position |
X | Alien column position |
Y | Alien row (counts down from 0 to V) |
I | Loop counter / bullet row |
PI/PI Idiom
The constant 1 is never written as a numeric literal; instead PI/PI is used throughout (lines 11, 13, 16, 22, 26, 31, 35, 37). On this platform, numeric literals are stored with a 5-byte floating-point value inline in the BASIC line, whereas a variable reference or expression reuses the existing FP value. Using PI/PI avoids storing multiple copies of the float value for 1, saving a small amount of RAM per occurrence. This is a well-known Sinclair BASIC size-optimisation idiom.
Movement and Control Logic
Line 19 updates the gun column in a single expression:
LET G=G+(INKEY$="C")-(INKEY$="Z")*(G>PI/PI)
Boolean expressions evaluate to 1 (true) or 0 (false), so pressing C increments G and pressing Z decrements it, but only when G>1, preventing movement off the left edge. There is no equivalent right-edge guard, so the gun can move off-screen to the right.
Line 21 steers the alien horizontally: LET X=X+(Y>3)-(Y<4). When Y>3 and Y<4 are simultaneously true (impossible for integer Y), the alien moves diagonally. For integer Y, if Y>3 it moves right; if Y<4 (i.e., Y≤3) it moves left. This creates a simple triangular zigzag as Y increases through 4.
Block Graphic Rendering
All sprites are built from ZX Spectrum block graphics characters:
"\.'\. "— the decorative alien row at the top (lines 17–18)"\.:\. "— the player’s cannon sprite (line 20)"\'.\' "— the descending alien sprite (line 23)"\ :"— the laser bolt (lines 27, 32), immediately overwritten with" "to animate movement
Alien Fire Mechanic
Line 25 gives the alien a 20% chance each iteration to fire: IF RND<.8 THEN GOTO 30. When it does fire (the 20% case), lines 26–28 animate a descending bolt from Y+1 to V using a FOR loop, printing and immediately erasing each row. Line 29 then checks if the bolt’s column X matches the gun column G; if so, it jumps to line 38 (game over / score display).
Player Fire Mechanic
Line 30 checks for the M key. If pressed, lines 31–33 animate a bolt upward from V-1 to 1 (step -PI/PI = -1). Line 34 tests a hit: IF G<>X AND G<>X+PI/PI THEN GOTO 19. The two-column hit test (G=X or G=X+1) accounts for the alien sprite being two characters wide.
Win and Death Conditions
Line 37 is the critical branching point after a shot event:
IF S<>5 AND (ABS(X-G)>PI/PI OR Y<>V) THEN GOTO 13
This continues the game (spawning a new alien at line 13) if the score is not yet 5 AND the player was not hit (the alien column is not adjacent to the gun, or the alien hasn’t reached the player row). If S=5, or if the alien reached row V directly above the gun, execution falls through to line 38 to display the score.
Bugs and Anomalies
- No right-edge guard on gun: The left-movement guard
(G>PI/PI)on line 19 protects the left boundary, but there is no equivalent for the right, allowingGto exceed the screen width. - Score starts at 1:
Sis initialised toPI/PI(=1) on line 11, so the first kill givesS=2and the win conditionS=5is reached after four kills, not five. - Alien fire collision uses alien column, not bullet column: Line 29 tests
X=G, whereXis the alien’s column — which is also where the shot was fired from — so this check is correctly positioned for a vertically falling shot. - Initial TAB on line 15 is not cleaned up: Line 15 prints
TAB Xwithout a following PRINT statement to finish the line, meaning the cursor is left mid-line before the FOR loop on lines 16–18 begins printing.
Content
Source Code
5 REM "GALAXIAN"
10 LET V=10
11 LET S=PI/PI
12 LET G=5
13 LET X=4+S*3
14 LET Y=PI-PI
15 PRINT TAB X;
16 FOR I=PI/PI TO 5-S
17 PRINT "\.'\. ";
18 NEXT I
19 LET G=G+(INKEY$="C")-(INKEY$="Z")*(G>PI/PI)
20 PRINT AT V,G;" \.:\. ";AT Y,X;" "
21 LET X=X+(Y>3)-(Y<4)
22 LET Y=Y+PI/PI
23 PRINT AT Y,X;"\'.\' "
24 IF Y=V THEN GOTO 36
25 IF RND<.8 THEN GOTO 30
26 FOR I=Y+PI/PI TO V
27 PRINT AT I,X;"\ :";AT I,X;" "
28 NEXT I
29 IF X=G THEN GOTO 38
30 IF INKEY$<>"M" THEN GOTO 19
31 FOR I=V-PI/PI TO PI/PI STEP -PI/PI
32 PRINT AT I,G;"\ :";AT I,G;" "
33 NEXT I
34 IF G<>X AND G<>X+PI/PI THEN GOTO 19
35 LET S=S+PI/PI
36 CLS
37 IF S<>5 AND (ABS (X-G)>PI/PI OR Y<>V) THEN GOTO 13
38 PRINT S
39 PAUSE 50
40 CLS
41 RUN
42 SAVE "1022%4"
43 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
