Moon lander game in python

Floating point numbers, called floats in python, are numbers which have a decimal point and sometimes digits after the decimal point. They are different to integers which represent whole numbers and do not have a decimal point. You can display the type of values or variables using the type() function. The following example displays the type of several values. In python 3, the division operation / always returns a float.

>>> type(3)
<class 'int'>
>>> type(3.14)
<class 'float'>
>>> type(3.0)
<class 'float'>
>>> type(6/2)
<class 'float'>

Printing floats can be messy because python prints as many decimal places as it thinks it needs up to about 16 significant figures. However python provides several methods of formatting floats to improve output. We will look at the .format() method which can be applied to any string and can be used to format all data types. It produces a new string which can be printed or saved to a file or stored in a variable for later use or passed to another function. .format() uses {} placeholders in a string to insert values of variables in the new string. Inside these curly braces you can specify details such as which value from the arguments (before the :), how wide the string is (integer just after the :), how many decimal places to show after the decimal point (for example .3f includes 3 decimal places after the decimal point of a float. Hence, to include the value of altitude to 3 decimal places in a new string we use

'Altitude = {:.3f}'.format(altitude)

which returns a string 'Altitude=970.000'

A width can be provided immediately following the :. To format and print several values in the same string, provided in the correct order in format, we have the following example:

print("Altitude={:8.3f} Speed={:6.3f} Fuel={:8.3f} Impact={:6.3f} Previous burn={:6.3f}".format(altitude,speed,fuel,impact,burn))

which prints the following:

Altitude= 970.000 Speed=29.422 Fuel=1478.000 Impact=32.969 Previous burn=22.000

This exercise also demonstrates the benefits of comments in python code. Comments are not interpreted by python and do not affect the program at all. However, they make it much easier for other people, or even yourself a few weeks later, understand what the program is supposed to do. All comments start with a #. Here is a game to pilot the lunar landing module onto the moon. Read the comments to work out what you need to do and then give it a go. See if you can work out how it works.

# moonlander.py
# this game simulates a lunar landing module (LLM) landing on the moon
# you are the pilot and need to control how much fuel you burn in the
# retro rockets so that your descent speed slows to zero just as your
# altitude above the moon's surface reaches zero. If you impact the moon
# more than 5 m below the surface, or your speed on impact is
# greater than 5 m/s then you have considered to have crashed.
# Otherwise it is considered to be a 'good' landing.
# If you run out of fuel, LLM will accelerate towards moon by gravity.

# set up the initial parameters
speed = 30      # speed approaching the moon
fuel = 1500     # how much fuel is left
altitude = 1000 # altitude above moon
gravity = 1.622 # acceleration due to gravity
burn = 0        # initial rate of burning fuel in retrorockets

# while LLM is above the moon's surface,
# calculate flight data and take input from pilot
while altitude > 0:
    # calculate how long until LLM will impact moon at current speed (impact)
    if speed <= 0:
        impact = 1000
    else:
        impact = altitude / speed
    # display flight data
    print("Altitude={:8.3f} Speed={:6.3f} Fuel={:8.3f} Impact={:6.3f} Previous burn={:6.3f}".format(altitude,speed,fuel,impact,burn))
    # take input from pilot
    burn = float(input("Enter fuel to burn (0-50)?"))
    # ensure rate of fuel burning is within rocket's capability and doesn't exceed remaining fuel
    if burn < 0:
        burn = 0
    if burn > 50:
        burn = 50
    if burn > fuel:
        burn = fuel
    #calculate new flight data
    altitude -= speed
    speed += gravity - burn/10
    fuel -= burn
# loop has ended so we must have hit moon's surface
# display final flight data and assess whether it was a crash or a good landing
print("Altitude={:8.3f} Speed={:6.3f} Fuel={:8.3f} Last burn={:6.3f}".format(altitude,speed,fuel,burn))
if altitude <- 5 or speed > 5:
    print("You have crashed")
else:
    print("You have landed")