Refactor cat.
authorSimon Cross <hodgestar@gmail.com>
Sat, 5 Mar 2016 17:01:57 +0000 (19:01 +0200)
committerSimon Cross <hodgestar@gmail.com>
Sat, 5 Mar 2016 17:01:57 +0000 (19:01 +0200)
koperkapel/roaches.py
koperkapel/scenes/base.py
koperkapel/scenes/level.py
koperkapel/world.py

index c844b5277c404c41c4448239d58daa564fecb570..da362a306361b6b28006b641ffb5ac3ff4401523 100644 (file)
@@ -5,6 +5,32 @@ from pygame.constants import BLEND_RGBA_MULT
 from .actors.animsurf import AnimatedSurfActor
 from .serums import roach_serum_color
 
+NAMES = [
+    "roupert",
+    "roachel",
+    "roeginald",
+    "roichard",
+    "rory",
+    "roalph",
+    "roabia",
+    "roafi",
+    "roaman",
+    "roemus",
+    "roadley",
+    "roanaell",
+    "roashwan",
+    "roashid",
+    "roaphael",
+    "roenfield",
+    "roani",
+    "roaya",
+    "roaza",
+    "robekka",
+    "rogan",
+    "roiana",
+    "roberta",
+]
+
 
 def roach_by_name(world, roach_name):
     roaches = [r for r in world.roaches if r.name == roach_name]
@@ -13,6 +39,26 @@ def roach_by_name(world, roach_name):
     return roaches[0]
 
 
+def next_roach_name(world):
+    roach_names = [x['name'] for x in world.roaches]
+    for cand in NAMES:
+        if cand not in roach_names:
+            return cand
+
+
+def build_roach(world, name=None, health=5, **kw):
+    if name is None:
+        name = next_roach_name(world)
+    if name is None:
+        return
+    roach = {
+        "name": name,
+        "health": health,
+    }
+    roach.update(kw)
+    return roach
+
+
 class WorldRoach(object):
     """A roach proxy with no properties for display on the game level."""
 
index 14998034ce7557a883bb14ee478f5c6e67bab647..623eb42a977276e506449831be35956d83758d32 100644 (file)
@@ -43,9 +43,6 @@ class Engine:
     def move_screen(self, offset):
         self._scene.move_screen(offset)
 
-    def add_roach(self):
-        self._world.add_new_roach()
-
     @apply_events
     def update(self, dt):
         return self._scene.update(self._world.proxy(), self, dt)
@@ -110,11 +107,6 @@ class MoveViewportEvent(Event):
 
     ENGINE_METHOD = "move_screen"
 
-class AddRoachEvent(Event):
-    """ Change to a new scene. """
-
-    ENGINE_METHOD = "add_roach"
-
 
 class Layer:
     """ A single layer of actors. """
index 6a8e232284b14746b6b592b5b9c8239754b2ad93..31e1269f281a47e3a396ce1e49e16e5fa5894e81 100644 (file)
@@ -4,10 +4,10 @@ from pgzero.constants import keys
 from pygame import Surface
 import pygame.locals as pgl
 from ..loaders.levelloader import levels
-from .base import Scene, ChangeSceneEvent, MoveViewportEvent, AddRoachEvent, defer_to_update
+from .base import Scene, ChangeSceneEvent, MoveViewportEvent, defer_to_update
 from ..constants import TILE_SIZE, WIDTH, HEIGHT
+from ..roaches import build_roach
 from ..vehicles.base import Vehicle
-from ..roaches import RoachFactory, WorldRoach
 
 
 class BaseLevelScene(Scene):
@@ -111,7 +111,7 @@ class GameLevelScene(BaseLevelScene):
 
     def _set_pos(self, x, y):
         self._player_pos = (x, y)
-        #print('At ', (x, y))
+        # print('At ', (x, y))
 
     def _can_move(self, x, y):
         if self._mode == 'walk':
@@ -134,6 +134,11 @@ class GameLevelScene(BaseLevelScene):
         self._roaches.add(self._avatar)
         self._set_angle(self._angle)
 
+    @defer_to_update
+    def _add_roach(self, world):
+        world.roaches.append(build_roach(world))
+        self._vehicle_changed()
+
     @defer_to_update
     def _change_vehicle(self, world):
         vehicle = Vehicle.random()
@@ -187,8 +192,7 @@ class GameLevelScene(BaseLevelScene):
             elif self._level.is_on_friend(x, y):
                 friend = self._level.remove_friend(x, y)
                 self._friends.remove(friend)
-                self._vehicle_changed()
-                return [AddRoachEvent()]
+                self._add_roach()
             return
         elif key == keys.X:
             # Fire
index 7115194c87e57d6cc299eda89850714172615126..5a22b04fdbefd21de586e0f8e8fc03cbd01091ef 100644 (file)
@@ -1,33 +1,7 @@
 """ World and player state. """
 
 from .scenes.base import WorldEvent
-
-
-NAMES =[
-        "roupert",
-        "roachel",
-        "roeginald",
-        "roichard",
-        "rory",
-        "roalph",
-        "roabia",
-        "roafi",
-        "roaman",
-        "roemus",
-        "roadley",
-        "roanaell",
-        "roashwan",
-        "roashid",
-        "roaphael",
-        "roenfield",
-        "roani",
-        "roaya",
-        "roaza",
-        "robekka",
-        "rogan",
-        "roiana",
-        "roberta",
-       ]
+from .roaches import build_roach
 
 
 class World:
@@ -47,10 +21,7 @@ class World:
     def _build_initial_state(self):
         state = {}
         state["roaches"] = [
-            #self._build_roach("roachel", smart=True),
-            #self._build_roach("roeginald", strong=True),
-            #self._build_roach("roichard", fast=True),
-            self._build_roach("roupert"),
+            build_roach(self, "roupert"),
         ]
         state["serums"] = [
             "smart", "strong", "fast",
@@ -72,26 +43,27 @@ class World:
         }
         return state
 
-    def _build_roach(self, name, health=5, **kw):
-        roach = {
-            "name": name,
-            "health": health,
-        }
-        roach.update(kw)
-        return roach
+    def _get_obj(self, name):
+        parts = name.split(".")
+        obj = self._state
+        for p in parts[:-1]:
+            if isinstance(obj, dict):
+                obj = obj[p]
+            elif isinstance(obj, list):
+                obj = obj[int(p)]
+            else:
+                raise KeyError("%r not found in world" % (name,))
+        return obj, parts[-1]
 
     def _apply_set(self, action, updates):
         for name, value in updates.items():
-            parts = name.split(".")
-            obj = self._state
-            for p in parts[:-1]:
-                if isinstance(obj, dict):
-                    obj = obj[p]
-                elif isinstance(obj, list):
-                    obj = obj[int(p)]
-                else:
-                    raise KeyError("%r not found in world" % (name,))
-            obj[parts[-1]] = value
+            obj, key = self._get_obj(name)
+            obj[key] = value
+
+    def _apply_append(self, action, updates):
+        for name, value in updates.items():
+            obj, key = self._get_obj(name)
+            obj.append(value)
 
     def _apply_reset(self, action):
         self._state = self._build_initial_state()
@@ -102,14 +74,6 @@ class World:
     def proxy(self):
         return WorldDictProxy(self._state)
 
-    def add_new_roach(self):
-        roach_names = [x['name'] for x in self.roaches]
-        for cand in NAMES:
-            if cand not in roach_names:
-                roach = self._build_roach(cand)
-                self._state['roaches'].append(roach)
-                break
-
     def apply_event(self, action, *args, **kw):
         handler = getattr(self, "_apply_%s" % (action,))
         return handler(action, *args, **kw)
@@ -142,8 +106,8 @@ class WorldBaseProxy:
             "_events": _events,
         })
 
-    def _record_change(self, fullname, value):
-        self._events.append(WorldEvent("set", {
+    def _record_change(self, fullname, value, action="set"):
+        self._events.append(WorldEvent(action, {
             fullname: value
         }))
 
@@ -155,10 +119,6 @@ class WorldBaseProxy:
 class WorldDictProxy(WorldBaseProxy):
     """ World dictionary proxy that records changes and produces events. """
 
-    def items(self):
-        return (
-            (k, _maybe_subproxy(self, k, v)) for k, v in self._state.items())
-
     def __setattr__(self, name, value):
         self._top._record_change("%s%s" % (self._prefix, name), value)
 
@@ -173,6 +133,10 @@ class WorldDictProxy(WorldBaseProxy):
     def __getitem__(self, name):
         return self.__getattr__(name)
 
+    def items(self):
+        return (
+            (k, _maybe_subproxy(self, k, v)) for k, v in self._state.items())
+
 
 class WorldListProxy(WorldBaseProxy):
     """ World list proxy that records changes and produces events. """
@@ -188,3 +152,6 @@ class WorldListProxy(WorldBaseProxy):
 
     def __bool__(self):
         return bool(self._state)
+
+    def append(self, value):
+        self._top._record_change(self._prefix, value, action="append")