How To Use Commands Again Without Copy And Pasting Them?
Solution 1:
On a more fundamental level, the object-oriented paradigm elegantly solves the problem of repetitive code like this:
global gold = 0defcave():
print"You are in a cave."print"You have %i gold." % gold
direction = input()
if direction = 'N':
stream()
elif direction == 'S':
house()
elif direction == 'W':
mountain()
elif direction == 'directions':
print"You can go North, West, or South."else:
print"You cannot go there."defstream():
print"A small stream flows out of the building and down a gully."print"You have %i gold." % gold
direction = input()
if direction == 'N':
tree()
elif direction == 'S':
cave()
elif direction == 'directions':
print"You can go North or South."else:
print"You cannot go there."defmain():
cave()
by turning it into something like this:
classLocation:
map = { 'cave': {
'description': 'You are in a cave.',
'directions': { 'N': 'stream', 'S': 'house', 'W': 'mountain' } },
'stream': {
'description':
'A small stream flows out the building and down a gully.',
'directions': { 'N': 'tree', 'S': 'cave' } } #...
}
def__init__ (self):
self.location = 'cave'defenter (self, direction):
self.location = self.map[self.location]["directions"][direction]
print self.map[self.location]["description"]
defdirections(self):
return self.map[self.location]["directions"].keys()
defreadable(self, dirs):
readable = { 'S': 'South', 'N': 'North', 'W': 'West', 'E': 'East' }
return [readable[d] for d in dirs]
classInventory:
def__init__ (self):
self.inventory = { 'gold': 0 }
defquery (self):
print"You have %i gold." % self.inventory['gold']
defmain:
loc = Location()
inv = Inventory()
whileTrue:
directions = loc.directions()
action = raw_input()
if action in directions:
loc.enter(action)
inv.query()
elif action == 'directions':
where = loc.readable(directions)
print"You can go " + ", ".join(where[:-1])\
+ ", or " + where[-1]
else:
print"You cannot go there."
You will notice that the more modular code is also easier to extend. For example, the inventory can now hold more things than gold, and it's easy to add new commands to query for weapons, potions, etc. Furthermore, it somewhat separates the code from the data, making it less cumbersome and error-prone to add new locations and actions.
Next up, define class Object
with subclasses for animate objects, objects you can pick up, immobile objects, etc; and populate the locations with instances of these. Different subclasses can have different interactions defined, and inherit from more basic superclasses which implement fundamentals like take
, drop
, kill
, etc.
What to map into objects is a broad topic, but a few simple guidelines would be to isolate and encapsulate unrelated code into their own classes, and make them as decoupled as possible (code implementing "location" should not need to know pretty much anything about code in "inventory", and vice versa).
Solution 2:
Your code for this has some serious structural problems. If I understand correctly, you're trying to accept repeated commands and execute some code to make them function the way you intend.
The problem is that your function to run the game is recursive, so every time you execute a command other than 1, 2, 3, or 4, you're calling your function again without returning from the first one. Eventually, if you enter enough commands, you'll get an error saying that you're recursing too deeply and the game will error out.
What you want is something more like this:
def prompt():
x = input('Type a command: ')
return x
def ProcessAction(command):
ifcommand == '1':
print()
elifcommand == '2':
print()
elifcommand == '3':
print()
elifcommand == '4':
print()
elifcommand == 'geld': #Actions start hereprint('\n\tYou have ' + str(gold) + ' euro. RICH BOY BRO!.\n')
print()
elifcommand == 'inv':
if not inv:
print("\n\tYou don't have any items..\n")
else:
print('\n\t' + str(inv) + '\n')
#Actions end here
curr_command = None
while curr_command not in ("1", "2", "3", "4"):
curr_command = prompt()
ProcessAction(curr_command)
What this will do is keep asking for new commands and processing them until one of the commands that exits the game is entered.
Edit: From your comment below, it sounds like you're trying to figure out how to display gold and inventory every time a command is entered without requiring a special command to do it. If this is what you're after, you can add print statements to the while
loop above to ensure that it's printed before every prompt. In that case, the while loop might look like:
while curr_command notin ("1", "2", "3", "4"):
print('\n\tYou have ' + str(gold) + ' euro. RICH BOY BRO!.\n')
ifnot inv:
print("\n\tYou don't have any items..\n")
else:
print('\n\t' + str(inv) + '\n')
curr_command = prompt()
ProcessAction(curr_command)
Hope that gets closer to what you're after.
Edit 2: Ok, after reading the full code for your game, I think you might want to consider reorganizing the entire thing. Think about what you want the game to be: the player enters a series of commands and each command does two things, it changes the game's state and it prints out a response based on both the current state and the new state.
So, you should think about processing your commands with a loop like I described. Then, fold all those different functions into ONE ProcessAction(command)
function that figures out from the game's state (which you store in variables) what to print out and how to change the state.
If it's a game where you're going room to room, for example, you might keep a global variable room
that defines where you are. Your ProcessAction
function then follows logic that says "If I'm in room A and the character types this thing then print out B and change room to C, and sets gold to 0."
To make this work well, you'll have to step back and think about the overall "story" of your game, how to store the state in various variables, and how to make your ONE ProcessAction
function handle all the possible states and commands that can be issued.
Doing this puts you on the path of developing what's called a "state machine," where you have a simple, general function that looks at a data structure (probably some nested dicts) that you fill up with what each command does when your game is in each state and where to go next, as well as what to print out.
This Wikipedia article describes the concept of a state machine. How you implement it in Python is up to you. I can tell you that if you're careful you should be able to do this without repeating any code. http://en.wikipedia.org/wiki/State_machine
Another edit: Answering a question you placed in the comments below, if you think you have to print out, for example, the value of a player's gold in multiple places, you can do something like this:
defprint_gold(gold_value):
print('\n\tYou have ' + str(gold_value) + ' euro. RICH BOY BRO!.\n')
print()
then use print_gold(gold)
in place of those print statements whenever you need to do that. However, I think you may want to take a step back and think about rewriting the whole thing with some of the thoughts I've offered before you tackle that problem.
Solution 3:
My earlier answer is long and addresses a number of problems in the OP's code, but he's asking about one specific thing, so I thought I'd separate out that answer here.
If you have some code you'd like to repeat multiple times, you might be tempted to copy and paste it around in your code In your case, that would be something like:
print('\n\tYou have ' + str(gold) + ' euro. RICH BOY BRO!.\n')
print()
Wrapping that in a function will allow you to execute that same code anytime you need to do that thing, without copying and pasting. You're already defining functions, so you seem to have the concept down, but this wrapped in a function might look like:
defprint_gold(gold_value):
print('\n\tYou have ' + str(gold_value) + ' euro. RICH BOY BRO!.\n')
print()
With this function defined, anytime you place print_gold(gold)
in your code, it'll pass the value of gold
into that function as the variable gold_value
and print it out as you've specified.
So, if for some reason you had code that looked like this:
print('\n\tYou have ' + str(gold) + ' euro. RICH BOY BRO!.\n')
print()
print('\n\tYou have ' + str(gold) + ' euro. RICH BOY BRO!.\n')
print()
print('\n\tYou have ' + str(gold) + ' euro. RICH BOY BRO!.\n')
print()
you could turn this into:
defprint_gold(gold_value):
print('\n\tYou have ' + str(gold_value) + ' euro. RICH BOY BRO!.\n')
print()
... somewhere elsein your code ...
print_gold(gold)
print_gold(gold)
print_gold(gold)
Those three lines are function calls, which tell Python to execute the function you've defined with def
.
Solution 4:
I am assuming you are currently pasting something into this prompt everytime you want to run your Python program, and your question is about how to avoid that:
The answer to this problem is generally to save your program's code in a whatever.py
file and run that file... either by doubleclick or through the terminal. The exact instructions depend on your operating system etc.
Solution 5:
If I understood correctly the latest edit to your question, then you might want something like:
def get_gold_or_inv(command):
ifcommand == 'geld': #Actions start hereprint('\n\tYou have ' + str(gold) + ' euro. RICH BOY BRO!.\n')
print()
elifcommand == 'inv':
if not inv:
print("\n\tYou don't have any items..\n")
else:
print('\n\t' + str(inv) + '\n')
while True:
command = prompt()
ifcommand == '1':
print()
elifcommand == '2':
print()
elifcommand == '3':
print()
elifcommand == '4':
print()
get_gold_or_inv(command)
Post a Comment for "How To Use Commands Again Without Copy And Pasting Them?"