changeset 252:dfc89bc64fdb

Start of walkthrough "unit test" and associated fixes and tweaks.
author Jeremy Thurgood <firxen@gmail.com>
date Fri, 27 Aug 2010 16:45:47 +0200
parents 602fe654bd37
children 60a0757bee05
files gamelib/scenes/bridge.py gamelib/scenes/crew_quarters.py gamelib/scenes/cryo.py gamelib/scenes/engine.py gamelib/scenes/machine.py gamelib/scenes/mess.py gamelib/scenes/scene_widgets.py gamelib/state.py gamelib/tests/game_logic_utils.py gamelib/tests/test_scene_interactions_cryo.py gamelib/tests/test_walkthrough.py
diffstat 11 files changed, 108 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/gamelib/scenes/bridge.py	Fri Aug 27 16:20:26 2010 +0200
+++ b/gamelib/scenes/bridge.py	Fri Aug 27 16:45:47 2010 +0200
@@ -52,7 +52,7 @@
 
 class ToMap(Door):
 
-    NAME = "bridge.tomap"
+    SCENE = "bridge"
 
     INTERACTS = {
         "door": InteractNoImage(707, 344, 84, 245),
--- a/gamelib/scenes/crew_quarters.py	Fri Aug 27 16:20:26 2010 +0200
+++ b/gamelib/scenes/crew_quarters.py	Fri Aug 27 16:45:47 2010 +0200
@@ -23,7 +23,7 @@
 
 class ToMap(Door):
 
-    NAME = "crew.tomap"
+    SCENE = "crew"
 
     INTERACTS = {
         "door": InteractText(100, 200, "To Map"),
--- a/gamelib/scenes/cryo.py	Fri Aug 27 16:20:26 2010 +0200
+++ b/gamelib/scenes/cryo.py	Fri Aug 27 16:45:47 2010 +0200
@@ -279,7 +279,7 @@
 class CryoRoomDoor(Door):
     "Door to the cryo room."
 
-    NAME = "cryo.door"
+    SCENE = "cryo"
 
     INTERACTS = {
         "shut": InteractNoImage(290, 260, 99, 152),
--- a/gamelib/scenes/engine.py	Fri Aug 27 16:20:26 2010 +0200
+++ b/gamelib/scenes/engine.py	Fri Aug 27 16:45:47 2010 +0200
@@ -23,7 +23,7 @@
 
 class ToMap(Door):
 
-    NAME = "engine.tomap"
+    SCENE = "engine"
 
     INTERACTS = {
         "door": InteractText(100, 200, "To Map"),
--- a/gamelib/scenes/machine.py	Fri Aug 27 16:20:26 2010 +0200
+++ b/gamelib/scenes/machine.py	Fri Aug 27 16:45:47 2010 +0200
@@ -28,7 +28,7 @@
 
 class ToMap(Door):
 
-    NAME = "machine.tomap"
+    SCENE = "machine"
 
     INTERACTS = {
         "door": InteractText(100, 200, "To Map"),
--- a/gamelib/scenes/mess.py	Fri Aug 27 16:20:26 2010 +0200
+++ b/gamelib/scenes/mess.py	Fri Aug 27 16:45:47 2010 +0200
@@ -198,7 +198,7 @@
 
 class ToMap(Door):
 
-    NAME = "mess.tomap"
+    SCENE = "mess"
 
     INTERACTS = {
         "door": InteractNoImage(20, 390, 85, 150),
--- a/gamelib/scenes/scene_widgets.py	Fri Aug 27 16:20:26 2010 +0200
+++ b/gamelib/scenes/scene_widgets.py	Fri Aug 27 16:45:47 2010 +0200
@@ -9,6 +9,11 @@
     """A door somewhere"""
 
     DEST = "map"
+    SCENE = None
+
+    def __init__(self):
+        self.NAME = self.SCENE + '.door'
+        Thing.__init__(self)
 
     def is_interactive(self):
         return True
--- a/gamelib/state.py	Fri Aug 27 16:20:26 2010 +0200
+++ b/gamelib/state.py	Fri Aug 27 16:45:47 2010 +0200
@@ -593,9 +593,13 @@
 class CloneableItem(Item):
     _counter = 0
 
+    @classmethod
+    def _get_new_id(cls):
+        cls._counter += 1
+        return cls._counter - 1
+
     def __init__(self, name):
-        my_count = CloneableItem._counter
-        CloneableItem._counter += 1
+        my_count = self._get_new_id()
         super(CloneableItem, self).__init__("%s.%s" % (name, my_count))
         self.tool_name = name
         if self.TOOL_NAME is not None:
--- a/gamelib/tests/game_logic_utils.py	Fri Aug 27 16:20:26 2010 +0200
+++ b/gamelib/tests/game_logic_utils.py	Fri Aug 27 16:45:47 2010 +0200
@@ -1,10 +1,9 @@
 import unittest
 
 import pygame
+from pygame.locals import SWSURFACE
 
 from gamelib import state
-
-from pygame.locals import SWSURFACE
 from gamelib.constants import SCREEN
 
 
@@ -21,18 +20,16 @@
         self.state = state.initial_state()
         self.state.set_current_scene(self.CURRENT_SCENE)
 
-    def set_game_data(self, key, value, thing=None, scene=None):
-        if scene is None:
-            scene = self.CURRENT_SCENE
-        gizmo = self.state.scenes[scene]
+    def set_game_data(self, key, value, thing=None):
+        gizmo = self.state.current_scene
         if thing is not None:
             gizmo = gizmo.things[thing]
         gizmo.set_data(key, value)
 
     def assert_game_data(self, key, value, thing=None, scene=None):
-        if scene is None:
-            scene = self.CURRENT_SCENE
-        gizmo = self.state.scenes[scene]
+        gizmo = self.state.current_scene
+        if scene is not None:
+            gizmo = self.state.scenes[scene]
         if thing is not None:
             gizmo = gizmo.things[thing]
         self.assertEquals(value, gizmo.get_data(key))
@@ -49,11 +46,16 @@
     def assert_item_exists(self, item, exists=True):
         self.assertEquals(exists, item in self.state.items)
 
-    def interact_thing(self, thing, item=None, detail=False):
+    def assert_current_scene(self, scene):
+        self.assertEquals(scene, self.state.current_scene.name)
+
+    def interact_thing(self, thing, item=None):
         item_obj = None
         if item is not None:
             item_obj = self.state.items[item]
-        thing_container = self.state.current_scene
-        if detail:
-            thing_container = self.state.current_detail
-        return thing_container.things[thing].interact(item_obj)
+        thing_container = self.state.current_detail or self.state.current_scene
+        result = thing_container.things[thing].interact(item_obj)
+        if result and result.detail_view:
+            self.state.set_current_detail(result.detail_view)
+        return result
+
--- a/gamelib/tests/test_scene_interactions_cryo.py	Fri Aug 27 16:20:26 2010 +0200
+++ b/gamelib/tests/test_scene_interactions_cryo.py	Fri Aug 27 16:45:47 2010 +0200
@@ -52,8 +52,8 @@
 
         self.interact_thing('cryo.door')
 
-        self.assert_game_data('door', 'open', 'cryo.door')
-        self.assertEquals('map', self.state.current_scene.name)
+        self.assert_game_data('door', 'open', 'cryo.door', scene='cryo')
+        self.assert_current_scene('map')
 
     def test_cryo_door_open_titanium_leg(self):
         "The door is open and we touch it with the titanium leg. No change."
@@ -63,7 +63,7 @@
         self.interact_thing('cryo.door', 'titanium_leg')
 
         self.assert_game_data('door', 'open', 'cryo.door')
-        self.assertEquals('cryo', self.state.current_scene.name)
+        self.assert_current_scene('cryo')
 
     def test_cryo_unit_alpha_full_hand(self):
         "The cryo unit has the leg in it and we touch it. We get the leg."
@@ -73,7 +73,7 @@
         self.assert_inventory_item('titanium_leg', False)
         self.assert_detail_thing('cryo.titanium_leg', True)
 
-        self.interact_thing('cryo.titanium_leg', detail='cryo_detail')
+        self.interact_thing('cryo.titanium_leg')
 
         self.assert_game_data('contains_titanium_leg', False, 'cryo.unit.1')
         self.assert_inventory_item('titanium_leg', True)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gamelib/tests/test_walkthrough.py	Fri Aug 27 16:45:47 2010 +0200
@@ -0,0 +1,71 @@
+import game_logic_utils
+
+
+class TestWalkthrough(game_logic_utils.GameLogicTestCase):
+
+    CURRENT_SCENE = 'cryo'
+
+    def close_detail(self):
+        self.state.set_current_detail(None)
+
+    def move(self, source, target):
+        self.interact_thing(source+'.door')
+        self.assert_current_scene('map')
+        self.interact_thing('map.to'+target)
+        self.assert_current_scene(target)
+
+    def test_walkthrough(self):
+        """A complete game walkthrough.
+
+        This should only contain interacts and assertions."""
+
+        # TODO: Add flavour interactions, maybe?
+
+        # Partially open the door.
+        self.assert_game_data('door', 'shut', 'cryo.door')
+        self.interact_thing('cryo.door')
+        self.assert_game_data('door', 'ajar', 'cryo.door')
+
+        # Get the titanium leg.
+        self.interact_thing('cryo.unit.1')
+        self.assertEquals('cryo_detail', self.state.current_detail.name)
+        self.assert_detail_thing('cryo.titanium_leg')
+        self.interact_thing('cryo.titanium_leg')
+        self.assert_detail_thing('cryo.titanium_leg', False)
+        self.assert_inventory_item('titanium_leg')
+        self.close_detail()
+
+        # Open the door the rest of the way.
+        self.interact_thing('cryo.door', 'titanium_leg')
+        self.assert_game_data('door', 'open', 'cryo.door')
+        self.assert_inventory_item('titanium_leg')
+
+        # Go to the machine room.
+        self.move('cryo', 'machine')
+
+        # Sharpen leg into machete.
+        self.interact_thing('machine.grinder', 'titanium_leg')
+        self.assert_inventory_item('titanium_leg', False)
+        self.assert_inventory_item('machete')
+
+        # Go to the mess.
+        self.move('machine', 'mess')
+
+        # Clear the broccoli.
+        self.assert_game_data('status', 'blocked', 'mess.tubes')
+        self.interact_thing('mess.tubes', 'machete')
+        self.assert_game_data('status', 'broken', 'mess.tubes')
+
+        # Get the cans.
+        self.assert_game_data('cans_available', 3, 'mess.cans')
+        self.interact_thing('mess.cans')
+        self.assert_inventory_item('full_can.0')
+        self.interact_thing('mess.cans')
+        self.assert_inventory_item('full_can.1')
+        self.interact_thing('mess.cans')
+        self.assert_inventory_item('full_can.2')
+        self.assert_game_data('cans_available', 0, 'mess.cans')
+
+
+        self.fail("Walkthrough incomplete.")
+