Text game: How to store commands in a class - python

I am making a text game (various smaller text games until I am absolutely comfortable.), and there will be a lot of commands. So for example:
If the player is in the "Credits" screen. And if there is one central command, for example, "help". How would I have the command "help" list all of the available commands?
What I am asking is, how would I store all of the custom commands in a class, then call them? Or is it even possible?

The module cmd is often overlooked but sounds like just what you might be needing. As they say, the batteries are included.

Firstly, please use the search function, or at least Google. Do not expect help if you haven't demonstrated you've done your fair share of researching.
That said, here's an example to get you started. You might write a function to accept input from the keyboard and use conditional statements to output the correct information:
class MyClass():
def menu(self):
strcmd = raw_input('Enter your input:')
if strcmd == "help":
self.help_func()
elif strcmd == "exit":
sys.exit(0);
else:
print("Unknown command")
def help_func(self):
print("Type 'help' for help.")
print("Type 'exit' to quit the application.")
# ...
If you want to get fancy, you can store function pointers in a dictionary and avoid conditionals altogether:
class MyClass():
def __init__(self):
self.cmds = {"help": help_func, "info": info_func}
def menu(self):
strcmd = raw_input('Enter your input:')
if strcmd in self.cmds:
self.cmds[strcmd]() # can even add extra parameters if you wish
else:
print("Unknown command")
def help_func(self):
print("Type 'help' for help.")
print("Type 'exit' to quit the application.")
def info_func(self):
print("info_func!")
A text based menu is a no-brainer for those with a general understanding of Python. You will have to figure out how to properly implement input and control-flow on your own. This is one of the top results on Google:
http://www.cyberciti.biz/faq/python-raw_input-examples/

Probably the best first thing to remember is that functions are first-class objects in python.
So you can learn how to use a dict to map a string (help topic) to a function (which presumably somehow displays what you want).
available_commands = {"Credits": [ helpcmd1, helpcmd2, ...],
# ... other screens and their command help functions
}
if current_screen in available_commands.keys ():
for command in available_commands [current_screen]:
command ()
else:
displayNoHelpFor (current_screen)

well you could create methods in the class for each command
for example:
class Credits():
def __init(self):
print "for command 1 press 1:"
print "for command 2 press 2:"
print "for command 3 press 3:"
print "for command 4 press 4:"
choice = raw_input("")
if choice == "1":
self.command1()
elif choice == "2":
self.command2()
elif choice == "3":
self.command3()
else:
self.command4()
def command1(self):
#do stuff
def command2(self):
#do stuff
def command3(self):
#do stuff
def command4(self):
#do stuff
then each choice will do a differentnop method and each method will do a command
I dont know if this is exactly what you want bu i hope this helps

Related

calling methods as command line arguments in the cmd

I have been dealing with this question for quite a time, so I decided to ask directly here for explanations/ what and where to read from.
From university we are doing a project where we use python and the cmd class to call the methods as arguments to the command line.
The lecturer has provided us with some example on how it could work and so on. However he didn't fully explained some details that I still miss about the arguments and how in general you can call the function as an argument in the command line prompt.
Here I will provide a shortened version of the code which he has written, as the general methods are the only thing included here in order to explain the situation in simpler manner.
import cmd
class Multiplayer(cmd.Cmd):
def __init__(self):
"""Init the object."""
super().__init__()
self.dice = dice.Dice() # dice object to call the roll() later
self.player1 = player.Player(1) # score = 0, index = 1
self.player2 = player.Player(2) # score = 0, index = 2
self.playerTurn = player.Player(1) # score = 0, index = 1
def do_start(self, _): #here is the part i dont fully understand
"""start a new game"""
print("You have started a new game.\n")
print("""
Welcome to the game. Type help or ? to list commands.\n
To set both players names, type: 'set_names' \n""")
self.__init__() #calling constructor so the new game starts
def do_exit(self, _):
"""Leave the game."""
print("press 'l' to leave game, press 's' to start a new one")
comand = input()
if comand == 'l':
return True
elif comand == 's':
self.do_start(self)
else:
print("unknow syntax")
self.do_exit(self)
def do_EOF(self, arg):
"""Leave the game."""
return self.do_exit(arg)
When I type "start" this function is called byt the cmd and executed. In general does the "do_" part infront of the function name has to do something with the command line itself? Why do we need this second argument (the underscore dash)? And what is it for?
(I have tried to remove it but then i typed in "-help", couldn't see the command.) I have checked other's classmates codes and they have used other words instead of underscore dash.
If you provide me with some sources/explanations so I can get a better grasp of this concept, it would be really appreciated.
Thanks in advance for the replies. Cheers!

Inputting a function into an imported module

I am attempting to create a game menu that I can then use in games to skip having to make a new menu each time. However, currently it just preforms the gameMain() function instead of doing the gameMenu() first, and then trying to select the game with "g" or "G" does nothing but end the program.
What I'm asking is if it's possible to have a variable in a module that's a function in the code that's importing it.
Here is the code for the menu, which is called textbasedadventures.py:
def gameMenu(game,your_choice="Please Enter how you'd like the game described"):
menu_options = ""
while not(menu_options == "G" or menu_options == "g":
title()
print()
print("\t\t",your_choice,"\n\n")
print('G start game')
menu_options = input("\t\tChoice: ")
if menu_options == "G" or menu_options == "g":
game
input(pause)
and this is the code for the game:
import sys
sys.path.append("\MyOwnProjects")
import textbasedadventures as t
def veryStart():
answer = ""
while not(answer == "1" or answer == "2" or answer == "3"):
print("\tYou are awoken by the blaring of your alarm clock.How did you sleep last night?")
print("\n\t1 Very well\n\n\t2 Well\n\n\t3 Not good\n\n\t4 atrociously")
answer = input("You slept ")
if answer == "1":
print("one option")
elif answer == "2":
print("\t")
elif answer == "3":
pass
elif answer == "4":
print("another option")
else:
print("\t",answer,"is not a valid entry, please try again")
def gameMain():
veryStart()
t.gameMenu(gameMain(),"please work")
If anyone can tell me how to do this, or if this is even possible, I'd be very grateful.
Your remaining problem is getting used to when you're calling a function, and when you're referring to the function as an object.
Since you didn't get any errors when you imported your textbasedadventures (which I shortened to tba to avoid typos), I assume that you've handled that properly: the file is named textbasedadventures.py and is in the local directory.
I had to remove the input(pause) line, since you didn't define pause, and it's there for a different shell from the one I'm using. I also had to remove title(), since that's no longer in your code.
When you pass the main program's main-game function, you have to pass it as a function object. You did this:
t.gameMenu(gameMain(),"please work")
This calls gameMain (because of the parentheses), grabs the return value, and passes that to t.gameMenu. Since there isn't any such return value, your remote menu routien receives only the value None.
Simply remove the parentheses:
t.gameMenu(gameMain,"please work")
This takes the entire gameMain function (well, a reference to it) and passes that to your remote function, where ...
Instead of calling the passed-in game module, you simply listed its value. Python thinks, "okay, cool, I have to evaluate this expression. Gee, a reference to an object -- that's easy. The value is simply the reference itself. I'm not even supposed to do anything with it. Done."
Simply putting a value on a line is legal Python, but boring: the value is displayed if you're in an interactive shell, but is otherwise ignored. Therefore, you never got any response from that line.
Instead, now you call it: this is where you put the parentheses you took off the other end of the call:
game()
I made those changes, and here's the result:
enter G to start game
Choice: g
You are awoken by the blaring of your alarm clock.How did you sleep last night?
1 Very well
2 Well
3 Not good
4 atrociously
You slept

Call functions in Python [duplicate]

I was trying to make a "game" in Python where the user inputs a command. However, I do not know whether you can take that input to be a function name. This is my current effort:
def move():
print("Test.")
if __name__ == "__main__":
input("Press enter to begin.")
currentEnvironment = getNewEnvironment(environments)
currentTimeOfDay = getTime(timeTicks, timeOfDay)
print("You are standing in the {0}. It is {1}.".format(currentEnvironment, currentTimeOfDay))
command = input("> ")
command()
Here, the input was move, as I wanted to try and call that function (as a potential end user might). However, I get the following error:
Traceback (most recent call last):
File "D:\Text Adventure.py", line 64, in <module>
command()
TypeError: 'str' object is not callable
I was wondering if there was any way that I could allow a user to 'move' in the game, which the program achieves by calling the "move" function.
It looks like you're using python3.x where input returns a string. To recover the python2.x behavior, you need eval(input()). However, you shouldn't do this. It's likely to lead to a bad day.
A better idea is to put the functions into a dictionary --
def move():
#...
def jump():
#...
function_dict = {'move':move, 'jump':jump }
and then:
func = input('>') #raw_input on python2.x
function_dict[func]()
The following code works for me on python3.2.
def move():
print("Test.")
func_dict = {'move':move}
if __name__ == "__main__":
input("Press enter to begin.")
currentEnvironment = "room" #getNewEnvironment(environments)
currentTimeOfDay = "1 A.M." #getTime(timeTicks, timeOfDay)
print("You are standing in the {0}. It is {1}.".format(currentEnvironment, currentTimeOfDay))
command = input("> ")
func_dict[command]()
You can access functions by name using:
function = globals()[function_name]
if the function is in the current module, or
function = getattr(other_module, function_name)
You should also take measures to disallow calling arbitrary functions, for example, prefixing:
def cmd_move() # ok to call this
def cmd_jump() # ok to call this
def internal_func....
cmd = raw_input('>') # e.g. "move"
fun = globals()['cmd_' + cmd]
fun()
Have a look at the cmd module. See this.
It is normally used for shell style comman dlanguages, but it can also be used to create simple text style adventure games.
You can create commands by creating a new method on the Cmd subclass.
E.g.
def do_move(self, args):
if self.next_room.has_snake():
print "The next room contains a poisonous snake. It bites you and you die."
else:
print "The room is empty"
It's usually better to re-use code as Hans suggests, but if you wanted to input commands and run them manually, it would be MUCH safer to have a dictionary of valid commands than to directly execute user-provided input.
cmd = { 'move': move, 'jump': jump, 'look': look }

Python text adventure - how to create HINT and SAVE in every prompt

So, finally I'm getting to the end of LPTHW, and I'm creating my own text adventure type of game.
I want to incorporate a save function to the game (probably by using file write). Also, the game can give you hints based on your location in the game. What I basically need is following:
There will be lots of prompts for user input (raw_input) in while loops. I want to be able to type SAVE or HINT any time to trigger a function. How do I do this so I don't have to create the same conditional every time? (for example elif action == "HINT": print "...")
Is there a way to create some global expressions so that every time they're typed in the prompt, I can act on them? I will create a module with a dictionary that will reference a certain hint when the player is present in a certain location. I just want to avoid putting the same conditionals all over the place.
If you separate the input into a function, you can pass a hint and access save easily:
def user_input(prompt, hint):
while True:
ui = raw_input(prompt)
if ui.lower() == "hint":
print hint
elif ui.lower() == "save":
save()
else:
return ui
You could also add checking here that the user stays within specific choices (an additional argument), deal with any errors and only ever return valid input.
you should probably use a dictionary
def do_save(*args,**kwargs):
print "SAVE!"
def do_hint(*args,**kwargs):
print "HINT!"
def do_quit(*args,**kwargs):
print "OK EXIT!"
global_actions = {'SAVE':do_save,
'HINT':do_hint,
'QUIT':do_quit}
def go_north(*args,**kwargs):
print "You Go North"
def go_east(*args,**kwargs):
print "you go east"
def make_choice(prompt="ENTER COMMAND:",actions={},context_info={}):
choice = raw_input(prompt)
fn = actions.get(choice.upper(),lambda *a,**kw:sys.stdout.write("UNKOWN CHOICE!"))
return fn(some_context=context_info)
local_actions = {"NORTH":go_north,"EAST":go_east}
player_actions = dict(global_actions.items() + local_actions.items())
print "From Here You Can Go [North] or [East]"
result = make_choice(actions=player_actions,
context_info={"location":"narnia","player_level":5})
I don't know about the save feature but for hint you could just have;
If raw_input == hint:
print "whatever you want here"
Or if you need the hint to be different depending on your position you could have a variable for what the hint for that room is and have it update each time you enter a new room then have:
if raw_input == "hint":
print hintvariable
If this doesn't work then sorry, I'm new.

Using user input to call functions

I was trying to make a "game" in Python where the user inputs a command. However, I do not know whether you can take that input to be a function name. This is my current effort:
def move():
print("Test.")
if __name__ == "__main__":
input("Press enter to begin.")
currentEnvironment = getNewEnvironment(environments)
currentTimeOfDay = getTime(timeTicks, timeOfDay)
print("You are standing in the {0}. It is {1}.".format(currentEnvironment, currentTimeOfDay))
command = input("> ")
command()
Here, the input was move, as I wanted to try and call that function (as a potential end user might). However, I get the following error:
Traceback (most recent call last):
File "D:\Text Adventure.py", line 64, in <module>
command()
TypeError: 'str' object is not callable
I was wondering if there was any way that I could allow a user to 'move' in the game, which the program achieves by calling the "move" function.
It looks like you're using python3.x where input returns a string. To recover the python2.x behavior, you need eval(input()). However, you shouldn't do this. It's likely to lead to a bad day.
A better idea is to put the functions into a dictionary --
def move():
#...
def jump():
#...
function_dict = {'move':move, 'jump':jump }
and then:
func = input('>') #raw_input on python2.x
function_dict[func]()
The following code works for me on python3.2.
def move():
print("Test.")
func_dict = {'move':move}
if __name__ == "__main__":
input("Press enter to begin.")
currentEnvironment = "room" #getNewEnvironment(environments)
currentTimeOfDay = "1 A.M." #getTime(timeTicks, timeOfDay)
print("You are standing in the {0}. It is {1}.".format(currentEnvironment, currentTimeOfDay))
command = input("> ")
func_dict[command]()
You can access functions by name using:
function = globals()[function_name]
if the function is in the current module, or
function = getattr(other_module, function_name)
You should also take measures to disallow calling arbitrary functions, for example, prefixing:
def cmd_move() # ok to call this
def cmd_jump() # ok to call this
def internal_func....
cmd = raw_input('>') # e.g. "move"
fun = globals()['cmd_' + cmd]
fun()
Have a look at the cmd module. See this.
It is normally used for shell style comman dlanguages, but it can also be used to create simple text style adventure games.
You can create commands by creating a new method on the Cmd subclass.
E.g.
def do_move(self, args):
if self.next_room.has_snake():
print "The next room contains a poisonous snake. It bites you and you die."
else:
print "The room is empty"
It's usually better to re-use code as Hans suggests, but if you wanted to input commands and run them manually, it would be MUCH safer to have a dictionary of valid commands than to directly execute user-provided input.
cmd = { 'move': move, 'jump': jump, 'look': look }

Categories