changeset 64:99fbb652ce8d

Refactor buildings so that new ones can be added just by adding a class to buildings.py.
author Simon Cross <hodgestar@gmail.com>
date Mon, 31 Aug 2009 20:25:11 +0000
parents 1047ccd22dac
children 7e9c8ad06d32
files gamelib/buildings.py gamelib/constants.py gamelib/gameboard.py
diffstat 3 files changed, 56 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/gamelib/buildings.py	Mon Aug 31 19:32:42 2009 +0000
+++ b/gamelib/buildings.py	Mon Aug 31 20:25:11 2009 +0000
@@ -10,19 +10,22 @@
 
     GRASSLAND = tiles.REVERSE_TILE_MAP['grassland']
 
-    def __init__(self, day_image, night_image, pos, size, tile_no):
+    def __init__(self, pos):
         """Initial image, tile vid position, size and tile number for building."""
+        self.day_image = imagecache.load_image(self.IMAGE)
+        self.night_image = imagecache.load_image(self.IMAGE, ('night',))
+        self.pos = pos
+        self.size = self.SIZE
+        self.tile_no = self.TILE_NO
+        self._buy_price = self.BUY_PRICE
+
         # Create the building somewhere far off screen
-        Sprite.__init__(self, day_image, (-1000, -1000))
-        self.day_image = day_image
-        self.night_image = night_image
-        self.pos = pos
-        self.size = size
-        self.tile_no = tile_no
+        Sprite.__init__(self, self.day_image, (-1000, -1000))
 
     def tile_positions(self):
         """Return pairs of (x, y) tile positions for each of the tile positions
-           occupied by the building."""
+           occupied by the building.
+           """
         xpos, ypos = self.pos
         xsize, ysize = self.size
 
@@ -58,31 +61,44 @@
 
         return True
 
+    def buy_price(self):
+        return self._buy_price
+
     def sun(self, sun_on):
         if sun_on:
             self.setimage(self.day_image)
         else:
             self.setimage(self.night_image)
 
+
 class HenHouse(Building):
     """A HenHouse."""
 
-    HENHOUSE = tiles.REVERSE_TILE_MAP['henhouse']
-
-    def __init__(self, pos):
-        day_image = imagecache.load_image('sprites/henhouse.png')
-        night_image = imagecache.load_image('sprites/henhouse.png', ('night',))
-        size = (3, 2)
-        Building.__init__(self, day_image, night_image, pos, size, self.HENHOUSE)
+    TILE_NO = tiles.REVERSE_TILE_MAP['henhouse']
+    BUY_PRICE = 100
+    SIZE = (3, 2)
+    IMAGE = 'sprites/henhouse.png'
+    NAME = 'Hen House'
 
 
 class GuardTower(Building):
     """A GuardTower."""
 
-    GUARDTOWER = tiles.REVERSE_TILE_MAP['guardtower']
+    TILE_NO = tiles.REVERSE_TILE_MAP['guardtower']
+    BUY_PRICE = 200
+    SIZE = (2, 2)
+    IMAGE = 'sprites/watchtower.png'
+    NAME = 'Watch Tower'
 
-    def __init__(self, pos):
-        day_image = imagecache.load_image('sprites/watchtower.png')
-        night_image = imagecache.load_image('sprites/watchtower.png', ('night',))
-        size = (2, 2)
-        Building.__init__(self, day_image, night_image, pos, size, self.GUARDTOWER)
+def is_building(obj):
+    """Return true if obj is a build class."""
+    return hasattr(obj, "NAME")
+
+BUILDINGS = []
+for name in dir():
+    obj = eval(name)
+    try:
+        if is_building(obj):
+            BUILDINGS.append(obj)
+    except TypeError:
+        pass
--- a/gamelib/constants.py	Mon Aug 31 19:32:42 2009 +0000
+++ b/gamelib/constants.py	Mon Aug 31 20:25:11 2009 +0000
@@ -22,11 +22,8 @@
 STARTING_CASH = 1000
 SELL_PRICE_CHICKEN = 10
 BUY_PRICE_FENCE = 50
-BUY_PRICE_HENHOUSE = 100
-BUY_PRICE_GUARDTOWER = 200
 
 TOOL_SELL_CHICKEN = 1
 TOOL_SELL_EGG = 2
-TOOL_BUY_FENCE = 3
-TOOL_BUY_HENHOUSE = 4
-TOOL_BUY_GUARDTOWER = 5
+TOOL_SELL_BUILDING = 3
+TOOL_BUY_FENCE = 4
--- a/gamelib/gameboard.py	Mon Aug 31 19:32:42 2009 +0000
+++ b/gamelib/gameboard.py	Mon Aug 31 20:25:11 2009 +0000
@@ -28,9 +28,10 @@
         self.add(self.cash_counter)
         self.add_tool_button("Sell chicken", constants.TOOL_SELL_CHICKEN)
         self.add_tool_button("Sell egg", constants.TOOL_SELL_EGG)
+        self.add_tool_button("Sell building", constants.TOOL_SELL_BUILDING)
         self.add_tool_button("Buy fence", constants.TOOL_BUY_FENCE)
-        self.add_tool_button("Buy henhouse", constants.TOOL_BUY_HENHOUSE)
-        self.add_tool_button("Buy guard tower", constants.TOOL_BUY_GUARDTOWER)
+        for building_cls in buildings.BUILDINGS:
+            self.add_tool_button("Buy %s" % (building_cls.NAME,), building_cls)
 
     def update_cash_counter(self, amount):
         self.cash_counter.update_value("Groats: %s" % amount)
@@ -87,8 +88,7 @@
         self.selected_tool = None
         self.chickens = []
         self.foxes = []
-        self.henhouses = []
-        self.guardtowers = []
+        self.buildings = []
         self.cash = 0
         self.add_cash(constants.STARTING_CASH)
 
@@ -123,10 +123,11 @@
             pass
         elif self.selected_tool == constants.TOOL_BUY_FENCE:
             self.buy_fence(self.tv.screen_to_tile(e.pos))
-        elif self.selected_tool == constants.TOOL_BUY_HENHOUSE:
-            self.buy_henhouse(self.tv.screen_to_tile(e.pos))
-        elif self.selected_tool == constants.TOOL_BUY_GUARDTOWER:
-            self.buy_guardtower(self.tv.screen_to_tile(e.pos))
+        elif buildings.is_building(self.selected_tool):
+            building_cls = self.selected_tool
+            tile_pos = self.tv.screen_to_tile(e.pos)
+            building = building_cls(tile_pos)
+            self.buy_building(building)
 
     def get_chicken(self, pos):
         for chick in self.chickens:
@@ -153,21 +154,12 @@
         self.add_cash(-constants.BUY_PRICE_FENCE)
         self.tv.set(tile_pos, tiles.REVERSE_TILE_MAP['fence'])
 
-    def buy_henhouse(self, tile_pos):
-        if self.cash < constants.BUY_PRICE_HENHOUSE:
+    def buy_building(self, building):
+        if self.cash < building.buy_price():
             return
-        henhouse = buildings.HenHouse(tile_pos)
-        if henhouse.place(self.tv):
-            self.add_cash(-constants.BUY_PRICE_HENHOUSE)
-            self.add_henhouse(henhouse)
-
-    def buy_guardtower(self, tile_pos):
-        if self.cash < constants.BUY_PRICE_GUARDTOWER:
-            return
-        guardtower = buildings.GuardTower(tile_pos)
-        if guardtower.place(self.tv):
-            self.add_cash(-constants.BUY_PRICE_GUARDTOWER)
-            self.add_guardtower(guardtower)
+        if building.place(self.tv):
+            self.add_cash(-building.buy_price())
+            self.add_building(building)
 
     def event(self, e):
         if e.type == KEYDOWN:
@@ -199,13 +191,9 @@
         self.foxes.append(fox)
         self.tv.sprites.append(fox)
 
-    def add_henhouse(self, henhouse):
-        self.henhouses.append(henhouse)
-        self.tv.sprites.append(henhouse)
-
-    def add_guardtower(self, guardtower):
-        self.guardtowers.append(guardtower)
-        self.tv.sprites.append(guardtower)
+    def add_building(self, building):
+        self.buildings.append(building)
+        self.tv.sprites.append(building)
 
     def remove_fox(self, fox):
         if fox in self.foxes: