On 20 July 1969, Eagle came down to the Moon with Neil Armstrong and Buzz Aldrin inside. The Moon has no air, so no parachute or wings can help: the only way to slow down is to fire a rocket engine downward. Fire too little and you hit the ground hard. Fire too much and you run out of fuel while still high up, and then you fall.
In late 1969, a 17-year-old student in the United States, Jim Storer, wrote a game about it on his school’s computer. Each turn you chose how much fuel to burn, and the computer worked out where the lander had got to. Here is our version. You start 500 m above the Moon, already falling at 30 m/s, with 120 units of fuel. Each second you choose a burn: how many units of fuel to fire, from 0 to 5.
Before you play much: what do you think is the best way to land without running out of fuel?
Pick an answer to see why.
You need: for the blocks, variables, ask and repeat until, from Grade 7. For the Python (from Grade 8), while loops and functions.
Try it
Play a few times with the lander above. Press Start again whenever you like.
- a.The careful landing. Burn 5 every second until the speed is under 2 m/s. Then keep it slow: burn 2 when it creeps over 2 m/s, and less when it is slower. What happens to your fuel?
- b.The late landing. Burn nothing until the lander is about 250 m up. Then burn 5 every second until it is slow, and land gently. How much fuel is left?
- c.Watch the dots. When are they far apart, and when close together?
How it works
Every second, the game does three small sums, always in the same order.
- The fuel: take away the burn. Burning 5 units leaves 5 fewer.
- The speed: the Moon’s pull makes anything falling there go 1.62 m/s faster every second. That is its gravity (on Earth it is 9.8 m/s every second, six times as much). Then the engine takes away 1 m/s for every unit burned. So the new speed is the old speed + 1.62 − the burn.
- The height: the lander falls as far as its new speed says, as if it had kept that speed all second. At 30 m/s it would drop 30 m. So the new height is the old height − the speed.
That is the whole game. The burn changes the speed, and the speed changes the height. The program does those three sums again and again, a second at a time, until the height reaches 0. A program that copies how something in the real world behaves, step by step, is called a simulation.
Suppose the lander is falling at 2 m/s and you burn exactly 1.62 units every second. What happens?
Pick an answer to see why.
One simplification: a real lander gets lighter as it burns fuel, so each unit slows it a little more than the last. Jim Storer’s game included that; ours leaves it out to keep the sums short. The ideas stay the same.
Program it
The 1969 game in blocks
Here is the game in blocks: the three sums inside a repeat until loop that goes round once a second until the lander is down. Each time round it asks for the burn; two if blocks keep it to at most 5 and at most the fuel left.
The same game in Python (from Grade 8)
In Python the loop is a while. This first program never burns at all, to see what the Moon does on its own:
height = 500speed = 30fuel = 120second = 0while height > 0: burn = 0 fuel = fuel - burn speed = speed + 1.62 - burn height = height - speed second = second + 1 print(second, round(height, 1), round(speed, 1), fuel)print('Landed at', round(speed, 1), 'm/s')Output
1 468.4 31.6 1202 435.1 33.2 1203 400.3 34.9 1204 363.8 36.5 1205 325.7 38.1 1206 286.0 39.7 1207 244.6 41.3 1208 201.7 43.0 1209 157.1 44.6 12010 110.9 46.2 12011 63.1 47.8 12012 13.6 49.4 12013 -37.4 51.1 120Landed at 51.1 m/sWithout the engine, the speed goes up by 1.62 every second, and the lander hits the ground 13 seconds after the start. In the last second it went from 13.6 m up to “−37.4”: the loop stops once the height is 0 or less, so the last height is below the ground. Only the speed at that moment matters: 51.1 m/s, about 184 km/h.
Let a function choose the burn
A pilot is just a rule: look at the height, the speed and the fuel, and decide the burn. In Python a rule like that is a function. This one is the careful pilot: brake whenever the lander falls faster than 2 m/s.
def burn(height, speed, fuel): if speed > 2: return 5 return 0The widget below calls your burn once every second of the flight, with the lander’s height, speed and fuel, and does the three sums with whatever it gives back. Press Fly. Then change the rule in the program above (Edit), and fly again.
Three pilots, one program
Now let a program fly three pilots one after another and report how each one did. The function fly takes a pilot as its input: in Python, a function can be handed to another function like any other value.
def never(height, speed, fuel): return 0 def careful(height, speed, fuel): if speed > 2: return 5 return 0 def wait_then_brake(height, speed, fuel): if speed > height / 10 + 2: return 5 return 0 def fly(name, pilot): height = 500 speed = 30 fuel = 120 second = 0 while height > 0: burn = pilot(height, speed, fuel) if burn > 5: burn = 5 if burn > fuel: burn = fuel if burn < 0: burn = 0 fuel = fuel - burn speed = speed + 1.62 - burn height = height - speed second = second + 1 if fuel == 0 and burn > 0: print(name, 'is out of fuel after', second, 's,', round(height), 'm up, speed', round(speed, 1), 'm/s') print(name, 'landed at', round(speed, 1), 'm/s after', second, 's, with', fuel, 'fuel left') fly('never', never)fly('careful', careful)fly('wait_then_brake', wait_then_brake)Output
never landed at 51.1 m/s after 13 s, with 120 fuel leftcareful is out of fuel after 55 s, 330 m up, speed -0.9 m/scareful landed at 33.1 m/s after 76 s, with 0 fuel leftwait_then_brake landed at 1.7 m/s after 35 s, with 35 fuel leftWhat your program shows
Never burning crashes at 51.1 m/s. The careful pilot crashes too: it ran dry after 55 seconds, still 330 m up, and fell the rest of the way. Waiting, then braking lands at 1.7 m/s after only 35 seconds, with 35 units left. Why did the careful pilot, with the same fuel, do so badly? Look at the speed. It starts at 30 m/s. Every second in the air, the Moon adds 1.62. Every unit of fuel takes 1 away. So at any moment:
speed now = 30 + 1.62 × seconds so far − fuel burned so far
Check it with the program’s own numbers. When the careful pilot ran dry after 55 seconds: 30 + 1.62 × 55 − 120 = 30 + 89.1 − 120 = −0.9 m/s, exactly the speed it printed. For the late pilot after 35 seconds: 30 + 1.62 × 35 − 85 = 1.7 m/s, its landing speed.
So to land at almost 0 m/s you must burn about 30 + 1.62 × (the seconds you spend in the air). The 30 is the speed you start with, and you can’t avoid it. The 1.62 for every second is a tax the Moon charges for being in the air. The careful pilot crept down at 2 m/s, so it would have needed minutes in the air, and the tax ate all its fuel. The late pilot was on the Moon in 35 seconds. The less time you spend in the air, the less fuel you need.
Nobody told the program about a “gravity tax”. It came out of three lines of arithmetic, repeated.
Going further still
Mars and Earth. Change 1.62 to 3.7 (Mars) in the three-pilots program. Does wait_then_brake still land? Then try 9.8 (Earth). Why can no pilot land on Earth with this engine, however much fuel it carries? (Hint: compare 9.8 with the biggest burn.)
Smaller steps. A real lander’s computer decides many times a second, not once. Change the program so that each step is 0.1 seconds: the speed changes by 0.162 − burn ÷ 10 and the height by speed ÷ 10. Do the landings change? Why might they?
Challenges
★ The engine won’t start (blocks)
The engine has failed, and the lander starts still, at the height you type. Finish the program so that it says how many seconds the lander takes to reach the ground (use the same sums: speed goes up by 1.62 each second, the height goes down by the speed). Then press Test. Look at the answers for 100 m and 400 m. What do you notice?
★★ Check a flight plan (Python, from Grade 8)
A pilot writes the burns down before the flight as a list, one number a second ([0, 0, 5, 5]). After the list ends, the burn is 0. Write flight(burns) that flies the plan from the usual start (500 m, 30 m/s, 120 fuel) with the game’s rules, and gives back 'safe' (3 m/s or slower), 'hard' (up to 6 m/s) or 'crash'.
def flight(burns): # burns: a list of burns, one a second return 'crash' print(flight([]))★★★ One autopilot for every start (Python, from Grade 8)
The wait_then_brake rule lands from 500 m. But try it from other starts: higher up, falling faster, with less fuel. It lands safely from only two of the eight starts in the tests below. Write a burn that lands safely from every start in the tests. The program’s fly does the sums and gives back 'safe', 'hard' or 'crash'; change only burn.
def burn(height, speed, fuel): if speed > height / 10 + 2: return 5 return 0 def fly(height, speed, fuel): while height > 0: b = burn(height, speed, fuel) if b > 5: b = 5 if b > fuel: b = fuel if b < 0: b = 0 fuel = fuel - b speed = speed + 1.62 - b height = height - speed if speed <= 3: return 'safe' elif speed <= 6: return 'hard' return 'crash' print(fly(2000, 0, 150))Questions
In the game, the lander falls at 20 m/s and you burn 5. What is its speed one second later?
Pick an answer to see why.
The lander is 100 m up, falling at 10 m/s, and you burn 0 for two seconds. Work out its speed and height after each second.
Answer
A friend’s autopilot keeps the lander falling at a steady 2 m/s all the way down from 500 m. Explain, without a program, why it needs far more fuel than a pilot who falls first and brakes late.
Answer
The ispace lander’s software stopped trusting its height sensor and flew with a height that was 5 km wrong. Your burn function also trusts the height it is given. What could a program do to notice that a reading might be wrong, without throwing away good readings?
Answer
Where to go next
- Grade 8, Decisions and Loops in Python:
whileloops, which fly the lander a second at a time. - Grade 8, Functions: functions that give back an answer, like
burn. - Grade 8, Physical Computing: computers that sense and act, as an autopilot does every second.
- Why do snakes and ladders games take so long? Another simulation: a game played thousands of times to find out what usually happens.
- How does a heater, or a drone, hold steady? Correcting a little at a time instead of all or nothing, the way a drone hovers.
- How did the Moon landing’s computer survive an overload? The computer inside Eagle, and the alarms that went off on the way down (Grades 9–12). (Coming soon.)
