changeset 444:feb9b7a23ef2

Support for saving and loading games (toolbar entries commented out for lack of space).
author Simon Cross <hodgestar@gmail.com>
date Sat, 21 Nov 2009 19:08:22 +0000
parents 4efe57fcc1d7
children af2482444945
files gamelib/gameboard.py gamelib/toolbar.py
diffstat 2 files changed, 60 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/gamelib/gameboard.py	Sat Nov 21 18:59:23 2009 +0000
+++ b/gamelib/gameboard.py	Sat Nov 21 19:08:22 2009 +0000
@@ -15,8 +15,8 @@
 import cursors
 import sprite_cursor
 import misc
-import engine
 import toolbar
+import serializer
 
 class VidWidget(gui.Widget):
     def __init__(self, gameboard, vid, **params):
@@ -40,13 +40,25 @@
         elif e.type == MOUSEMOTION and self.gameboard.sprite_cursor:
             self.gameboard.update_sprite_cursor(e)
 
-class GameBoard(object):
+class GameBoard(serializer.Simplifiable):
 
     GRASSLAND = tiles.REVERSE_TILE_MAP['grassland']
     FENCE = tiles.REVERSE_TILE_MAP['fence']
     WOODLAND = tiles.REVERSE_TILE_MAP['woodland']
     BROKEN_FENCE = tiles.REVERSE_TILE_MAP['broken fence']
 
+    SIMPLIFY = [
+        'chickens',
+        'buildings',
+        'foxes',
+        'cash',
+        'wood',
+        'eggs',
+        'days',
+        'killed_foxes',
+        'day', 'night',
+    ]
+
     def __init__(self, main_app, level):
         self.disp = main_app
         self.level = level
@@ -62,7 +74,7 @@
         self.sprite_cursor = None
         self.chickens = set()
         self.foxes = set()
-        self.buildings = []
+        self.buildings = set()
         self._pos_cache = { 'fox' : [], 'chicken' : []}
         self.cash = 0
         self.wood = 0
@@ -568,6 +580,10 @@
         for chicken in self.chickens.copy():
             self.remove_chicken(chicken)
 
+    def clear_buildings(self):
+        for building in self.buildings.copy():
+            self.remove_building(building)
+
     def do_night_step(self):
         """Handle the events of the night.
 
@@ -657,7 +673,7 @@
         self.tv.sprites.append(fox)
 
     def add_building(self, building):
-        self.buildings.append(building)
+        self.buildings.add(building)
         self.tv.sprites.append(building, layer='buildings')
 
     def place_hatched_chicken(self, new_chick, building):
@@ -707,7 +723,7 @@
 
     def remove_building(self, building):
         if building in self.buildings:
-            self.buildings.remove(building)
+            self.buildings.discard(building)
             self.tv.sprites.remove(building, layer='buildings')
 
     def add_cash(self, amount):
@@ -795,6 +811,27 @@
         width, height = self.tv.size
         return len([(x,y) for x in range(width) for y in range(height) if self.tv.get((x,y)) == self.WOODLAND])
 
+    def save_game(self):
+        return serializer.simplify(self)
+
+    def restore_game(self, data):
+        if 'refid' not in data or 'class' not in data or data['class'] != self.__class__.__name__:
+            import pprint
+            pprint.pprint(data)
+            print self.__class__.__name__
+            raise ValueError("Invalid save game.")
+        newself = serializer.unsimplify(data)
+        self.clear_chickens()
+        self.clear_buildings()
+        for chicken in newself.chickens:
+            self.add_chicken(chicken)
+        for building in newself.buildings:
+            self.add_building(building)
+        for attr in self.SIMPLIFY:
+            if attr in ('chickens', 'buildings'):
+                continue
+            setattr(self, attr, getattr(newself, attr))
+
 
 class TextDialog(gui.Dialog):
     def __init__(self, title, text, **params):
--- a/gamelib/toolbar.py	Sat Nov 21 18:59:23 2009 +0000
+++ b/gamelib/toolbar.py	Sat Nov 21 19:08:22 2009 +0000
@@ -7,6 +7,10 @@
 import equipment
 import cursors
 import engine
+try:
+    import json
+except ImportError:
+    import simplejson as json
 
 class OpaqueLabel(gui.Label):
     def __init__(self, value, **params):
@@ -107,6 +111,10 @@
         self.add_spacer(5)
         self.add_tool("Price Reference", self.show_prices)
 
+        #self.add_spacer(5)
+        #self.add_tool("Save Game", self.save_game)
+        #self.add_tool("Load Game", self.load_game)
+
         self.fin_tool = self.add_tool("Finished Day", self.day_done)
 
     def day_done(self):
@@ -196,6 +204,16 @@
         close_button.connect(gui.CLICK, dialog.close)
         dialog.open()
 
+    def save_game(self):
+        """Save game 'dialog'."""
+        data = self.gameboard.save_game()
+        open("foxassault.json", "wb").write(json.dumps(data))
+
+    def load_game(self):
+        """Load game 'dialog'."""
+        data = json.loads(open("foxassault.json", "rb").read())
+        self.gameboard.restore_game(data)
+
     update_cash_counter = mkcountupdate('cash_counter')
     update_wood_counter = mkcountupdate('wood_counter')
     update_fox_counter = mkcountupdate('killed_foxes')