Commits

Radomir Dopieralski  committed 2579c7e

Move behaviors into separate functions

  • Participants
  • Parent commits 218b390

Comments (0)

Files changed (1)

File jelly/mobs.py

 }
 
 
+def attack_behavior(mob, level):
+    if dist(level.pc.pos, mob.pos) <= 1:
+        level.attack(mob, pos2dir(mob.pos, level.pc.pos), level.pc)
+        return True
+
+
+def fitness_behavior(mob, level, fitness):
+    x, y = mob.pos
+    possible = [d for (d, (dx, dy)) in enumerate(zip(DX, DY))
+                if level[x + dx, y + dy]]
+    direction = fitness(possible)
+    try:
+        level.walk(mob, direction)
+    except level.Blocked:
+        return False
+    return True
+
+
+def wander_behavior(mob, level):
+    return fitness_behavior(mob, level, random.choice)
+
+
+def passive_behavior(mob, level):
+    return True
+
+
+def slow_behavior(mob, level):
+    mob.wait = not getattr(mob, 'wait', False)
+    if mob.wait:
+        return True
+    return False
+
+
+def coward_behavior(mob, level):
+    x, y = mob.pos
+    return fitness_behavior(mob, level, lambda choices: max(choices,
+        key=lambda d: dist((x+DX[d], y+DY[d]), level.pc.pos)))
+
+
+def aggressive_behavior(mob, level):
+    x, y = mob.pos
+    return fitness_behavior(mob, level, lambda choices: min(choices,
+        key=lambda d: dist((x+DX[d], y+DY[d]), level.pc.pos)))
+
+
 class Mob(object):
     Sprite = sprites.MobSprite
     has_light = False
     max_hp = 2
+    behaviors = [attack_behavior, wander_behavior]
 
     def __init__(self, (x, y)):
         self.pos = x, y
         return sprite, shadow, None
 
     def control(self, level):
-        if dist(level.pc.pos, self.pos) <= 1:
-            level.attack(self, pos2dir(self.pos, level.pc.pos), level.pc)
-            return
-        x, y = self.pos
-        possible = [d for (d, (dx, dy)) in enumerate(zip(DX, DY))
-                    if level[x + dx, y + dy]]
-        direction = random.choice(possible)
-        try:
-            level.walk(self, direction)
-        except level.Blocked:
-            pass
+        for behavior in self.behaviors:
+            if behavior(self, level):
+                return
 
     def hit(self, level, attacker):
         self.hp -= 1
         return True
 
 
-
 class PinkJelly(Mob):
     name = 'pink jelly'
     color = 2
     animation = [56, 56, 57, 57, 57, 57]
-
-    def control(self, level):
-        if dist(level.pc.pos, self.pos) <= 1:
-            level.attack(self, pos2dir(self.pos, level.pc.pos), level.pc)
-            return
-        x, y = self.pos
-        possible = [d for (d, (dx, dy)) in enumerate(zip(DX, DY))
-                    if level[x + dx, y + dy]]
-        # Run away from the player
-        direction = max(possible,
-            key=lambda d: dist((x+DX[d], y+DY[d]), level.pc.pos))
-        try:
-            level.walk(self, direction)
-        except level.Blocked:
-            pass
+    behaviors = [attack_behavior, coward_behavior]
 
 
 class PurpleJelly(Mob):
     name = 'red jelly'
     color = 3
     animation = [66, 66, 67, 67, 67, 67]
-
-    def control(self, level):
-        if dist(level.pc.pos, self.pos) <= 1:
-            level.attack(self, pos2dir(self.pos, level.pc.pos), level.pc)
-            return
-        x, y = self.pos
-        possible = [d for (d, (dx, dy)) in enumerate(zip(DX, DY))
-                    if level[x + dx, y + dy]]
-        # Move towards the player
-        direction = min(possible,
-            key=lambda d: dist((x+DX[d], y+DY[d]), level.pc.pos))
-        try:
-            level.walk(self, direction)
-        except level.Blocked:
-            pass
+    behaviors = [attack_behavior, aggressive_behavior]
 
 
 class BlueJelly(Mob):
     name = 'blue jelly'
     color = 0
     animation = [36, 36, 37, 37, 37, 37]
+    behaviors = [slow_behavior, attack_behavior, wander_behavior]
 
 
 class BlackJelly(Mob):