HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Fallout-style homework game

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
homeworkstylegamefallout

Problem

I've been going through LPHW (learn Python the hard way) lessons and I am now at exercise No36 where I have to create a similar game.

Could you please review it and point out beginner mistakes?

```
from sys import exit

inventory = []
ground = ['Bones', "Commander's Key", 'Security Code', 'Shipment Report']

turrets_active = True
rats_hungry = True
hatch_active = True

def check_inventory(inv):
print
print ">The contents of your inventory are:"
if len(inv) > 0:
for counter, content in enumerate(inv):
# This will look like " 0 . Bones " and then " 1 . Security Code " etc
print ">", counter, ".", content
else:
print
print ">Your inventory is empty"

def report_in_inventory():
if 'Shipment Report' in inventory:
print
print "You map the coordinates from the report to your PIP-BOY"
print "Fort Everlast awaits!"
print "CONGRATULATIONS! YOU COMPLETED THE GAME!"
else:
print
print "You wander the desert for the rest the day..."
exit("But deathclaws get you near Broken Hills...")

def take_item(item):
if item in ground:
inventory.append(item)
print
print ">", item, "taken."
ground.remove(item)
else:
print
print ">You check same spots all over again"
print ">but there is nothing to be found"
print

def surroundings_text():
print """
You find yourself in a valley surrounded by the mountains.
You are in a field of the old pre-war satellite dishes
that glare at you with their eyeless faces.
In front of you is an entrance to the Underground Control Complex
that was used to operate the satellite array.
By looks of it the door is guarded by automated Gatling turrets
that will tear you to shreds.
On your right you see a small passage between the mountains
On your left there is an old maintenance hatch surrounded by a fence.
"""
surround

Solution

I would be inclined to reduce some of the duplication using dictionaries and functions, if not classes.

For example, you repeatedly take user input from defined choices, which could all be done by:

def get_input(choices):
    for choice in sorted(choices):
        print("{0}. {1}".format(choice, choices[choice]))
    while True:
        try:
            ui = int(raw_input("Choose an action: "))
        except ValueError:
            print("Please enter a number.")
        else:
            if ui in choices:
                return ui
            print("Not a valid action.")


You can then use this function as:

action = get_input({1: "See if you can find something useful on the skeleton...",
                    2: "Go back.",
                    3: "Check your inventory."})


And guarantee a valid choice in the response. Each set of choices is now defined by a simple dictionary and the validation is handled in one place.

You could also hold the definitions of what to do for each choice in a dictionary, rather than the if: elif: blocks, although you will need to think about how to represent your choices' inventory items needed or global state (e.g. turrets active).

Similarly, you can handle moving around your world by having each choice return the next room to go to, then store all room functions in a dictionary:

rooms = {"tower": enter_tower, "bunker": enter_bunker, ...}


You could then finish by returning None, and have an overall game loop:

room = "tower" # first room 
while room is not None: # game loop
    room = rooms[room]() # call function and get next room
print("Game over.") # end of the game


This avoids your current recursive calling.

Finally, the global is a bad sign. Instead, you could have a World object or dictionary that holds this state:

world = {"rats hungry": True, "turrets active": False,
         "ground" ["bones", "security code", ...], 
         "inventory": [], ...}


and pass it around explicitly:

room = rooms[room](world)

Code Snippets

def get_input(choices):
    for choice in sorted(choices):
        print("{0}. {1}".format(choice, choices[choice]))
    while True:
        try:
            ui = int(raw_input("Choose an action: "))
        except ValueError:
            print("Please enter a number.")
        else:
            if ui in choices:
                return ui
            print("Not a valid action.")
action = get_input({1: "See if you can find something useful on the skeleton...",
                    2: "Go back.",
                    3: "Check your inventory."})
rooms = {"tower": enter_tower, "bunker": enter_bunker, ...}
room = "tower" # first room 
while room is not None: # game loop
    room = rooms[room]() # call function and get next room
print("Game over.") # end of the game
world = {"rats hungry": True, "turrets active": False,
         "ground" ["bones", "security code", ...], 
         "inventory": [], ...}

Context

StackExchange Code Review Q#43450, answer score: 4

Revisions (0)

No revisions yet.