2015-04-01 75 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

相關問題