したがって、これは複雑になる場合とそうでない場合があります。うまくいけば、そうではありません。いずれにせよ、私は暇なときにかなり野心的なPythonテキストゲームを書いていて、それができるかどうかを確認しています。インタラクティブフィクションエンジンやパーサーなどがたくさんあることに気づきましたが、私はそれをゼロからやっています。それは私が学ぶ方法です-難しい方法だと思います。
それで、これがどのように分解するかです:
- engine.pyモジュールにmain()関数があります。この関数は、部屋のオブジェクトを取得して部屋の説明を表示します。次に、ユーザー入力を待機し、パーサーに送信します。
- parser.pyモジュールのパーサーは、ユーザー入力を実行し、Sentenceオブジェクト(動詞とオブジェクトで構成されます-名詞または方向にすることができます)を構築します。Sentenceオブジェクトには、command.pyモジュール内からxxxCommandクラスを呼び出す出力関数もあります。
- 例:「gonorth」と入力すると、パーサーはそれを適切な文として受け入れます。したがって、パーサー出力関数はGoCommandクラスを検索します。
今ここで私は問題を抱えています。続行する前に、わかりやすくするために、Engine&Sentenceクラスを貼り付けます。
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は変更されません。誰もが理由を知っていますか?
親愛なる神様、これは長いことだと思いますが、誰かが私が話していることを知っていて、私を助けてくれることを願っています。ユーザーが北に行くと言ったときに北に設定されたパスがある場合に部屋のクラスを変更するように、これをどのように修正する必要がありますか?