changeset 555:c014f5023cd2

Test run replays
author Neil Muller <drnlmuller@gmail.com>
date Thu, 22 Sep 2011 17:32:38 +0200
parents b308ebaa96f3
children 30a5ded79313
files mamba/engine.py mamba/habitats/editor.py mamba/widgets/level.py
diffstat 3 files changed, 66 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/mamba/engine.py	Fri Sep 23 22:17:46 2011 +0200
+++ b/mamba/engine.py	Thu Sep 22 17:32:38 2011 +0200
@@ -129,6 +129,15 @@
         super(FlipArrowsEvent, cls).post()
 
 
+class ReplayEvent(UserEvent):
+
+    TYPE = "REPLAY_EVENT"
+
+    @classmethod
+    def post(cls, run, replay_pos):
+        super(ReplayEvent, cls).post(run=run, replay_pos=replay_pos)
+
+
 class HabitatSetupEvent(UserEvent):
 
     TYPE = "SETUP_HABITAT"
--- a/mamba/habitats/editor.py	Fri Sep 23 22:17:46 2011 +0200
+++ b/mamba/habitats/editor.py	Thu Sep 22 17:32:38 2011 +0200
@@ -74,6 +74,7 @@
         self.sprite_mode = 'Add'
         self.sprite_cls = None
         # Map for test mode lookups
+        self.replays = {}
         self.action_map = {
                 K_UP: UP,
                 K_DOWN: DOWN,
@@ -213,6 +214,22 @@
                     tile_button.add_callback('clicked', self.sprite_tool,
                             name, None, None)
                     tool_list.append(tile_button)
+            elif self.mode == 'Test':
+                for replay in [1, 2]:
+                    store_button = TextButton((0, 0),
+                            'Store run as %s' % replay)
+                    store_button.add_callback('clicked', self.store_replay,
+                            replay)
+                    tool_list.append(store_button)
+                    replay_button = TextButton((0, 0),
+                            'Replay run %s' % replay)
+                    replay_button.add_callback('clicked', self.do_replay,
+                            replay)
+                    tool_list.append(replay_button)
+                last_button = TextButton((0, 0),
+                        'Replay last run')
+                last_button.add_callback('clicked', self.do_replay, None)
+                tool_list.append(last_button)
             self.tool_widget = ToolListWidget((button_left, button_height),
                     tool_list, MAX_TOOLS, start_key=K_2)
             self.toolbar[self.mode] = self.tool_widget
@@ -396,6 +413,7 @@
         self.edit_widget = EditLevelWidget(self.level)
         self.edit_widget.add_callback(SnakeDiedEvent, self.halt_test)
         self.edit_widget.add_callback(LevelCompletedEvent, self.halt_test)
+        self.replays = {}
         self.container.add(self.edit_widget)
         self.clear_toolbar()
         self.setup_toolbar()
@@ -546,3 +564,17 @@
             self.level.replace_sprite(sprite)
         self.level.restart()
         return True
+
+    def store_replay(self, ev, widget, number):
+        self.replays[number] = self.edit_widget.get_replay()
+
+    def do_replay(self, ev, widget, number):
+        if number:
+            # We do nothing if the user tries to replay something thay
+            # isn't there
+            if number in self.replays:
+                # Replay stored replay
+                self.edit_widget.replay(self.replays[number])
+        else:
+            # Replaying last run
+            self.edit_widget.replay()
--- a/mamba/widgets/level.py	Fri Sep 23 22:17:46 2011 +0200
+++ b/mamba/widgets/level.py	Thu Sep 22 17:32:38 2011 +0200
@@ -5,7 +5,7 @@
 from mamba.widgets.base import Widget
 from mamba.constants import TILE_SIZE
 from mamba.snake import Snake
-from mamba.engine import FlipArrowsEvent
+from mamba.engine import FlipArrowsEvent, ReplayEvent
 
 
 class EditLevelWidget(Widget):
@@ -22,11 +22,34 @@
         self.add_callback(MOUSEBUTTONUP, self.end_draw)
         self.add_callback(MOUSEMOTION, self.draw_tiles)
         self.add_callback(FlipArrowsEvent, self.flip_arrows)
+        self.add_callback(ReplayEvent, self.handle_replay)
         self.snake = None
         self.snake_alive = False
+        self.replay_data = []
+        self.last_run = []
+        self.replay_pos = 0
+
+    def get_replay(self):
+        return self.replay_data[:]
+
+    def replay(self, run=None):
+        if run is None:
+            # We exclude the last couple of steps, so we don't redo
+            # the final crash in this run
+            run = self.last_run[:-4]
+        if len(run) > 0:
+            self.start_test()
+            ReplayEvent.post(run, 0)
+
+    def handle_replay(self, ev, widget):
+        self.apply_action(ev.run[ev.replay_pos])
+        if ev.replay_pos < len(ev.run) - 1:
+            ReplayEvent.post(ev.run, ev.replay_pos + 1)
 
     def start_test(self):
         self.level.update_tiles_ascii()
+        self.last_run = self.replay_data
+        self.replay_data = []
         self.level.restart()
         tile_pos, orientation = self.level.get_entry()
         self.snake = Snake(tile_pos, orientation)
@@ -62,6 +85,7 @@
         return self.level.extra_sprites[sprite_id]
 
     def apply_action(self, orientation):
+        self.replay_data.append(orientation)
         if not self.snake or not self.snake_alive:
             return
         # We choose numbers that are close to, but not exactly, move 0.5 tiles