changeset 201:3495a2025bc6

Break puzzlers out of game_object.py
author Stefano Rivera <stefano@rivera.za.net>
date Tue, 03 Sep 2013 23:27:25 +0200
parents dc0cc8228e2a
children 63d7ab8ede83
files nagslang/game_object.py nagslang/level.py nagslang/puzzle.py nagslang/tests/test_game_object.py nagslang/tests/test_puzzle.py
diffstat 5 files changed, 174 insertions(+), 166 deletions(-) [+]
line wrap: on
line diff
--- a/nagslang/game_object.py	Tue Sep 03 23:16:09 2013 +0200
+++ b/nagslang/game_object.py	Tue Sep 03 23:27:25 2013 +0200
@@ -4,89 +4,19 @@
 import pymunk
 import pymunk.pygame_util
 
+from nagslang import puzzle
 from nagslang.constants import (
     SWITCH_PUSHERS, COLLISION_TYPE_SWITCH, COLLISION_TYPE_BOX, ZORDER_LOW,
-    ZORDER_FLOOR, COLLISION_TYPE_DOOR, COLLISION_TYPE_PLAYER)
+    ZORDER_FLOOR, COLLISION_TYPE_DOOR)
 from nagslang.options import options
 from nagslang.resources import resources
 from nagslang.events import DoorEvent
 from nagslang.widgets.text import LabelWidget
 
 
-class PuzzleGlue(object):
-    """Glue that holds bits of a puzzle together.
-    """
-    def __init__(self):
-        self._components = {}
-
-    def add_component(self, name, puzzler):
-        if not isinstance(puzzler, Puzzler):
-            puzzler = puzzler.puzzler
-        self._components[name] = puzzler
-        puzzler.set_glue(self)
-
-    def get_state_of(self, name):
-        return self._components[name].get_state()
-
-
-class Puzzler(object):
-    """Behaviour specific to a puzzle component.
-    """
-    def set_glue(self, glue):
-        self.glue = glue
-
-    def set_game_object(self, game_object):
-        self.game_object = game_object
-
-    def get_state(self):
-        raise NotImplementedError()
-
-
-class YesPuzzler(Puzzler):
-    """Yes sir, I'm always on.
-    """
-    def get_state(self):
-        return True
-
-
-class NoPuzzler(Puzzler):
-    """No sir, I'm always off.
-    """
-    def get_state(self):
-        return False
-
-
-class CollidePuzzler(Puzzler):
-    def __init__(self, *collision_types):
-        if not collision_types:
-            collision_types = (COLLISION_TYPE_PLAYER,)
-        self._collision_types = collision_types
-
-    def get_state(self):
-        space = self.game_object.get_space()
-        for shape in space.shape_query(self.game_object.get_shape()):
-            if shape.collision_type in self._collision_types:
-                return True
-        return False
-
-
-class StateProxyPuzzler(Puzzler):
-    def __init__(self, state_source):
-        self._state_source = state_source
-
-    def get_state(self):
-        return self.glue.get_state_of(self._state_source)
-
-
-class StateLogicalAndPuzzler(Puzzler):
-    def __init__(self, *state_sources):
-        self._state_sources = state_sources
-
-    def get_state(self):
-        for state_source in self._state_sources:
-            if not self.glue.get_state_of(state_source):
-                return False
-        return True
+# For levels to import, until we get module names in 'classname'
+StateProxyPuzzler = puzzle.StateProxyPuzzler
+StateLogicalAndPuzzler = puzzle.StateLogicalAndPuzzler
 
 
 class Physicser(object):
@@ -403,7 +333,7 @@
                 True: resources.get_image('objects', 'sensor_on.png'),
                 False: resources.get_image('objects', 'sensor_off.png'),
             }),
-            CollidePuzzler(*SWITCH_PUSHERS),
+            puzzle.CollidePuzzler(*SWITCH_PUSHERS),
         )
 
 
@@ -417,7 +347,7 @@
         super(Note, self).__init__(
             SingleShapePhysicser(space, self.shape),
             ImageRenderer(resources.get_image('objects', 'note.png')),
-            CollidePuzzler(),
+            puzzle.CollidePuzzler(),
             TextOverlay(message),
         )
 
@@ -436,7 +366,7 @@
                 True: resources.get_image('objects', 'light_on.png'),
                 False: resources.get_image('objects', 'light_off.png'),
             }),
-            StateProxyPuzzler(state_source),
+            puzzle.StateProxyPuzzler(state_source),
         )
 
 
@@ -464,9 +394,9 @@
         self.destination = destination
         self.dest_pos = tuple(dest_pos)
         if key_state is None:
-            puzzler = YesPuzzler()
+            puzzler = puzzle.YesPuzzler()
         else:
-            puzzler = StateProxyPuzzler(key_state)
+            puzzler = puzzle.StateProxyPuzzler(key_state)
         super(Door, self).__init__(
             SingleShapePhysicser(space, self.shape),
             ImageRenderer(resources.get_image('objects', 'door.png')),
--- a/nagslang/level.py	Tue Sep 03 23:16:09 2013 +0200
+++ b/nagslang/level.py	Tue Sep 03 23:27:25 2013 +0200
@@ -3,6 +3,7 @@
 
 from nagslang import game_object as go
 from nagslang import enemies
+from nagslang import puzzle
 from nagslang.resources import resources
 from nagslang.yamlish import load, dump
 
@@ -32,7 +33,7 @@
         self._tile_image = None
         self._surface = None
         self._exterior = False
-        self._glue = go.PuzzleGlue()
+        self._glue = puzzle.PuzzleGlue()
         self.drawables = []
         self.overlay_drawables = []
         self._game_objects = []
@@ -74,7 +75,7 @@
         # We should probably build a registry of game objects or something.
         # At least this is better than just calling `eval`, right?
         cls = getattr(go, classname)
-        if issubclass(cls, go.Puzzler):
+        if issubclass(cls, puzzle.Puzzler):
             gobj = cls(*args)
         elif issubclass(cls, go.GameObject):
             gobj = cls(space, *args)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nagslang/puzzle.py	Tue Sep 03 23:27:25 2013 +0200
@@ -0,0 +1,77 @@
+from nagslang.constants import COLLISION_TYPE_PLAYER
+
+
+class PuzzleGlue(object):
+    """Glue that holds bits of a puzzle together.
+    """
+    def __init__(self):
+        self._components = {}
+
+    def add_component(self, name, puzzler):
+        if not isinstance(puzzler, Puzzler):
+            puzzler = puzzler.puzzler
+        self._components[name] = puzzler
+        puzzler.set_glue(self)
+
+    def get_state_of(self, name):
+        return self._components[name].get_state()
+
+
+class Puzzler(object):
+    """Behaviour specific to a puzzle component.
+    """
+    def set_glue(self, glue):
+        self.glue = glue
+
+    def set_game_object(self, game_object):
+        self.game_object = game_object
+
+    def get_state(self):
+        raise NotImplementedError()
+
+
+class YesPuzzler(Puzzler):
+    """Yes sir, I'm always on.
+    """
+    def get_state(self):
+        return True
+
+
+class NoPuzzler(Puzzler):
+    """No sir, I'm always off.
+    """
+    def get_state(self):
+        return False
+
+
+class CollidePuzzler(Puzzler):
+    def __init__(self, *collision_types):
+        if not collision_types:
+            collision_types = (COLLISION_TYPE_PLAYER,)
+        self._collision_types = collision_types
+
+    def get_state(self):
+        space = self.game_object.get_space()
+        for shape in space.shape_query(self.game_object.get_shape()):
+            if shape.collision_type in self._collision_types:
+                return True
+        return False
+
+
+class StateProxyPuzzler(Puzzler):
+    def __init__(self, state_source):
+        self._state_source = state_source
+
+    def get_state(self):
+        return self.glue.get_state_of(self._state_source)
+
+
+class StateLogicalAndPuzzler(Puzzler):
+    def __init__(self, *state_sources):
+        self._state_sources = state_sources
+
+    def get_state(self):
+        for state_source in self._state_sources:
+            if not self.glue.get_state_of(state_source):
+                return False
+        return True
--- a/nagslang/tests/test_game_object.py	Tue Sep 03 23:16:09 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-from unittest import TestCase
-
-from nagslang.constants import COLLISION_TYPE_OTHER, SWITCH_PUSHERS
-from nagslang import game_object
-
-
-class FakeShape(object):
-    def __init__(self, collision_type=COLLISION_TYPE_OTHER):
-        self.collision_type = collision_type
-
-
-class FakeSpace(object):
-    def __init__(self, *shapes):
-        self._shapes = shapes
-
-    def shape_query(self, shape):
-        return self._shapes
-
-
-class FakeGameObject(object):
-    def __init__(self, shape, space):
-        self._shape = shape
-        self._space = space
-
-    def get_shape(self):
-        return self._shape
-
-    def get_space(self):
-        return self._space
-
-
-class FakePuzzler(game_object.Puzzler):
-    def __init__(self, fake_state):
-        self.fake_state = fake_state
-
-    def get_state(self):
-        return self.fake_state
-
-
-class TestPuzzles(TestCase):
-    def mkpuzzler(self, gobj, cls, *args, **kw):
-        puzzler = cls(*args, **kw)
-        puzzler.set_game_object(gobj)
-        return puzzler
-
-    def assert_collide_state(self, expected, shapes, collision_types):
-        gobj = FakeGameObject(None, FakeSpace(*shapes))
-        puzzler = self.mkpuzzler(
-            gobj, game_object.CollidePuzzler, *collision_types)
-        self.assertEqual(expected, puzzler.get_state())
-
-    def test_collide_puzzler(self):
-        self.assert_collide_state(False, [], [])
-        self.assert_collide_state(False, [FakeShape()], SWITCH_PUSHERS)
-
-        for collision_type in SWITCH_PUSHERS:
-            self.assert_collide_state(
-                True, [FakeShape(collision_type)], SWITCH_PUSHERS)
-            self.assert_collide_state(
-                True, [FakeShape(), FakeShape(collision_type)], SWITCH_PUSHERS)
-
-    def test_state_proxy_puzzler(self):
-        glue = game_object.PuzzleGlue()
-        puzzler = game_object.StateProxyPuzzler('faker')
-        glue.add_component('puzzler', puzzler)
-        faker = FakePuzzler('foo')
-        glue.add_component('faker', faker)
-
-        self.assertEqual('foo', puzzler.get_state())
-        faker.fake_state = 'bar'
-        self.assertEqual('bar', puzzler.get_state())
-
-    def test_glue_add_component(self):
-        glue = game_object.PuzzleGlue()
-        puzzler = FakePuzzler('foo')
-        gobj = FakeGameObject(None, None)
-        gobj.puzzler = FakePuzzler('bar')
-
-        self.assertEqual({}, glue._components)
-        glue.add_component('foo', puzzler)
-        self.assertEqual({'foo': puzzler}, glue._components)
-        glue.add_component('bar', gobj)
-        self.assertEqual(
-            {'foo': puzzler, 'bar': gobj.puzzler}, glue._components)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nagslang/tests/test_puzzle.py	Tue Sep 03 23:27:25 2013 +0200
@@ -0,0 +1,84 @@
+from unittest import TestCase
+
+from nagslang.constants import COLLISION_TYPE_OTHER, SWITCH_PUSHERS
+from nagslang import puzzle
+
+
+class FakeShape(object):
+    def __init__(self, collision_type=COLLISION_TYPE_OTHER):
+        self.collision_type = collision_type
+
+
+class FakeSpace(object):
+    def __init__(self, *shapes):
+        self._shapes = shapes
+
+    def shape_query(self, shape):
+        return self._shapes
+
+
+class FakeGameObject(object):
+    def __init__(self, shape, space):
+        self._shape = shape
+        self._space = space
+
+    def get_shape(self):
+        return self._shape
+
+    def get_space(self):
+        return self._space
+
+
+class FakePuzzler(puzzle.Puzzler):
+    def __init__(self, fake_state):
+        self.fake_state = fake_state
+
+    def get_state(self):
+        return self.fake_state
+
+
+class TestPuzzles(TestCase):
+    def mkpuzzler(self, gobj, cls, *args, **kw):
+        puzzler = cls(*args, **kw)
+        puzzler.set_game_object(gobj)
+        return puzzler
+
+    def assert_collide_state(self, expected, shapes, collision_types):
+        gobj = FakeGameObject(None, FakeSpace(*shapes))
+        puzzler = self.mkpuzzler(
+            gobj, puzzle.CollidePuzzler, *collision_types)
+        self.assertEqual(expected, puzzler.get_state())
+
+    def test_collide_puzzler(self):
+        self.assert_collide_state(False, [], [])
+        self.assert_collide_state(False, [FakeShape()], SWITCH_PUSHERS)
+
+        for collision_type in SWITCH_PUSHERS:
+            self.assert_collide_state(
+                True, [FakeShape(collision_type)], SWITCH_PUSHERS)
+            self.assert_collide_state(
+                True, [FakeShape(), FakeShape(collision_type)], SWITCH_PUSHERS)
+
+    def test_state_proxy_puzzler(self):
+        glue = puzzle.PuzzleGlue()
+        puzzler = puzzle.StateProxyPuzzler('faker')
+        glue.add_component('puzzler', puzzler)
+        faker = FakePuzzler('foo')
+        glue.add_component('faker', faker)
+
+        self.assertEqual('foo', puzzler.get_state())
+        faker.fake_state = 'bar'
+        self.assertEqual('bar', puzzler.get_state())
+
+    def test_glue_add_component(self):
+        glue = puzzle.PuzzleGlue()
+        puzzler = FakePuzzler('foo')
+        gobj = FakeGameObject(None, None)
+        gobj.puzzler = FakePuzzler('bar')
+
+        self.assertEqual({}, glue._components)
+        glue.add_component('foo', puzzler)
+        self.assertEqual({'foo': puzzler}, glue._components)
+        glue.add_component('bar', gobj)
+        self.assertEqual(
+            {'foo': puzzler, 'bar': gobj.puzzler}, glue._components)