0

我正在开发一个自己选择的冒险项目,其主要功能接受 3 个参数。

  • 第一个参数由函数打印。这始终是一个包含描述场景的文本的变量
  • 第二个参数始终是一个变量,其中包含与当前场景有关的选项,由函数打印
  • 第三个参数是一个字典,其键对应于场景选择,并与用户的输入进行比较。键的值包含接下来的 3 个参数。

例子。

text1 = 'This is the scenario'  
text2 = 'These are the choices'

dict2 = {'1':[text2, text1, dict1]}
dict1 = {'1':[text1, text2, dict2]}

def mainloop(scenario, choice, consequence):
    print scenario
    print choice

    answer = raw_input('Please input 1, 2 or 3>>> ')

    if answer in consequence.keys():
        mainloop(*consequence[answer])

mainloop(text3, text2, dict1)   

我认为这将是设计我的项目的好方法,但是我遇到了字典参数的问题。因为字典值包含参数列表,其中包括其他字典,所以我不断收到错误消息:

NameError: name 'dict1' is not defined

翻转我定义字典的顺序预期会导致相同的错误,只是没有定义'dict2'。关于如何让这个概念发挥作用的任何建议?或者是时候采取完全不同的方法了?

4

4 回答 4

3

我不太清楚为什么你需要两个字典,但假设你这样做,可以使用循环引用定义字典:

text1 = 'This is the scenario'  
text2 = 'These are the choices'

dict1, dict2 = {}, {}
dict2['1'] = [text2, text1, dict1]
dict1['1'] = [text1, text2, dict2]
于 2013-11-13T18:14:19.913 回答
1

有几件事我建议重新考虑整个方法。

正如其他人指出的那样,mainloop()实际上并不是一个循环;这是一个递归函数。理想情况下,如果这是一个游戏循环,您会希望它更像……</p>

def myGameLoop():
    gameRunning = True
    while gameRunning:
        # code that displays your rooms, gets user input,
        #and checks to make sure that gameRunning is not False.
        #for an example, something like:
        if somethingAwfulHappened
            gameRunning = False

这样,您不必多次调用mainloop,它也没有理由调用自己。

此外,您的房间字典/列表不断告诉您它们不存在的原因是因为它们不存在 :) 这实际上是一个很好的例子,说明了为什么分开您的关注点是个好主意!

这样想:为什么“房间”对象——无论是字典、列表、对象等——需要包含有关其他房间的任何数据?你的厨房可能会通向你的浴室,当然——但你的厨房知道它通向浴室吗?通过通向浴室而不是卧室,它是否有新的用途?就像你的厨房不“关心”它连接到你的浴室一样,你的 dicts 也不需要通过在自己的数据中明确命名彼此来“知道”它们是连接的。

一个理想的方法可能是去定义所有房间,然后创建一个描述房间之间关系的“地图”。例如:

kitchen = {
    "name":"Kitchen",
    "description": "This is the kitchen! It's nice and clean.",
    "exits": "S", "E"
}

bathroom = {
    "name":"Bathroom",
    "description":"This is the bathroom. Someone left a towel on the floor.",
    "exits":"W", "S"
}
#and so on, creating rooms

现在创建一个地图字典,它只包含所有这些信息并描述这些出口是如何工作的。

mapOfHouse = {
    "kitchen": kitchen,
    "leadsTo": {
        "S": bathroom,
        "E": someOtherRoom ##some other place you've defined
    },
    "bathroom": bathroom,
    "leadsTo": {
        "S": otherAwesomePlaces,
        "E": kitchen
    },

    #and so on for other rooms in the house/on the map/etc
 }

一旦你勾勒出所有这些,你就可以设置你的游戏循环来获取玩家的输入,检查房间的出口,如果有匹配,只要循环仍然存在True,它就会回到顶部,显示更新的信息.

似乎需要更多的工作,但实际上这给了你极大的自由。它可以让您在设计房间时严格关注房间,然后在更新地图时严格关注地图,然后让您设计一个游戏循环,它并不真正关心循环内容的内容,只要因为它会一直停留True并从玩家那里得到良好的指示。

于 2013-11-13T18:44:45.490 回答
0

您在 dict2 中引用了 dict1,但 dict1 尚不存在。

于 2013-11-13T18:11:17.773 回答
0

您的问题如下:

dict2 = {'1':[text2, text1, dict1]} # NameError: Here dict1 does not exist yet
dict1 = {'1':[text1, text2, dict2]}

您只能通过在引用对象之前定义对象来解决此问题。为了实现这一点,您可以执行以下操作:

dict1, dict2 = {}, {} # Define both objects
dict1[1] = [text2, text1, dict2] # Here dict2 is already defined, no NameError
dict1[2] = None # ...
dict2[1] = [text1, text2, dict1] # And here is dict1 already defined too
dict2[2] = None # ...

我们可以问的问题是:引用一个对象然后更改它会改变引用吗? 答案是肯定的,确实如此;前提是您使用的是引用而不是副本(分配字典总是引用它们)。

如果您想制作副本而不是参考怎么办?

好吧,您可以通过模块中的deepcopyandcopy函数来做到这一点copy

s的问题NameError是没有定义这样的名称;Python 不使用名称来跟踪变量:同一个名称可以对应不同的变量(在不同的范围内或在不同的时间),并且可以通过不同的名称访问同一个变量(通过将一个名称的值分配给另一个)。

当你这样做时del x,你取消了一个变量与其名称的链接,但你并不总是消除该对象。

例如,以下代码可以stash正常工作和打印,尽管我们通过del运算符取消了str对象'hello'x包含它的对象的链接。

x = {1: 'hello'}
stash = x[1]
del x[1]

print stash

通过删除该stash对象,该'hello'对象现在可能在某些时候容易被垃圾收集。

提醒

如果您想通过名称引用其他对象,则必须在该引用发生之前对其进行命名。

于 2013-11-13T18:33:13.217 回答