patternpythonMinor
Making user menus in a text-based game
Viewed 0 times
menususertextgamebasedmaking
Problem
I'm new to Python and programming in general, but I'm making it work. I have this little game I've been working on as a learning exercise and I'm a bit concerned that I'm using far too many
```
# Bizarro house text adventure game
from sys import exit
import time
#error message for an incorrect choice
def error():
print """
Invalid number
Time rewinds to the beginning of your journey.
"""
start()
#Beginning of the game
def start():
print """
You're standing at the entrance to an old spooky mansion.
It's just after midnight.
What would you like to do?
1. Go inside
2. leave
"""
choice = raw_input("> ")
if choice == "1":
entrance()
elif choice == "2":
dead("This could have been an exciting adventure if you weren't too scared,")
else:
print "Wrong answer try again."
start()
def dead(why):
print why, "better luck next time."
exit(0)
# Group of functions for the downstairs area
def entrance():
print """
There is a room on the left,
a room on the right,
and a kitchen in the back.
Also a set of stairs
Which way?
1. Left
2. Right
3. Kitchen
4. Upstairs
"""
choice = raw_input("> ")
if choice == "1":
left_room()
elif choice == "2":
right_room()
elif choice == "3":
kitchen()
elif choice == "4":
stairwell()
else:
error()
def left_room():
print """
The room is dark.
You hear a voice that says:
'I see you, and so does Jesus'
You use your cell phone for light.
You shine the light around the room.
You find a lightswitch.
You also shine the light on a parrot cage.
The parrot repeats his warning.
'I see you and so does Jesus'
What do you do?
1. Turn on light
2. Leave room
"""
choice = raw_input("> ")
if choice == "1":
d
if/else statements for the user menus. Is there perhaps a better way?```
# Bizarro house text adventure game
from sys import exit
import time
#error message for an incorrect choice
def error():
print """
Invalid number
Time rewinds to the beginning of your journey.
"""
start()
#Beginning of the game
def start():
print """
You're standing at the entrance to an old spooky mansion.
It's just after midnight.
What would you like to do?
1. Go inside
2. leave
"""
choice = raw_input("> ")
if choice == "1":
entrance()
elif choice == "2":
dead("This could have been an exciting adventure if you weren't too scared,")
else:
print "Wrong answer try again."
start()
def dead(why):
print why, "better luck next time."
exit(0)
# Group of functions for the downstairs area
def entrance():
print """
There is a room on the left,
a room on the right,
and a kitchen in the back.
Also a set of stairs
Which way?
1. Left
2. Right
3. Kitchen
4. Upstairs
"""
choice = raw_input("> ")
if choice == "1":
left_room()
elif choice == "2":
right_room()
elif choice == "3":
kitchen()
elif choice == "4":
stairwell()
else:
error()
def left_room():
print """
The room is dark.
You hear a voice that says:
'I see you, and so does Jesus'
You use your cell phone for light.
You shine the light around the room.
You find a lightswitch.
You also shine the light on a parrot cage.
The parrot repeats his warning.
'I see you and so does Jesus'
What do you do?
1. Turn on light
2. Leave room
"""
choice = raw_input("> ")
if choice == "1":
d
Solution
Python allows for object oriented programming. Using this would simplify your program immensely. So let's walk through remaking this.
Let's think about what your game consists of. You have locations, options the player can choose from, and actions those options should trigger. In addition, you want to keep track of some state about the player (alive, any items, etc.).
First, we want to define a game state. The state should keep track of our current location, if we are alive, and a map of locations. A few extra functions are added to make it easier later.
Now we want to define a location. Locations have their description and a list of things you can do there. Simple enough, but let's also give them a name, since we want to map their name to them in the State class. We also define a method for getting user input and executing the action if it was good.
Now, what should we put in options? You can see above that I want to be able to get an action from them, and I want to print some text from them, so we define the class like so
Now what about actions themselves? They need to define an execute method that takes a state object. So lets define an action for moving and killing the player.
Now let's create a few locations:
And now we can put it all together:
If you want different actions, you can now create a simple class that defines the execute method. So, let's say you wanted a
This class won't change the state of the game but will print the message given.
A class to change what an option does is also possible
How about an action that does multiple actions? Easy!
```
class MultiAction:
def __init__(self, actions=None):
self.actions = actions
def execute(self, state):
if(self.actions == None): return
for action in self.actions:
Let's think about what your game consists of. You have locations, options the player can choose from, and actions those options should trigger. In addition, you want to keep track of some state about the player (alive, any items, etc.).
First, we want to define a game state. The state should keep track of our current location, if we are alive, and a map of locations. A few extra functions are added to make it easier later.
class State:
def __init__(self, starting_loc):
self.alive = True
self.location = starting_loc
self.locations = {}
def addloc(self, location):
self.locations[location.name] = location
def gotoloc(self, locname):
self.location = self.locations[locname]Now we want to define a location. Locations have their description and a list of things you can do there. Simple enough, but let's also give them a name, since we want to map their name to them in the State class. We also define a method for getting user input and executing the action if it was good.
class Location:
def __init__(self, name, desc, options=None):
self.name = name
self.desc = desc
self.options = options
def start(self):
print self.desc
def print_opts(self):
if(self.options != None):
for i in range(len(self.options)):
print " {0}. {1}".format(i, self.options[i].text)
def get_choice(self, state):
choice = raw_input("> ")
print "You chose \"{0}\"".format(choice)
try:
index = int(choice)
self.options[index].action.execute(state)
return True
except Exception as e:
print(e)
print("Please choose a valid option")
return FalseNow, what should we put in options? You can see above that I want to be able to get an action from them, and I want to print some text from them, so we define the class like so
class Option:
def __init__(self, text, action):
self.text = text
self.action = actionNow what about actions themselves? They need to define an execute method that takes a state object. So lets define an action for moving and killing the player.
class GoToLocation:
def __init__(self, location):
self.loc = location
def execute(self, state):
state.gotoloc(self.loc)
state.location.start()
class KillPlayer:
def __init__(self, message):
self.message = message
def execute(self, state):
state.alive = False
print(self.message)Now let's create a few locations:
start_loc = Location("start",
"You're standing at the entrance to a spooky mansion",
[Option("Go Inside", GoToLocation("entrance")),
Option("Leave", KillPlayer("Scardy Cat"))])
entrance = Location("entrance",
"""You are standing in the entrance hall.
There is a room on the left, a room on the right, and a kitchen in the back.
There is also a set of stairs in front of you.""",
[Option("Left", KillPlayer("The building collapses")),
Option("Right", KillPlayer("The building collapses")),
Option("Kitchen", KillPlayer("The building collapses")),
Option("Upstairs", KillPlayer("The building collapses")),
Option("Outside", GoToLocation("start"))])And now we can put it all together:
if(__name__=="__main__"):
s = State(start_loc)
s.addloc(start_loc)
s.addloc(entrance)
s.location.start()
while(s.alive):
s.location.print_opts()
s.location.get_choice(s)If you want different actions, you can now create a simple class that defines the execute method. So, let's say you wanted a
Message action that doesn't do anything but print it's message.class Message:
def __init__(self, msg):
self.msg = msg
def execute(self, state):
print self.msgThis class won't change the state of the game but will print the message given.
A class to change what an option does is also possible
class OptionMutator:
def __init__(self, location, index, newoption):
self.locname = location
self.index = index
self.newoption = newoption
def execute(self, state):
loc = state.locations[self.locname]
if(self.index = len(loc.options)):
loc.options.append(self.newoption)
else:
loc.options[self.index] = self.newoptionHow about an action that does multiple actions? Easy!
```
class MultiAction:
def __init__(self, actions=None):
self.actions = actions
def execute(self, state):
if(self.actions == None): return
for action in self.actions:
Code Snippets
class State:
def __init__(self, starting_loc):
self.alive = True
self.location = starting_loc
self.locations = {}
def addloc(self, location):
self.locations[location.name] = location
def gotoloc(self, locname):
self.location = self.locations[locname]class Location:
def __init__(self, name, desc, options=None):
self.name = name
self.desc = desc
self.options = options
def start(self):
print self.desc
def print_opts(self):
if(self.options != None):
for i in range(len(self.options)):
print " {0}. {1}".format(i, self.options[i].text)
def get_choice(self, state):
choice = raw_input("> ")
print "You chose \"{0}\"".format(choice)
try:
index = int(choice)
self.options[index].action.execute(state)
return True
except Exception as e:
print(e)
print("Please choose a valid option")
return Falseclass Option:
def __init__(self, text, action):
self.text = text
self.action = actionclass GoToLocation:
def __init__(self, location):
self.loc = location
def execute(self, state):
state.gotoloc(self.loc)
state.location.start()
class KillPlayer:
def __init__(self, message):
self.message = message
def execute(self, state):
state.alive = False
print(self.message)start_loc = Location("start",
"You're standing at the entrance to a spooky mansion",
[Option("Go Inside", GoToLocation("entrance")),
Option("Leave", KillPlayer("Scardy Cat"))])
entrance = Location("entrance",
"""You are standing in the entrance hall.
There is a room on the left, a room on the right, and a kitchen in the back.
There is also a set of stairs in front of you.""",
[Option("Left", KillPlayer("The building collapses")),
Option("Right", KillPlayer("The building collapses")),
Option("Kitchen", KillPlayer("The building collapses")),
Option("Upstairs", KillPlayer("The building collapses")),
Option("Outside", GoToLocation("start"))])Context
StackExchange Code Review Q#65305, answer score: 8
Revisions (0)
No revisions yet.