This program simulates a lunar lander descent game where the player manages thrust and burn duration to safely land a spacecraft. Each turn the player inputs thrust level and a duration (capped at 10 cycles), and the simulation updates height, velocity, and fuel over that many animation frames. The display uses AT coordinates to render a crude spacecraft sprite that moves vertically on screen, with height scaled to fit the 22-row display by dividing by 100. Outcomes include a successful landing (velocity under 10 at low altitude with fuel remaining), a crash landing with a crater depth calculation, fuel exhaustion, or explosion if the craft somehow exceeds 1600 units altitude.
Program Analysis
Program Structure
The program is self-contained within lines 2005–2360, looping back via RUN at line 2330. The overall flow is:
- Initialise game variables (lines
2005–2030). - Wait for ENTER to begin (lines
2040–2047). - Inner animation/physics loop over
Dcycles (FOR A=1 TO D, lines2095–2228). - Prompt for thrust and duration after each burst (lines
2230–2270). - Outcome reporting and restart (lines
2280–2360).
Variable Roles
| Variable | Role |
|---|---|
H | Height (starts ~1350–1549, decreases each cycle) |
V | Velocity (downward; increases with gravity term 17-T/3) |
F | Fuel remaining (drains by T/5 per cycle) |
T | Thrust level entered by player |
D | Duration (number of cycles to simulate, max 10) |
R | Result code: 0=in progress, 1=safe, 2=crash, 3=no fuel |
K1 | Horizontal column of the sprite, drifts randomly |
A | Loop counter for current burst |
Physics Model
Each cycle the velocity is updated as V = V + 17 - T/3. A thrust of roughly 51 exactly cancels gravity, making that the neutral point. Height decreases by the current velocity: H = H - V. Fuel drains by T/5 per cycle, so higher thrust is more fuel-hungry. The horizontal position K1 drifts by a random increment each cycle, wrapping back to column 20 if it exceeds 26.
Display and Sprite Rendering
The spacecraft sprite is drawn at PRINT AT 16-H/100, K1, mapping the full height range (~0–1600) to screen rows 0–16. The sprite characters \.:\''\:. represent a block-graphic shape. Lines 2140 and 2145 test the even/odd parity of A with 2*(INT(A/2))=A, but both branches print the identical sprite string — no actual alternation occurs. A status line at row 0 shows HGT, VEL, FL (fuel), and a progress bar at row 16 shows elapsed time within the burst.
Rounding Idiom
Lines 2101–2106 apply a multiply-by-10 / INT / divide-by-10 sequence to F, H, and V every cycle. This truncates each value to one decimal place, preventing floating-point accumulation from producing untidy display strings. It is a common Sinclair BASIC technique for controlling numeric display width.
Early Loop Exit
When a landing result is detected mid-burst (R>0 or H<1), lines 2107–2108 force H=0 and set A=D, which causes the FOR…NEXT loop to terminate on its next iteration, jumping to the outcome detection block at line 2280. This avoids a direct GOTO out of the loop.
Outcome Logic
| Code | Condition | Message |
|---|---|---|
R=1 | H<100 and F>0 and V<10 | SUCCESSFUL LANDING |
R=2 | H<100 and V>9 | CRASH LANDING + crater depth INT(V*4.5) feet |
R=3 | F<1 | YOU HAVE RUN OUT OF FUEL |
| — | H>1600 | YOUR SHIP EXPLODED |
Note that R=3 is set at line 2223 but the program also reaches line 2300 directly from line 2195 via GOTO 2300 when fuel runs out mid-burst, bypassing the R assignment. The PRINT at 2300 is therefore reachable by two separate paths.
Notable Anomalies
- Lines
2140and2145are intended to alternate two sprite frames but print the same string — no visual flicker is produced. - The duration input at line
2260is validated only for exceeding 10 (IF D>10 THEN GOTO 2260); a value of 0 or a negative number is accepted and would produce a zero-iteration or backwardFORloop. - The
H>1600check at line2125branches to2305, which only prints ifH>1600— this is consistent, but upward motion is physically implausible given the gravity-dominated velocity update, so this path is rarely reachable in practice. - Line
2350containsSAVE "1027%3"; the%3escape denotes an inverse digit3, functioning as an auto-run flag on load.
Content
Source Code
2005 LET R=0
\n2010 LET H=1350+INT (RND*200)+1
\n2020 LET F=80+(INT (RND*400)/2)+1
\n2030 LET V=INT (RND*20)+1
\n2035 PRINT
\n2040 PRINT "PRESS ENTER TO BEGIN DESCENT"
\n2045 INPUT U$
\n2047 CLS
\n2048 LET T=1
\n2050 LET D=1
\n2060 LET K1=1
\n2090 CLS
\n2095 FOR A=1 TO D
\n2100 PRINT AT 16-H/100,K1;" "
\n2101 LET F=INT (10*F)
\n2102 LET F=F/10
\n2103 LET H=INT (10*H)
\n2104 LET H=H/10
\n2105 LET V=INT (10*V)
\n2106 LET V=V/10
\n2107 IF R>0 OR H<1 THEN LET H=0
\n2108 IF R>0 OR H<1 THEN LET A=D
\n2109 PRINT AT 0,0;"HGT:";H;" VEL:";V;" FL:";F;" "
\n2110 LET V=V+17-T/3
\n2115 LET K1=K1+RND
\n2116 IF K1>26 THEN LET K1=20
\n2120 LET H=H-V
\n2125 IF H>1600 THEN GOTO 2305
\n2130 LET F=F-T/5
\n2140 IF 2*(INT (A/2))=A THEN PRINT AT 16-H/100,K1;"\.:\''\:."
\n2145 IF 2*(INT (A/2))<>A THEN PRINT AT 16-H/100,K1;"\.:\''\:."
\n2190 PRINT AT 16,0;"TIME:";D-A;"% % % % % % % % % % % % % % % % % % % % % % % % % "
\n2195 IF F<1 THEN GOTO 2300
\n2220 IF H<100 AND F>0 AND V<10 THEN LET R=1
\n2222 IF H<100 AND V>9 THEN LET R=2
\n2223 IF F<1 THEN LET R=3
\n2224 IF R>0 THEN GOTO 2280
\n2228 NEXT A
\n2230 PRINT AT 19,0;"THRUST? ";
\n2235 INPUT T
\n2250 PRINT T," DURATION?( 11)"
\n2260 INPUT D
\n2265 IF D>10 THEN GOTO 2260
\n2270 GOTO 2090
\n2280 IF R=1 THEN PRINT "SUCCESSFUL LANDING"
\n2290 IF R=2 THEN PRINT " CRASH LANDING","DIGGING A ";INT (V*4.5);" FOOT CRATER"
\n2300 IF R=3 THEN PRINT "YOU HAVE RUN OUT OF FUEL","GOODBYE"
\n2305 IF H>1600 THEN PRINT "YOUR SHIP EXPLODED"
\n2310 PAUSE 400
\n2320 CLS
\n2330 RUN
\n2340 CLEAR
\n2350 SAVE "1027%3"
\n2360 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
