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
2010 LET H=1350+INT (RND*200)+1
2020 LET F=80+(INT (RND*400)/2)+1
2030 LET V=INT (RND*20)+1
2035 PRINT
2040 PRINT "PRESS ENTER TO BEGIN DESCENT"
2045 INPUT U$
2047 CLS
2048 LET T=1
2050 LET D=1
2060 LET K1=1
2090 CLS
2095 FOR A=1 TO D
2100 PRINT AT 16-H/100,K1;" "
2101 LET F=INT (10*F)
2102 LET F=F/10
2103 LET H=INT (10*H)
2104 LET H=H/10
2105 LET V=INT (10*V)
2106 LET V=V/10
2107 IF R>0 OR H<1 THEN LET H=0
2108 IF R>0 OR H<1 THEN LET A=D
2109 PRINT AT 0,0;"HGT:";H;" VEL:";V;" FL:";F;" "
2110 LET V=V+17-T/3
2115 LET K1=K1+RND
2116 IF K1>26 THEN LET K1=20
2120 LET H=H-V
2125 IF H>1600 THEN GOTO 2305
2130 LET F=F-T/5
2140 IF 2*(INT (A/2))=A THEN PRINT AT 16-H/100,K1;".:'':."
2145 IF 2*(INT (A/2))<>A THEN PRINT AT 16-H/100,K1;".:'':."
2190 PRINT AT 16,0;"TIME:";D-A;"% % % % % % % % % % % % % % % % % % % % % % % % % "
2195 IF F<1 THEN GOTO 2300
2220 IF H<100 AND F>0 AND V<10 THEN LET R=1
2222 IF H<100 AND V>9 THEN LET R=2
2223 IF F<1 THEN LET R=3
2224 IF R>0 THEN GOTO 2280
2228 NEXT A
2230 PRINT AT 19,0;"THRUST? ";
2235 INPUT T
2250 PRINT T," DURATION?( 11)"
2260 INPUT D
2265 IF D>10 THEN GOTO 2260
2270 GOTO 2090
2280 IF R=1 THEN PRINT "SUCCESSFUL LANDING"
2290 IF R=2 THEN PRINT " CRASH LANDING","DIGGING A ";INT (V*4.5);" FOOT CRATER"
2300 IF R=3 THEN PRINT "YOU HAVE RUN OUT OF FUEL","GOODBYE"
2305 IF H>1600 THEN PRINT "YOUR SHIP EXPLODED"
2310 PAUSE 400
2320 CLS
2330 RUN
2340 CLEAR
2350 SAVE "1027%3"
2360 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
