Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Lee <joe@jotaro.com>2008-04-02 04:16:28 (GMT)
committer Joe Lee <joe@jotaro.com>2008-04-02 04:16:28 (GMT)
commit260aca2de2aa743f7fcf2a150f1fb8b9d02fc0ea (patch)
treefa412abe194947f7228211e3c11eef1658db4d6d
parent26cd1b9ec3da1186a2c6157c128cf19851b97099 (diff)
Added Journal suspend/resume.
-rw-r--r--NEWS8
-rw-r--r--gridwidget.py13
-rw-r--r--implodeactivity.py33
-rw-r--r--implodegame.py42
4 files changed, 90 insertions, 6 deletions
diff --git a/NEWS b/NEWS
index bab21e7..9a7c677 100644
--- a/NEWS
+++ b/NEWS
@@ -24,11 +24,11 @@
- Fixed ticket #5737: Implode smiley face draws over new game.
- Added initial gamepad/keyboard support.
+2008/04/01
+
+ - Added Journal suspend/resume.
+
TODO:
-- The activity needs to save/restore the current game on exit/restart (maybe
- using the Journal?).
-- Maybe include a way to regenerate earlier games or games from another
- laptop?
- The game could detect a loss and display a "Try again" graphic?
- Rectangle invalidation could be improved.
- A tutorial mode or sequence of introductory games might help.
diff --git a/gridwidget.py b/gridwidget.py
index e237524..d6d7eb9 100644
--- a/gridwidget.py
+++ b/gridwidget.py
@@ -194,6 +194,19 @@ class GridWidget(gtk.DrawingArea):
self._win_draw_flag = value
self._invalidate_board()
+ def get_win_draw_flag(self):
+ return self._win_draw_flag
+
+ def get_win_color(self):
+ return self._win_color
+
+ def set_win_state(self, draw_flag, win_color):
+ self._win_draw_flag = draw_flag
+ if draw_flag:
+ self._recalc_win_animation_frames()
+ self._win_color = win_color
+ self._invalidate_board()
+
def get_animation_length(self):
if self._animation_mode == ANIMATE_NONE:
return 0.0
diff --git a/implodeactivity.py b/implodeactivity.py
index 5b76b74..2141309 100644
--- a/implodeactivity.py
+++ b/implodeactivity.py
@@ -27,7 +27,8 @@ from sugar.graphics.radiotoolbutton import RadioToolButton
import implodegame
-#import sys, os
+import os
+import json
import gtk
import gobject
@@ -69,6 +70,35 @@ class ImplodeActivity(Activity):
self.show_all()
self._game.grab_focus()
+ last_game_path = self._get_last_game_path()
+ if os.path.exists(last_game_path):
+ self.read_file(last_game_path)
+
+ def _get_last_game_path(self):
+ return os.path.join(self.get_activity_root(), 'data', 'last_game')
+
+ def read_file(self, file_path):
+ # Loads the game state from a file.
+ f = file(file_path, 'rt')
+ file_data = json.read(f.read())
+ f.close()
+ print file_data
+ _logger.debug(file_data)
+ (file_type, version, game_data) = file_data
+ if file_type == 'Implode save game' and version <= [1, 0]:
+ self._game.set_game_state(game_data)
+
+ def write_file(self, file_path):
+ # Writes the game state to a file.
+ game_data = self._game.get_game_state()
+ file_data = ['Implode save game', [1, 0], game_data]
+ content = json.write(file_data)
+ last_game_path = self._get_last_game_path()
+ for path in (file_path, last_game_path):
+ f = file(path, 'wt')
+ f.write(content)
+ f.close()
+
class _Toolbox(ActivityToolbox):
__gsignals__ = {
'new-game-clicked' : (gobject.SIGNAL_RUN_LAST, None, ()),
@@ -124,4 +154,3 @@ class _Toolbox(ActivityToolbox):
self.add_toolbar(_("Game"), toolbar)
self.set_current_toolbar(1)
-
diff --git a/implodegame.py b/implodegame.py
index 93409db..17496f0 100644
--- a/implodegame.py
+++ b/implodegame.py
@@ -129,6 +129,48 @@ class ImplodeGame(gtk.EventBox):
def set_level(self, level):
self._difficulty = level
+ def get_game_state(self):
+ # Returns a dictionary containing the game state, in atomic subobjects.
+ def encode_board(b):
+ (w, h) = (b.width, b.height)
+ data = []
+ for i in range(h):
+ for j in range(w):
+ data.append(b.get_value(j, i))
+ return [w, h] + data
+ return {
+ 'difficulty' : self._difficulty,
+ 'seed' : self._seed,
+ 'size' : self._size,
+ 'fragmentation' : self._fragmentation,
+ 'board' : encode_board(self._board),
+ 'undo_stack': [encode_board(b) for b in self._undoStack],
+ 'redo_stack': [encode_board(b) for b in self._redoStack],
+ 'win_draw_flag': self._grid.get_win_draw_flag(),
+ 'win_color': self._grid.get_win_color(),
+ }
+
+ def set_game_state(self, state):
+ # Sets the game state using a dictionary of atomic subobjects.
+ self._finish_animation()
+ def decode_board(state):
+ b = board.Board()
+ (w, h) = (state[0], state[1])
+ data = state[2:]
+ for i in range(h):
+ for j in range(w):
+ b.set_value(j, i, data.pop(0))
+ return b
+ self._difficulty = state['difficulty']
+ self._seed = state['seed']
+ self._size = state['size']
+ self._fragmentation = state['fragmentation']
+ self._board = decode_board(state['board'])
+ self._undoStack = [decode_board(x) for x in state['undo_stack']]
+ self._redoStack = [decode_board(x) for x in state['redo_stack']]
+ self._grid.set_board(self._board)
+ self._grid.set_win_state(state['win_draw_flag'], state['win_color'])
+
def _reset_board(self):
# Regenerates the board with the current seed.
self._board = boardgen.generate_board(seed=self._seed,