diff mamba/widgets/level.py @ 555:c014f5023cd2

Test run replays
author Neil Muller <drnlmuller@gmail.com>
date Thu, 22 Sep 2011 17:32:38 +0200
parents b308ebaa96f3
children 03c0f1f5488c
line wrap: on
line diff
--- 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