2015-04-01 45 views
2

我想玩弄一个简单的文本游戏的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因为它没有被实例化。有没有解决的办法?

回答

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_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} 
+0

我不知道为什么我没有想到这一点。谢谢! – 2015-04-01 03:50:50

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 
+0

有趣。我会试试这个。谢谢! – 2015-04-01 03:51:37

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 
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') 
+0

当然'房间'可能更好地用作列表,除非您需要稍后专门访问它们。 – 2015-04-01 04:26:05

相关问题