[gnome-games/sudoku-vala] sudoku: Add undo/redo functionality
- From: Robert Ancell <rancell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games/sudoku-vala] sudoku: Add undo/redo functionality
- Date: Mon, 19 Dec 2011 10:45:55 +0000 (UTC)
commit e47dd9802fc8fb295992c51b34ff1203f7db6ebb
Author: LubomÃr SedlÃÅ <lubomir sedlar gmail com>
Date: Mon Aug 8 21:13:56 2011 +0200
sudoku: Add undo/redo functionality
gnome-sudoku/src/sudoku-game.vala | 73 ++++++++++++++++++++++++++++++++++---
1 files changed, 68 insertions(+), 5 deletions(-)
---
diff --git a/gnome-sudoku/src/sudoku-game.vala b/gnome-sudoku/src/sudoku-game.vala
index f8eb15b..fe4709d 100644
--- a/gnome-sudoku/src/sudoku-game.vala
+++ b/gnome-sudoku/src/sudoku-game.vala
@@ -31,6 +31,7 @@ public class SudokuCell
return;
if (_value == value)
return;
+ before_value_changed ();
_value = value;
value_changed ();
}
@@ -49,6 +50,7 @@ public class SudokuCell
}
public signal void value_changed ();
+ public signal void before_value_changed ();
public SudokuCell (int row, int col)
{
@@ -62,18 +64,31 @@ public class SudokuCell
public class SudokuGame
{
public SudokuCell[,] cells;
+
+ private struct UndoItem
+ {
+ public int row;
+ public int col;
+ public int val;
+ }
+
+ private SList<UndoItem?> undostack;
+ private SList<UndoItem?> redostack;
public signal void cell_changed (SudokuCell cell);
public SudokuGame ()
{
cells = new SudokuCell[9,9];
+ undostack = null;
+ redostack = null;
for (int row = 0; row < 9; row++)
for (int col = 0; col < 9; col++)
{
var cell = new SudokuCell (row, col);
cells[row, col] = cell;
cell.value_changed.connect (cell_changed_cb);
+ cell.before_value_changed.connect (update_undo);
}
}
@@ -104,27 +119,37 @@ public class SudokuGame
cell.value = digit;
cell.is_fixed = is_fixed;
}
+
+ /* No undo for preset cells */
+ undostack = null;
+ redostack = null;
}
public void undo ()
{
- stdout.printf ("TODO: undo\n");
+ apply_stack (ref undostack, ref redostack);
}
public void redo ()
{
- stdout.printf ("TODO: redo\n");
+ apply_stack (ref redostack, ref undostack);
}
public void reset ()
{
- for (int i = 0; i < 9; i++) {
- for (int j = 0; j < 9; j++) {
- if ( ! cells[i,j].is_fixed) {
+ int num = 0;
+ for (int i = 0; i < 9; i++)
+ {
+ for (int j = 0; j < 9; j++)
+ {
+ if (!cells[i,j].is_fixed && cells[i,j].value != 0)
+ {
cells[i,j].value = 0;
+ num++;
}
}
}
+ add_to_stack (ref undostack, -1, -1, num);
}
private void cell_changed_cb (SudokuCell cell)
@@ -150,4 +175,42 @@ public class SudokuGame
cell_changed (cell);
}
+
+ private void update_undo (SudokuCell cell)
+ {
+ add_to_stack (ref undostack, cell.row, cell.col, cell.value);
+ redostack = null;
+ }
+
+ private void add_to_stack (ref SList<UndoItem?> stack, int r, int c, int v)
+ {
+ UndoItem step = { r, c, v };
+ stack.prepend (step);
+ }
+
+ private void apply_stack (ref SList<UndoItem?> from, ref SList<UndoItem?> to)
+ {
+ if (from == null) return;
+
+ /* Undoing change of single cell */
+ if (from.data.row >= 0 && from.data.col >= 0)
+ {
+ var cell = cells[from.data.row, from.data.col];
+
+ cell.before_value_changed.disconnect (update_undo);
+ add_to_stack (ref to, from.data.row, from.data.col, cell.value);
+ cell.value = from.data.val;
+ from.remove (from.data);
+ cell.before_value_changed.connect (update_undo);
+ }
+ /* Undoing reset action */
+ else
+ {
+ int num = from.data.val;
+ from.remove (from.data);
+ for (int i = 0; i < num; i++)
+ apply_stack (ref from, ref to);
+ add_to_stack (ref to, -1, -1, num);
+ }
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]