changeset 84:5494af02a0e8

Chickens with rifles!
author Jeremy Thurgood <firxen@gmail.com>
date Tue, 01 Sep 2009 21:31:08 +0000
parents 9bd2c22e1746
children 782e45d70ea8
files gamelib/animal.py gamelib/equipment.py gamelib/gameboard.py
diffstat 3 files changed, 75 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/gamelib/animal.py	Tue Sep 01 19:40:08 2009 +0000
+++ b/gamelib/animal.py	Tue Sep 01 21:31:08 2009 +0000
@@ -1,5 +1,7 @@
 """Class for the various animals in the game"""
 
+import random
+
 from pgu.vid import Sprite
 from pgu.algo import getline
 
@@ -16,6 +18,7 @@
         self.image_left = image_left
         self.image_right = image_right
         self.pos = Position(tile_pos[0], tile_pos[1])
+        self.equipment = []
 
     def loop(self, tv, _sprite):
         ppos = tv.tile_to_view(self.pos.to_tuple())
@@ -34,6 +37,12 @@
         elif final_pos.right_of(self.pos):
             self.setimage(self.image_right)
 
+    def equip(self, item):
+        self.equipment.append(item)
+
+    def weapons(self):
+        return [e for e in self.equipment if e.is_weapon]
+
 class Chicken(Animal):
     """A chicken"""
 
@@ -47,6 +56,29 @@
         """A free chicken will move away from other free chickens"""
         pass
 
+    def _find_killable_fox(self, weapon, gameboard):
+        """Choose a random fox within range of this weapon."""
+        killable_foxes = []
+        for fox in gameboard.foxes:
+            if weapon.in_range(gameboard, self, fox):
+                killable_foxes.append(fox)
+        if not killable_foxes:
+            return None
+        return random.choice(killable_foxes)
+
+    def attack(self, gameboard):
+        """An armed chicken will attack a fox within range."""
+        if not self.weapons():
+            # Not going to take on a fox bare-winged.
+            return
+        # Choose the first weapon equipped.
+        weapon = self.weapons()[0]
+        fox = self._find_killable_fox(weapon, gameboard)
+        if not fox:
+            return
+        if weapon.hit(gameboard, self, fox):
+            gameboard.kill_fox(fox)
+
 class Egg(Animal):
     """An egg"""
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gamelib/equipment.py	Tue Sep 01 21:31:08 2009 +0000
@@ -0,0 +1,28 @@
+"""Stuff for animals to use."""
+
+import random
+
+class Equipment(object):
+    is_weapon = False
+
+class Weapon(Equipment):
+    is_weapon = True
+
+    def in_range(self, gameboard, wielder, target):
+        """Can the lucky wielder hit the potentially unlucky target with this?"""
+        return False
+
+    def hit(self, gameboard, wielder, target):
+        """Is the potentially unlucky target actually unlucky?"""
+        return False
+
+class Rifle(Weapon):
+    def in_range(self, gameboard, wielder, target):
+        """For now, we ignore terrain and just assume we can hit
+        anything that isn't too far away."""
+        return wielder.pos.dist(target.pos) <= 3
+
+    def hit(self, gameboard, wielder, target):
+        """Closer is more accurate."""
+        return random.randint(1, 100) > 60 + 10*wielder.pos.dist(target.pos)
+
--- a/gamelib/gameboard.py	Tue Sep 01 19:40:08 2009 +0000
+++ b/gamelib/gameboard.py	Tue Sep 01 21:31:08 2009 +0000
@@ -10,6 +10,7 @@
 import constants
 import buildings
 import animal
+import equipment
 
 class OpaqueLabel(gui.Label):
     def paint(self, s):
@@ -248,19 +249,20 @@
 
     def clear_foxes(self):
         for fox in self.foxes:
-            self.tv.sprites.remove(fox)
             # Any foxes that didn't make it to the woods are automatically
             # killed
             if self.in_bounds(fox.pos) and self.tv.get(fox.pos.to_tuple()) \
                     != self.WOODLAND:
-                self.killed_foxes += 1
-                self.toolbar.update_fox_counter(self.killed_foxes)
-                self.add_cash(constants.SELL_PRICE_DEAD_FOX)
+                self.kill_fox(fox)
+            else:
+                self.tv.sprites.remove(fox)
         self.foxes = [] # Remove all the foxes
 
     def move_foxes(self):
         for fox in self.foxes:
             fox.move(self)
+        for chicken in self.chickens:
+            chicken.attack(self)
 
     def add_chicken(self, chicken):
         self.chickens.append(chicken)
@@ -275,6 +277,13 @@
         self.buildings.append(building)
         self.tv.sprites.append(building)
 
+    def kill_fox(self, fox):
+        if fox in self.foxes:
+            self.killed_foxes += 1
+            self.toolbar.update_fox_counter(self.killed_foxes)
+            self.add_cash(constants.SELL_PRICE_DEAD_FOX)
+            self.remove_fox(fox)
+
     def remove_fox(self, fox):
         if fox in self.foxes:
             self.foxes.remove(fox)
@@ -331,6 +340,8 @@
                 if roll == 1:
                     # Create a chicken
                     chick = animal.Chicken((x, y))
+                    if random.randint(0, 1) == 0:
+                        chick.equip(equipment.Rifle())
                     self.add_chicken(chick)
             x += 1