Lander

Date: 198x
Type: Cassette
Platform(s): TS 1000
Tags: Game

This program implements a lunar lander game where the player must pilot a spacecraft to a safe landing on a surface. The lander is drawn using block graphic characters to form a small ship sprite, and the terrain is rendered with slash and backslash characters to create a rugged landscape with a flat landing pad at column 12. Physics are simulated through a velocity variable L that increases with gravity each iteration and can be reduced by firing the thruster with key “0”, while keys “5” and “8” move the craft horizontally. Scoring rewards gentle landings and fuel conservation, with bonuses for lower touchdown speed and remaining fuel (tracked by thruster presses K). The program uses SLOW mode for display timing and handles three distinct end states: successful landing, crash, and fuel exhaustion.


Program Analysis

Program Structure

The program flows through a clear set of phases: initialisation, main flight loop, landing detection, and outcome handling. Line 2040 set up score and lives; lines 50110 draw the play field; lines 120240 form the main game loop; and lines 250300 handle thruster firing. Outcomes branch to landing success (310), crash (380), fuel exhaustion (510), or game over (480).

Variables

VariableRole
SPlayer score
MLives remaining (starts at 2)
ALander row position (vertical)
BLander column position (horizontal)
LDownward velocity (gravity accumulator)
KThruster presses used (fuel counter)
ZFlag: 1 = crash reached via fuel-out path

Physics and Game Loop

Gravity is implemented by incrementing L by 0.5 each iteration at line 180, then adding L to the row coordinate A at line 200. This gives a simple parabolic fall. Firing the thruster (key "0") reduces velocity by 2.3 (line 260), but only if L>0, capping deceleration so the craft cannot gain upward momentum. Horizontal movement at line 230 uses the boolean arithmetic idiom: INKEY$="8" evaluates to 1 or 0, making left/right movement a single expression rather than branching IF statements. Fuel is limited to 20 thruster burns (K=20 triggers the fuel-out routine at line 510).

Sprite and Terrain Rendering

The lander sprite at line 150 uses ZX81 block graphics: \.'\ and \'.\ produce a small two-character-wide graphic resembling a lander body with legs. The terrain at lines 100110 is drawn once per life using slash characters for craggy ground and a row of block graphic characters for the surface. The flat landing pad is implicitly at column 12, enforced by the check B<>12 at line 310.

Landing and Crash Detection

A successful landing requires three simultaneous conditions checked at lines 310320: the lander must be at row 18, at column 12, and arriving at speed L<=1.5. The score bonus at line 350 is 1500 + (K*100), rewarding fuel efficiency. A further 1500-point bonus is granted if the lander arrives at the minimum possible speed (L=.1, set by line 330 as a floor). The crash animation at lines 390410 prints asterisks in a cross pattern to simulate an explosion.

Fuel Exhaustion Path

When fuel runs out (K=20), execution jumps to line 510, which displays a message then falls through a FOR loop (lines 530550) that drops the lander to the surface row by row. The flag Z is then set to 1 at line 560, and the crash routine is entered at line 390. Inside the crash handler, line 420 checks Z=1 to skip the speed-display message, since the fuel-out scenario already printed its own outcome text.

Notable Techniques and Anomalies

  • Boolean arithmetic for horizontal movement (line 230) is a compact ZX81 BASIC idiom avoiding two separate IF branches.
  • SLOW mode at line 70 is used deliberately to introduce display timing delay, serving as a frame-rate limiter without a PAUSE loop.
  • The INT(A)>=18 guard at line 220 prevents floating-point accumulation from pushing A past the screen boundary before the landing check at line 170.
  • At line 330, the condition L*10<0 is always false since L>=0 throughout normal play; this line effectively never fires, meaning the minimum speed floor of 0.1 is never applied. This appears to be a latent bug — the intended condition was likely L*10<=0 or simply L<=0.
  • Similarly, line 430 uses L*17<0 to conditionally add to L before displaying crash speed; since L cannot be negative here, this condition is also always false, meaning the speed display is always the raw accumulated velocity.
  • The lander starting column equals the starting row (B=A=3, line 140), meaning each new life always begins at the same position.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

Source Code

  10 REM 
  20 LET S=0
  30 LET M=2
  40 PAUSE 60
  50 CLS 
  60 PRINT AT 20,17;"SCORE ";S
  70 SLOW 
  80 PRINT ,"MEN LEFT ";M
  90 LET L=0
 100 PRINT AT 18,0;"/  // /  ///   /// / //// /   //"
 110 PRINT "////////////\''\''\''/////////////////"
 120 LET K=0
 130 LET A=3
 140 LET B=A
 150 PRINT AT A,B;"\.'\;;\'."
 160 IF INKEY$="0" THEN GOTO 250
 170 IF A=18 THEN GOTO 310
 180 LET L=L+.5
 190 PRINT AT A,B;"   "
 200 LET A=A+L
 210 IF A<0 THEN LET A=0
 220 IF INT (A)>=18 THEN LET A=18
 230 LET B=B+(INKEY$="8" AND B<29)-(INKEY$="5" AND B>0)
 240 GOTO 150
 250 PRINT TAB B;"VVV"
 260 LET L=L-(2.3 AND L>0)
 270 LET K=K+1
 280 IF K=20 THEN GOTO 510
 290 PRINT AT A+1,B;"   "
 300 GOTO 170
 310 IF B<>12 THEN GOTO 380
 320 IF L>1.5 THEN GOTO 380
 330 IF L*10<0 THEN LET L=.1
 340 PRINT AT 20,0;"YOU LANDED","GOING ";INT (L*10);" MPH."
 350 LET S=S+1500+(K*100)
 360 IF L=.1 THEN LET S=S+1500
 370 GOTO 40
 380 LET Z=0
 390 PRINT AT A-1,B+1;"*"
 400 PRINT TAB B;"***"
 410 PRINT TAB B+1;"*"
 420 IF Z=1 THEN GOTO 450
 430 IF L*17<0 THEN LET L=L+2
 440 PRINT AT 20,0;"YOU CRASHED",,"GOING ";INT (L*17);" MPH."
 450 LET M=M-1
 460 IF M=-1 THEN GOTO 480
 470 GOTO 40
 480 PRINT AT 11,12;"GAME OVER"
 490 PAUSE 500
 500 RUN 
 510 PRINT AT 20,0;"YOU RAN OUT",,"OF FUEL"
 520 PAUSE 60
 530 FOR A=A TO 18
 540 PRINT AT A,B;"   ";TAB B;"\.'\;;\'."
 550 NEXT A
 560 LET Z=1
 570 GOTO 390

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top