函数运行后返回代码

时间:2012-09-12 01:41:03

标签: python text-based

我正在制作一个基于文本的游戏,需要一个可以在任何文本条目中提取的应用程序范围的命令行。我的计划是让命令包含在一个模块中,并执行command(),然后允许用户输入一个命令(或获取一个列表)然后运行(包含在同一个模块中)。这不起作用,因为我需要一种方法来返回用户所在的位置。无论如何返回到用户进入命令模式之前的位置,还是有更好的方法来做到这一点?

这是我的想法:

import commands

def something():
    print "a question"

    action = raw_input("> ")

    if action == "command":
        commands.commands()
    elif "something else" in action:
        do something
    else:
        error.error(1)
        something()

然后转到commands.py:

def commands():
    print "Enter a command, help for a list, blah blah blah."

    command = raw_input("$ ")

    if command == "bag":
        bag()
    elif command == "other":
        other()

def bag():
    print "Action listing things in bag"

问题是返回用户离开的地方。

2 个答案:

答案 0 :(得分:2)

你需要的是一个主要的游戏循环:

while game.is_running:
    command = get_user_input()
    user_do(command)
    update_world()

只要whilegame.is_running,这将在True循环内重复三行代码。首先,您获得用户输入。接下来,你采取行动。最后,您可以执行游戏所需的任何其他更新,例如移动或产生怪物。此时,它会循环返回并要求用户输入另一个命令。

更新:这是一个有效的例子:

# In commands.py:
def bag():
    print 'bag'

def other():
    print 'other'

def unrecognized():
    print 'unknown command'

# In main.py:
import commands

def user_input():
    print 'a question'
    return raw_input('>')

def user_do(command):
    # get the matching command out of commands, or pass back
    # the unrecognized function if it's not found
    action = getattr(commands, command, commands.unrecognized)
    action()

is_running = True
while is_running:
    command = user_input()
    if command == 'quit':
        is_running = False
    else:
        user_do(command)

在这个例子中,我已经作弊,并且依赖于用户输入命令与要调用的函数的名称相同。在user_do中,getattr调用将用户输入的字符串与command模块的内容进行比较,返回相同名称的函数(如果存在)或回退函数{{ 1}}如果没有。 unrecognized现在将保留命令功能或action

如果您不希望将用户命令与实际函数本身紧密绑定,则可以使用unrecognized作为分支构造(或 dispatch )而不是很多dict陈述:

if / elif / else

在此示例中,我们不是在# Modified main.py import commands COMMAND_DISPATCH = { 'bag': commands.bag, 'sack': commands.bag, 'other': commands.other, # ... } # ... def user_do(command): action = COMMAND_DISPATCH.get(command, commands.unrecognized) action() 模块中查找函数,而是在commands中查找它们。

还有一点建议:很快你就会想要将用户输入解析为不止一个命令。对于此示例,假设您希望能够接受“command ...”形式的输入。您可以扩展COMMAND_DISPATCH功能来处理这个问题:

user_input

因此,如果您输入'foo bar baz',这将返回元组def user_input(): print 'a question' user_input = raw_input('>').split(' ') command = user_input[0] arguments = user_input[1:] return command, arguments 。接下来我们更新主循环来处理参数。

('foo', ['bar', 'baz'])

然后确保我们将它们传递给命令:

while is_running:
    # use tuple unpacking to split into command, argument pairs
    command, arguments = user_input()
    if command == 'quit':
        is_running = False
    else:
        user_do(command, arguments)

最后,我们修改接受和处理参数的命令:

def user_do(command, arguments):
    action = COMMAND_DISPATCH.get(command, commands.unrecognized)
    action(arguments)

对于文字冒险,你需要一个更实质的解析器,它可以处理def bag(arguments): for argument in arguments: print 'bagged ', argument command object,甚至可能command object preposition subject

答案 1 :(得分:0)

你应该研究“python有限状态机”。它几乎就是你想要的。

  

什么是状态机?

     

对状态机的过于准确的描述是它是一个   有向图,由一组节点和一组相应的组成   过渡功能机器通过响应系列“运行”   事件。每个事件都在转换函数的域中   属于“当前”节点,其中函数的范围是a   节点的子集。该函数返回“下一个”(也许是   相同的)节点。这些节点中的至少一个必须是最终状态。当一个   达到最终状态,机器停止。

     

何时使用状态机...

     
      
  1. 从初始状态开始。
  2.   
  3. 阅读一行输入。
  4.   
  5. 根据输入和当前状态,转换为新状态或根据当前状态处理该行。
  6.   

类似于@MatthewTrevor在他的回答中建议的,你将有一个主循环,并将“状态”上下文传递给第一个入口点调用(startintro或其他)。该调用可以改变状态上下文以指向其他内容。当控制再次返回主循环并检查状态时,它将运行新状态。