Skip to content
Game 3

Make another attempt

Give an attempt a beginning, a result and a clean way to try again, without adding fuel or sideways steering yet.

Continue with Brake before you arrive. Landing is already a game. Give an attempt a beginning, a result and a clean way to try again, without adding fuel or sideways steering yet.

This step reorganises the program. Most of the flight calculations move to new line numbers so the title, setup and reusable routines have their own space. Use this map to recognise them:

Existing work Old lines New lines
Read input and choose thrust 80–90 200, 260–270
Update and limit velocity 95–97 280–300
Propose position and resolve boundaries 100–110 310–350
Choose a character, draw and remember position 120, 128–140 360, 375–390
Handle contact and repeat 150–160 400–410, 700–740

The result routine now waits for a retry or quit choice instead of stopping immediately. Remove the listed old lines before adding the new routines; otherwise an old STOP or jump can remain in the new loop. Enter the entire change before running it.

Add lines 60, 70, 200, 260, 270, 280, 290, 300, 310, 330, 340, 350, 360, 370, 375, 380, 390, 400, 410, 600, 610, 620, 630, 650, 700, 710, 720, 740, 770, 780, 790, 795, 796, 797, 800, 810, 820, 830, 850, 860. Replace lines 50, 80, 100, 110, 120, 130, 140, 150, 160. Delete lines 20, 30, 40, 90, 95, 96, 97, 105, 125, 128, 155.

50 PRINT AT 3,9;"TOUCHDOWN"
60 PRINT AT 6,2;"SPACE: brake your fall"
70 PRINT AT 8,2;"Thrust is unlimited."
80 PRINT AT 10,2;"Safe speed: 0 to 12"
100 PRINT AT 15,2;"S launches. Q quits."
110 GO SUB 800: IF k$="q" THEN GO TO 850
120 CLS: GO SUB 600
130 LET x=24: LET y=400: LET v=0: LET r=4: LET burn=0
140 PRINT AT r,x;"A"
150 PRINT AT 0,1;"SPEED       SAFE 0 TO 12"
160 PRINT AT 1,1;"SPACE THRUST  Q QUIT"
200 LET k$=INKEY$: IF k$="q" THEN GO TO 850
260 LET burn=0
270 IF k$=" " THEN LET burn=1
280 LET v=v+2-6*burn
290 IF v>60 THEN LET v=60
300 IF v<-30 THEN LET v=-30
310 LET ny=y+v: LET contact=0: LET limit=1900
330 IF ny>=limit THEN LET contact=1
340 IF contact=1 THEN LET ny=limit
350 IF ny<300 THEN LET ny=300: LET v=0
360 LET nr=INT (ny/100)
370 PRINT AT 0,7;v;"   "
375 LET a$="A": IF burn=1 THEN LET a$="*"
380 PRINT AT r,x;" ";AT nr,x;a$
390 LET y=ny: LET r=nr
400 IF contact=1 THEN GO TO 700
410 PAUSE 2: GO TO 200
600 FOR c=0 TO 31
610 FOR j=20 TO 21: PRINT PAPER 4;INK 0;AT j,c;" ";: NEXT j
620 PRINT PAPER 4;INK 0;AT 20,c;"#"
630 NEXT c
650 RETURN
700 PRINT AT r,x;"A"
710 LET m$="Too fast!"
720 IF v>=0 THEN IF v<=12 THEN LET m$="Safe landing!"
740 PRINT AT 2,1;m$;"    "
770 PRINT AT 1,1;"R retries. Q quits.            "
780 IF INKEY$<>"" THEN GO TO 780
790 LET k$=INKEY$: IF k$<>"r" AND k$<>"q" THEN GO TO 790
795 IF INKEY$<>"" THEN GO TO 795
796 IF k$="q" THEN GO TO 850
797 GO TO 120
800 IF INKEY$<>"" THEN GO TO 800
810 LET k$=INKEY$: IF k$<>"s" AND k$<>"q" THEN GO TO 810
820 IF INKEY$<>"" THEN GO TO 820
830 RETURN
850 IF INKEY$<>"" THEN GO TO 850
860 PAPER 0: INK 7: CLS: PRINT "Finished.": STOP

Separate setup from flight

Lines 50–100 put instructions on the screen. At line 110, GO SUB 800 calls a routine and remembers where to return. Its RETURN resumes with the IF statement on that same line, where a Q choice can leave the program. The flight begins at 120.

Line 120 clears the title and calls the ground-drawing routine at 600. It visits every column; the inner loop fills rows 20 and 21 with green PAPER before placing the skyline character. FOR counters must be single letters in Sinclair BASIC. c selects a column and j selects a row. Each NEXT belongs to its own loop.

Line 130 resets position, velocity, display row and the burn flag. x=24 names the unchanged craft column. It is still a vertical game. The first character and instruments are drawn before execution reaches the repeating flight loop at 200.

Make contact an outcome

contact starts at zero on each update. If the candidate reaches the surface, it becomes 1 and the candidate is clamped before drawing. Line 400 then jumps to 700. Movement does not continue behind the result.

The result routine first removes the provisional flame. It assumes a hard landing, then changes the message if velocity is in the safe interval. The two nested IF tests check its lower and upper limits. m$ holds the chosen message; PRINT displays it once.

The loop now returns to 200, keeping setup outside repeated movement. Retry returns to 120 instead: it redraws the ground and runs all the starting assignments again. The start-wait routine has already returned, so repeated retries do not accumulate unfinished GO SUB calls.

Why does retry go to 120 rather than straight back to the flight loop at 200?

Show the explanation

Jumping to 200 would keep the old position and velocity, and could immediately produce the same contact again. Line 120 rebuilds the display and line 130 resets the values that describe an attempt.

A press belongs to one phase

The routine at 800 first waits for an empty keyboard reading. Line 810 then looks for S or Q. Its two comparisons, joined by AND, reject any other reading. AND is true only when both comparisons are true: the reading must be different from S and different from Q to keep waiting. After a valid choice, line 820 waits for release before returning. The value in k$ still holds the recognised choice even after the physical key is released.

The result routine follows the same pattern: release old controls, recognise R or Q, release that answer, then branch. <> means not equal. The condition on line 790 continues waiting while the reading is neither accepted choice.

Q during flight goes to 850. That line waits for release before 860 clears the screen and stops. Otherwise a held Q could reach the BASIC editor after the game ended. Finished. and the intentional STOP report confirm the exit.

Complete a safe landing, retry, then make a hard landing and retry again. Try holding S and R; the next phase should wait for release. Press Q alone during flight, hold it briefly, then release it. The BASIC prompt should not contain an unwanted q.

Complete program for this step
10 BORDER 0: PAPER 0: INK 7: BRIGHT 1: CLS
50 PRINT AT 3,9;"TOUCHDOWN"
60 PRINT AT 6,2;"SPACE: brake your fall"
70 PRINT AT 8,2;"Thrust is unlimited."
80 PRINT AT 10,2;"Safe speed: 0 to 12"
100 PRINT AT 15,2;"S launches. Q quits."
110 GO SUB 800: IF k$="q" THEN GO TO 850
120 CLS: GO SUB 600
130 LET x=24: LET y=400: LET v=0: LET r=4: LET burn=0
140 PRINT AT r,x;"A"
150 PRINT AT 0,1;"SPEED       SAFE 0 TO 12"
160 PRINT AT 1,1;"SPACE THRUST  Q QUIT"
200 LET k$=INKEY$: IF k$="q" THEN GO TO 850
260 LET burn=0
270 IF k$=" " THEN LET burn=1
280 LET v=v+2-6*burn
290 IF v>60 THEN LET v=60
300 IF v<-30 THEN LET v=-30
310 LET ny=y+v: LET contact=0: LET limit=1900
330 IF ny>=limit THEN LET contact=1
340 IF contact=1 THEN LET ny=limit
350 IF ny<300 THEN LET ny=300: LET v=0
360 LET nr=INT (ny/100)
370 PRINT AT 0,7;v;"   "
375 LET a$="A": IF burn=1 THEN LET a$="*"
380 PRINT AT r,x;" ";AT nr,x;a$
390 LET y=ny: LET r=nr
400 IF contact=1 THEN GO TO 700
410 PAUSE 2: GO TO 200
600 FOR c=0 TO 31
610 FOR j=20 TO 21: PRINT PAPER 4;INK 0;AT j,c;" ";: NEXT j
620 PRINT PAPER 4;INK 0;AT 20,c;"#"
630 NEXT c
650 RETURN
700 PRINT AT r,x;"A"
710 LET m$="Too fast!"
720 IF v>=0 THEN IF v<=12 THEN LET m$="Safe landing!"
740 PRINT AT 2,1;m$;"    "
770 PRINT AT 1,1;"R retries. Q quits.            "
780 IF INKEY$<>"" THEN GO TO 780
790 LET k$=INKEY$: IF k$<>"r" AND k$<>"q" THEN GO TO 790
795 IF INKEY$<>"" THEN GO TO 795
796 IF k$="q" THEN GO TO 850
797 GO TO 120
800 IF INKEY$<>"" THEN GO TO 800
810 LET k$=INKEY$: IF k$<>"s" AND k$<>"q" THEN GO TO 810
820 IF INKEY$<>"" THEN GO TO 820
830 RETURN
850 IF INKEY$<>"" THEN GO TO 850
860 PAPER 0: INK 7: CLS: PRINT "Finished.": STOP

Sources

Steven Vickers, edited by Robin Bradbeer, ZX Spectrum BASIC Programming, second edition (Sinclair Research, 1983), chapters 3–5 (conditions, loops and subroutines), chapter 13 (AND), and chapter 18 (keyboard polling).