我正在尝试使用Python制作一个简单的文本游戏。我有一个Room
课程:
class Room():
def __init__(self, monster, exits, loot):
self.room_guard = monster
self.exits = exits
self.guard_is_alive = True
self.loot = loot
当我创建房间时,我收到错误,因为我在创建它们之前调用它们:
room_2 = Room(spider, {"West": room_3, "East": room_4, "South": room_1}, 2)
room_1 = Room(trogdor, {"North": room_2}, 2)
2号房间无法"South": room_1
,因为它尚未实例化。有办法解决这个问题吗?
答案 0 :(得分:6)
两个选项:间接,创建后的分配。
不是直接引用房间,而是使用dict
将房间名称映射到房间:
rooms = {}
rooms['room_2'] = Room(spider, {"West": 'room_3', "East": 'room_4', "South": 'room_1'}, 2)
rooms['room_1'] = Room(trogdor, {"North": 'room_2'}, 2)
或者在创建Room对象后指定出口:
room_2 = Room(spider, {}, 2)
room_1 = Room(trogdor, {}, 2)
room_2.exits = {"West": room_3, "East": room_4, "South": room_1}
room_1.exits = {"North": room_2}
答案 1 :(得分:2)
在创建对象之前无法引用对象。但是,您可以在创建对象后修改exits
字典,以在房间之间创建链接。一个很好的方法可能是让你创建的第二个房间通过一个额外的参数自动创建一些返回自己的链接:
class Room():
def __init__(self, monster, exits, loot, exits_back={}):
self.room_guard = monster
self.exits = exits
self.guard_is_alive = True
self.loot = loot
for direction, room in exits_back.items():
room.exits[direction] = self
然后你将一个额外的字典传递给后一个房间的构造函数,让它从前一个房间将链接设置回自己:
room_2 = Room(spider, {"West": room_3, "East": room_4}, 2) # no room_1 ref here
room_1 = Room(trogdor, {"North": room_2}, 2, {"South": room_2}) # extra dict passed
答案 2 :(得分:0)
这个问题有很多解决方案。这是另一个。此解决方案等待初始化对象,直到创建完所有对象为止。
class Room():
def create(self, monster, exits, loot=None):
self.room_guard = monster
self.exits = exits
self.guard_is_alive = True
self.loot = loot
room_1 = Room()
room_2 = Room()
room_3 = Room()
room_4 = Room()
room_1.create('spider', {"West": room_3, "East": room_4, "South": room_1}, 2)
room_2.create('trogdor', {"North": room_2}, 2)
编辑:使用上述方法,这是组织房间的一种可能方式。我已将房间存放在2-dimensional list。这个解决方案很好,因为你不必担心出口的位置;该计划为您创建的每个房间都有所体现。
rooms = []
horizontal_room_count = 2
vertical_room_count = 2
class Room():
def __init__(self, x, y):
self.x = x
self.y = y
def create(self, monster, loot):
self.room_guard = monster
self.exits = self.get_exits()
self.guard_is_alive = True
self.loot = loot
def get_exits(self):
x, y = self.x, self.y
def get_room(x2, y2):
if x2 < 0 or y2 < 0 or x2 >= horizontal_room_count or y2 >= vertical_room_count:
return None
return rooms[x2][y2]
return {
'West': get_room(x-1, y),
'East': get_room(x+1, y),
'North': get_room(x, y+1),
'South': get_room(x, y-1)
}
rooms = [[Room(x,y) for x in range(horizontal_room_count)] for y in range(vertical_room_count)]
rooms[0][0].create('spider', loot=2)
rooms[0][1].create('trogdor', loot=2)
我们知道有一个很好的简单界面可以与房间互动。以下是使用界面在角落位置(0,0)与房间进行交互的示例。
#creating the room
>> rooms[0][0].create('evil_fairy', loot=3)
#finding the exits
>> rooms[0][0].exits
#accessing info
>> rooms[0][0].loot
答案 3 :(得分:0)
我能想象的最好方法是创建对象,然后在两个不同的步骤中创建链接。
class Room(object):
def __init__(self, monster, loot):
self.exits = {direction:None for direction in
["North", "South", "East", "West"]}
# rooms have no exits until you add links to them manually
self.room_guard = monster
self.guard_is_alive = True
self.loot = loot
def add_link(self, other, ordinal):
"""Creates a link between this room and another in the specified direction
room_A.add_link(room_B, 'East')
sets room_A.exits['East'] = room_B and room_B.exits['West'] = room_A"""
if not hasattr(other, 'exits')
raise ValueError("Can only link with other objects with exits")
ordinal_map = {"North":"South", "South":"North",
"East":"West", "West":"East"}
try:
other_ordinal = ordinal_map[ordinal]
except KeyError:
raise ValueError("ordinal must be one of {}".format(
', '.join(ordinal_map.keys())))
self.exits[ordinal] = other
other.exits[other_ordinal] = self
首先制作房间
map = """ A - B C
| |
D - E - F """
# bonus points if you can build a function that takes this as input and
# outputs the correct structure of rooms!!!
rooms = {key:Room(*args) for key,args in zip("ABCDEF",monster_loot_tuples)}
# monster_loot_tuples would be a list like [("Gargoyle","+1 Sword of Smiting"), ...]
然后添加链接
rooms['A'].add_link(rooms['B'], 'East')
rooms['A'].add_link(rooms['D'], 'South')
rooms['D'].add_link(rooms['E'], 'East')
rooms['E'].add_link(rooms['F'], 'East')
rooms['F'].add_link(rooms['C'], 'North')