Python文本游戏的麻烦

时间:2012-12-15 23:29:10

标签: python

所以,这可能会,也可能不会变得复杂。希望不是。 无论如何,我在业余时间一直在写一个相当雄心勃勃的Python文本游戏,只是为了看看我是否能完成它。我意识到那里有大量的交互式小说引擎,解析器等,但我是从头开始做的。它是我学习的方式 - 我想是很难的方式。

所以这就是崩溃的原因:

  • 你在engine.py模块中有main()函数,几乎可以抓住一个房间对象&显示房间描述。然后它等待用户输入并将其发送给解析器。
  • parser.py模块中的解析器运行用户输入并构造一个Sentence对象(由动词和对象组成 - 可以是名词或方向)。 Sentence对象还有一个输出函数,它从command.py模块中调用xxxCommand类。
  • 示例:您输入“go north”&解析器接受它作为一个合适的句子。因此解析器输出函数将搜索GoCommand类。

现在,我遇到了麻烦。在我继续之前,为了清楚起见,我会粘贴我的引擎和放大器。句子类:

class Engine(object):
    def __init__(self, start_room):
        self.L = lexi.Lexicon() #Imported earlier
        self.P = parser.Parser() #Imported earlier
        self.room = start_room

    def main(self):
        while True:
            self.room.describe() #Describes the current room.

            # Ask for user prompt
            input = raw_input(self.room.prompt)
            cmd = input.lower()

            # Scans user input & creates tokens from Lexicon table
            # For example: [('verb', 'go'), ('direction', 'north')]
            tokenizer = self.L.scan(cmd)

            # Runs through tokens and creates a sentence object
            # With noun & object attributes
            parsed_sentence = self.P.parse_sentence(tokenizer)

            # See below
            parsed_sentence.output(self.room)


class Sentence(object):

    def __init__(self, verb, noun):
        self.verb = verb[1]
        self.obj = noun[1]

    # There's a command module with different xxxCommand classes with an execute method
    # as seen on last line. So pretend the command module has already been imported.
    def output(self, current_room):
        verb = self.verb.capitalize()
        obj = self.obj
        command = getattr(commands, '%sCommand' % verb)(obj)
        command.execute(current_room)   

好的,在那个冗长的设置之后,我有这样的GoCommand类:

# Subclassed from Command parent class. Has one method called execute. Does nothing else.
class GoCommand(Command):
    def __init__(self, direction):
        self.direction = direction

    def execute(self, current_room):
        # 'E' is the instantiation of the Engine class, declared within engine.py
        from engine import E

        # self.direction is 'north' in our example
        # current_room.map is a dict within any Room class named 'map'.
        # For example: Intro.map = {'north': char_intro }
        if self.direction in current_room.map:
            print "You head %s\n" % self.direction # Pretty explanatory

            # HERE'S WHERE I HAVE TROUBLE
            E.room = current_room.map[self.direction]
        else:
            print "You can't go that way."

所以我希望实现的是当循环结束时,E.room将等于一个名为char_intro的房间类,当循环再次运行时,它会显示char_intro的描述,基本上重新开始。

这不是最新情况。它只停留在第一个房间。虽然正在运行GoCommand.execute(),但是E.room不会改变。谁知道为什么?

亲爱的上帝,我知道这很长但我希望有人知道我在说什么&可以帮助我。我应该如何解决这个问题,以便当用户说去北方和北方时有一个为North设置的路径,它会改变房间类别吗?

2 个答案:

答案 0 :(得分:0)

要回答我自己的问题,Engine.main()中的循环就像它应该的那样工作,但我从while语句中取出了self.room.describe():

def main(self):
    self.room.describe() #Describes the current room.
    while True:
        # Ask for user prompt
        input = raw_input(self.room.prompt)
        cmd = input.lower()
        ...etc, etc, etc...

然后我将GoCommand更改为:

class GoCommand(Command):
def __init__(self, direction):
    self.direction = direction

def execute(self):
    # 'E' is the instantiation of the Engine class, declared within engine.py
    from engine import E

    # self.direction is 'north' in our example
    if self.direction in E.room.map.keys():
        print "You head %s\n" % self.direction # Pretty explanatory

        E.room = E.room.map[self.direction]
        print E.room.describe()
    else:
        print "You can't go that way."

一切都按原样运作。

答案 1 :(得分:0)

因此看起来游戏状态(当前房间,库存)保留在引擎上。仅仅为了比较,查看我在http://www.ptmcg.com/geo/python/confs/adventureEngine.py.txt上作为命令解析练习编写的文本冒险游戏。在该代码中,我将当前房间和库存保留在Player实例上。主游戏循环看起来像:

parser = Parser()
p = Player("Joe")
p.moveTo( startRoom )
while not p.gameOver:
    cmdstr = raw_input(">> ")
    cmd = parser.parseCmd(cmdstr)
    if cmd is not None:
        cmd.command( p )

parseCmd解析输入字符串,如果有效,则返回一个实现command(p)的Command对象,其中p是Player。通过玩家,该命令可以访问当前房间,当前库存以及任何特殊玩家状态或技能(例如,具有高视力的玩家在进入特定房间时可能具有更好的检测陷阱的几率)。这也使得使用模拟播放器测试命令变得更容易,而不必在引擎本身中模拟任何全局变量或属性。

相关问题