简体   繁体   中英

How to have a versatile function call that can call different functions in Python?

I'm trying to make a text-based game in Python, however, code could get out of hand pretty quickly if I can't do one thing on one line.

First, the source code:

from sys import exit

prompt = "> "
inventory = []

def menu():
    while True:
        print "Enter \"start game\" to start playing."
        print "Enter \"password\" to skip to the level you want."
        print "Enter \"exit\" to exit the game."
        choice = raw_input(prompt)
        if choice == "start game":
            shell()
        elif choice == "password":
            password()
        elif choice == "exit":
            exit(0)
        else:
            print "Input invalid. Try again."

def password():
    print "Enter a password."
    password = raw_input(prompt)
    if password == "go back":
        print "Going to menu..."
    else:
        print "Wrong password. You are trying to cheat by (pointlessly) guess passwords."
        dead("cheating")

def shell(location="default", item ="nothing"):
    if location == "default" and item == "nothing":
        print "Starting game..."
        # starter_room (disabled until room is actually made)
    elif location != "default" and item != "nothing":
        print "You picked up %s." % item
        inventory.append(item)
        location()
    elif location != "default" and item == "nothing":
        print "You enter the room."
        location()
    else:
        print "Error: Closing game."

def location():
    print "Nothing to see here."
    # Placeholder location so the script won't spout errors.

def dead(reason):
    print "You died of %s." % reason
    exit(0)

print "Welcome."
menu()

First, an explanation on how my game basically works. The game has a 'shell' (where input is done) which receives information from and sends information to the different 'rooms' in the game, and it stores the inventory. It can receive two arguments, the location and an eventual item to be added to the inventory. However, line 40-42 (the first elif block in 'shell') and line 43-45 (the last elif block in 'shell') are supposed to go back to whatever location the location was (line 42 and 45, to be exact). I've tried "%s() % location" but that doesn't work, it seems to only work when printing things or something.

Is there any way to do this? If not, even writing an engine for this game would be a nightmare. Or I'd have to make an entirely different engine, which I think would be a way better approach in such a case.

Sorry if I made any mistakes, first question/post ever.

elif location != "default" and item != "nothing":
    print "You picked up %s." % item
    inventory.append(item)
    location()
elif location != "default" and item == "nothing":
    print "You enter the room."
    location()

I guess you want to call a function having its name. For that you need a reference to the module or class inside which it was defined:

module = some_module # where the function is defined
function = getattr(module, location) # get the reference to the function
function() # call the function

If the function is defined in the current module:

function = globals()[location]
function() # call the function

If I correctly understand what you want is something like this : player will enter a location name and you want to call the related method. "%s"()%location will not work, a string (that is what is "%s" is not callable).

Let's try an OOP way :

class Maze:
   def __init__(self):
      # do what you need to initialize your maze

   def bathroom(self):
      #go to the bathroom

   def kitchen(self):
      # go to the kitchen

   def shell(self, location="", item=""):
      if location == "" and item == "":
         print "Starting game..."
         # starter_room (disabled until room is actually made)
      elif location and item:
         print "You picked up %s." % item
         inventory.append(item)
         getattr(self, location)()
      elif location and item == "":
         print "You enter the room."
         getattr(self, location)()
      else:
         print "Error: Closing game."

maze = Maze()
while True:   # or whatever you want as stop condition
   location = raw_input("enter your location :")
   item = raw_input("enter your location :")
   maze.shell(location=location, item=item)

I think you can use the getattr() method.

Example : You want to call method "helloword()" from module "test", you would then do :

methodYouWantToCall = getattr(test, "helloworld")
caller = methodYouWantToCall()

Hope it gives you a clue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM