Lunar landing game madness
|
04-07-2024, 02:03 AM
(This post was last modified: 04-12-2024 06:08 PM by robve.)
Post: #1
|
|||
|
|||
Lunar landing game madness
So I got one of those "Mathemagician" (APF 1500) calculators from 1980 last week to try and could not stop myself like a lunatic to get perfect Lunar Landing game landings.
The game is fairly simple, like this in HP-71B BASIC: Code: 100 INTEGER F,V,H,A @ DELAY 0,0 Surely there must be a better way to perform a perfect landing by punching the right sequence of rocket burns to burn as little fuel as possible? It's not that easy (at least not with the Mathemagician version of the game). I came up with a relatively simple method to find the perfect sequence of burns, which doesn't involve a numerical solver, but does take some time to compute a solution using a brute-force approach. This approach can surely be improved or replaced with a more elegant and faster algorithm Let's think of this problem as if we're taking off. A landing is a time-reversed takeoff. The best way to preserve fuel is to go full burn when taking off to reach a high velocity. Likewise, when landing, a full burn to the surface from a set altitude and velocity uses less fuel overall. Worst way to take off (or land) is to stall and burn fuel without making any progress. For example, if the lander is at an altitude (height) h0=100 and velocity v0=20, we set the burn rate to a maximum (say a=9) to land on a lunar surface. Assuming the moon's gravity g=5 (which must be lower than a, of course!), then we have an effective acceleration (time-reversed deceleration) of 4, giving the following velocity and height: 0 (at the surface) 4 4 8 12 12 24 16 40 20 60 24 84 28 112 This consumed 63 units of fuel. If we set a=7 then we consume 70 units of fuel to get to an altitude of 110. Computed in Lua: g = 5; a = 9; v = 0; h = 0; f = 99 while h >= 0 and h <= h0 do f = f - a -- out of fuel? if f < 0 then a = f + a; f = 0 end v = v + a - g h = h + v print(v, h) end In this example we already passed the desired height h0=100 and also our final speed exceeds v0=20. The tricky part is to determine when and where to reduce the burn to reach the exact height h0 with velocity v0. Let's add an autopilot of sorts that computes a burn rate b that is required to reach the desired velocity at the end of the remaining distance to altitude h0. It may overshoot some, but we want to get the velocity under control. Such burn rate b can be computed with: d = h0 - h t = d / v b = (v0 - v) / t + g if b is small or negative, then we really have to slow down. In this case we found the point at which the full burn should stop to allow the autopilot to take over control. Let's do this by setting mode flag m=true: w = 1; m = false g = 5; a = 9; v = 0; h = 0; f = 99 while h >= 0 and h <= h0 do f = f - a -- out of fuel? if f < 0 then a = f + a; f = 0 end v = v + a - g h = h + v -- remaining time steps t to h0 and burn b to slow to v0 d = h0 - h t = d / v b = (v0 - v) / t + g -- switch to autopilot? if b<=w and nor m then m = true r = d + v s = v - v0 n = 0 print("now on autopilot") end print(v, h) if m then -- on autopilot a = math.max(math.floor(b), 0) n = n + 1 end end For h0=300 and v0=20 for the Mathemagician Lunar Lander game we get: 4 4 8 12 12 24 16 40 20 60 24 84 28 112 32 144 now on autopilot 36 180 31 211 27 238 23 261 21 282 19 301 Not bad. But not good enough, because it overshoots h0 by 1 unit and the velocity is one unit off from the target v0. To find the perfect burn sequence, we can use a bit of brute-force to find the solutions by computing the required burns after the full blast stage. For the above conditions, there are nine remaining burns each with five steps for n=6 (n is computed as above) that are perfect: 3 6 0 0 0 4 4 1 0 0 5 2 2 0 0 5 3 0 1 0 6 0 3 0 0 6 1 1 1 0 6 2 0 0 1 7 0 0 2 0 7 0 1 0 1 All of these nine burn sequences of five steps give a perfect landing using the same amount of fuel. For example 3, 6, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9 lands the lunar lander with 9 fuel units remaining (did I mention the Mathemagician version of this game has tight tolerances?). To brute force compute the solutions we need: -- the remaining velocities sum to k k = (n - 1) * g - s We want to find a burn sequence a[1], a[2], ..., a[n-1] such that \( \sum_{i=1}^{n-1} a_i = k \) and \( v_0 + \sum_{i=1}^{n-1} \sum_{j=1}^i g-a_i = v_0 + \sum_{i=1}^{n-1} (n-i)(g-a_i) = r \) where \( r \) is the remaining distance to h0 plus one more step (the current velocity v) as set by the autopilot r = d + v. The Lua code to produce perfect lunar landing sequences: Code: -- compute perfect solutions to a lunar lander game A version in a generic BASIC: Code: 100 CLEAR : V0=20 : H0=300 I wonder what other methods or solvers are applicable. Because it is a discrete problem with discrete solutions, rather than a physics-based continuous model, it smells like a bin-packing problem (that's NP-hard), but on the other hand, it's not the same thing. - Rob EDIT: moved a loop to compute the next burn sequence, so that the first burn sequence is not omitted when it could be a solution. Also added game code. "I count on old friends to remain rational" |
|||
« Next Oldest | Next Newest »
|
Messages In This Thread |
Lunar landing game madness - robve - 04-07-2024 02:03 AM
RE: Lunar landing game madness - EdS2 - 04-07-2024, 06:55 AM
RE: Lunar landing game madness - Maximilian Hohmann - 04-07-2024, 02:39 PM
RE: Lunar landing game madness - robve - 04-11-2024, 06:45 PM
RE: Lunar landing game madness - Jim Horn - 04-08-2024, 09:36 PM
RE: Lunar landing game madness - Thomas Okken - 04-08-2024, 10:24 PM
|
User(s) browsing this thread: 2 Guest(s)