通过学习pythonthhardway,我已经进入了文本冒险游戏,我有一些代码可以理解它们执行的内容,但我不明白如何执行。以下是我将整个代码缩小为一个.py文件:
from sys import exit
from random import randint
class Scene(object):
def enter(self):
print "This isn't configured yet. Subclass and implement enter()"
exit(1)
class CentralCorridor(Scene):
def enter(self):
print "Something."
action = raw_input("> ")
if action == "shoot!":
print "Something something."
return 'death'
class Death(Scene):
dead = [
"You died. That sucks ...",
"You shouldn't have died here...that was dumb.",
"You L00se.",
"Even a cow's moo sounds smarter than you."
]
def enter(self):
print Death.dead[randint(0, len(self.dead)-1)]
exit(1)
class Engine(object):
def __init__(self, scene_map):
self.scene_map = scene_map #sets scene_map from the a_map variable
def play(self):
current_scene = self.scene_map.opening_scene()#sets aMap.opening_scene() and initiates CentralCorridor
last_scene = self.scene_map.next_scene('finished') #for the last win scene Finished()
while current_scene != last_scene:
next_scene_name = current_scene.enter() #if scene's not last, call enter() of current scene to next scene name
current_scene = self.scene_map.next_scene(next_scene_name)#Set current_scene to instance of scene_map with self, next_scene_name as parameters
current_scene.enter()
class Map(object): #initially central_corridor
scenes = {
'central_corridor':CentralCorridor(),
'death':Death(),
}
def __init__(self, start_scene):
self.start_scenes = start_scene #central_corridor
def next_scene(self, scene_name):
val = Map.scenes.get(scene_name) #sets CentralCorridor() to val
return val
def opening_scene(self):
return self.next_scene(self.start_scenes) #returns val from
#next_scene which is
#CentralCorridor()
a_map = Map('central_corridor')
a_game = Engine(a_map)
a_game.play()
在这段代码中,我有一些东西我没有得到(请耐心等待。)
CentralCorridor类下的"return‘death’"如何在Map类的场景中引用字典,并返回death类?当我打字射击!它似乎要遍历Engine类并执行current_scene.enter(),但我还没有在CentralCorridor类的任何地方调用Engine类的play函数。
在Map类的opening_scene函数中返回self.next_scene(self.start_scenes)工作???我知道它的作用,但self.next_scene(self.start_scenes)有点让我困惑。
感谢大家的解释!
我几天前刚刚在书中完成了这个练习,并花了一些时间寻找答案。这个网站真的很好。让我试着解释一下,因为它加强了我的理解。如果我在任何时候都错了,请随时纠正我。
在回答你的问题时,我不妨先解释一下:
a_map = Map('central_corridor')
a_game = Engine(a_map)
a_game.play()
a_map是一个以"中央走廊"为参数的地图。
课堂地图(阅读#comment)
def __init__(self, start_scene):
self.start_scenes = start_scene #start_scene is set to 'central corridor'
def next_scene(self, scene_name):
val = Map.scenes.get(scene_name) #get() narrows the search in the library scenes.
return val #return and pass to next_scene as a method.
def opening_scene(self):
return self.next_scene(self.start_scenes) #return and pass to opening_scene
由于self.start_scene被设置为参数"central roach",opening_scene将通过next_scene中所述的方法在Map类中的场景库中搜索"central round",该方法是get(),一个用于定位库中事物的函数。继续…
a_game = Engine(a_map)
a_game是一个以a_map为参数的引擎,而a_map则以"中央走廊"为参数。因此a_game也将"中央走廊"作为一个参数。逻辑A=B和B=C,因此A=C,并且A_game可以访问类Map和Engine作为继承。你可以在本章之后的《硬着头皮学蟒蛇》一书的下一章中读到这一点。
类内引擎(阅读#comment)
def __init__(self, scene_map):
self.scene_map = scene_map #self.scene_map has set to 'central corridor'
def play(self):
current_scene = self.scene_map.opening_scene() #set current_scene by calling the function opening_scene which was explained in class Map, accessible by a_game
last_scene = self.scene_map.next_scene('finished') #set last_scene by searching scene in class Map.
#I didn't see any 'finish' scene in map. I think you should have added it in scenes.
注意这里您将从enter函数中得到一个返回。
while current_scene != last_scene: #enters the while loop!! This is where the game starts.
next_scene_name = current_scene.enter()
current_scene = self.scene_map.next_scene(next_scene_name)
current_scene.enter()
这里是理解整个游戏过程的关键点:
next_scene_name = current_scene.enter()
现在您进入了函数CentralCorridor(),并进行了选择。因为您的代码不完整,所以在这种情况下,我们假设action=="射击!"它会将"death"作为返回值,并将其传递给next_scene_name。现在next_scene_name已设置为"death"。如果您在此处进行其他选择(如果您对其进行编码),则可能需要设置其他场景。
然后
current_scene = self.scene_map.next_scene(next_scene_name)
通过使用前面解释的next_scene函数在Map类中搜索场景来设置current_scene。在这种情况下,搜索CentralCorridor()的返回值"death",将在类Map中的库scenes
中获得函数death()。
游戏在循环时持续到current_scene!=lastrongcene。这就是为什么在场景库中需要一个"已完成"的场景。
您在代码的最后一行调用play()
函数:a_game.play()
def opening_scene(self):
# This call the next_scene method with the parameter start_scenes.
# which is initialize to 'central_corridor' when you create the object
# with Map('central_corridor') a few lines below
return self.next_scene(self.start_scenes)
def next_scene(self, scene_name):
# This get the value for key 'central_corridor' from
# the scenes dictionary and assign it to variable val.
val = Map.scenes.get(scene_name)
return val
要理解代码,您需要理解代码的最后三行以及它们的实际作用:
a_map = Map('central_corridor')
a_game = Engine(a_map)
a_game.play()
首先创建对象a_map
,它属于Map类。Map是使用参数central_corridor调用的,该参数是保存值CentralCorridor()的字典的键。CentralCorridor()是一个继承自类Scene的类。
有了这些信息,让我们了解对象a_map
现在实际包含的内容。对象a_map
可以访问类Map中的所有内容。该对象也指向类CentralCorridor,可以访问那里的每个方法和变量。请记住,CentralCorridor继承自类Scene,这意味着它也可以访问Scene中的变量和方法。
现在让我们了解对象a_game
。此对象是Engine类对象。另一方面,Engine类具有参数a_map。正如我们所看到的,a_map是一个可以访问如上所述的许多类中的各种方法和变量的对象。现在可以访问Engine中的播放方法,即a_game.play()
。只有这样才能帮助你理解并回答你的第一个问题。只需花点时间来了解一切是如何融合并相互连接的。
关于第二个问题,事实上,正确理解以上内容可以帮助您理解Engine类中的所有内容是如何耦合的。CCD_ 9保持初始参数CCD_。在执行由代码val = Map.scenes.get(scene_name)
选取的下一个值之后,代码return val
将代码带到新场景,即类Death。