[iagno] Faster history.
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [iagno] Faster history.
- Date: Wed, 24 Sep 2014 13:38:39 +0000 (UTC)
commit 85c758be425bf2fb239808208b93eb1e8bca8643
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date: Tue Sep 23 21:57:26 2014 +0200
Faster history.
https://bugzilla.gnome.org/show_bug.cgi?id=736934
src/game.vala | 129 ++++++++++++++++++++++++++++++---------------------------
1 files changed, 68 insertions(+), 61 deletions(-)
---
diff --git a/src/game.vala b/src/game.vala
index 927b813..b67231e 100644
--- a/src/game.vala
+++ b/src/game.vala
@@ -21,13 +21,14 @@ public class Game : Object
private set { _size = value; }
}
- /* undoing */
- private UndoItem? state = null;
- private UndoItem? previous_state = null;
- private int number_of_moves = 0;
+ /* Undoing */
+ private int?[] undo_stack;
+ private int history_index = -1;
- /* Color to move next */
- public Player current_color { get; private set; }
+ /* Color to move next; Dark always plays first;
+ * should be dark if number_of_moves % 2 == 0 */
+ public Player current_color { get; private set; default = Player.DARK; }
+ private int number_of_moves = 0;
/* Indicate that a player should move */
public signal void move ();
@@ -45,13 +46,13 @@ public class Game : Object
get { return n_dark_tiles + n_light_tiles; }
}
- private int _n_light_tiles = 0;
+ private int _n_light_tiles = 2;
public int n_light_tiles
{
get { return _n_light_tiles; }
}
- private int _n_dark_tiles = 0;
+ private int _n_dark_tiles = 2;
public int n_dark_tiles
{
get { return _n_dark_tiles; }
@@ -93,16 +94,16 @@ public class Game : Object
for (var y = 0; y < size; y++)
tiles[x, y] = Player.NONE;
- /* Dark plays first */
- current_color = Player.DARK;
+ /* Stack is oversized: there is 60 turns, each adds one piece,
+ * there's place for the end of turn and the opponent passing,
+ * and you could flip max ((size - 2) * 3) tiles in one turn. */
+ undo_stack = new int?[180 * (size - 1)]; /* (3 + (size - 2) * 3) * 60 */
/* Setup board with four tiles by default */
- set_tile (size / 2 - 1, size / 2 - 1, Player.LIGHT, false);
- set_tile (size / 2 - 1, size / 2, Player.DARK, false);
- set_tile (size / 2, size / 2 - 1, Player.DARK, false);
- set_tile (size / 2, size / 2, Player.LIGHT, false);
- n_current_tiles = 2;
- n_opponent_tiles = 2;
+ tiles [size / 2 - 1, size / 2 - 1] = Player.LIGHT;
+ tiles [size / 2 - 1, size / 2] = Player.DARK;
+ tiles [size / 2, size / 2 - 1] = Player.DARK;
+ tiles [size / 2, size / 2] = Player.LIGHT;
}
public Game.from_strings (string[] setup, Player to_move, int tmp_size = 8)
@@ -111,6 +112,7 @@ public class Game : Object
{
size = tmp_size;
tiles = new Player[size, size];
+ undo_stack = new int?[180 * (size - 1)];
for (int y = 0; y < size; y++)
{
@@ -143,6 +145,7 @@ public class Game : Object
{
size = game.size;
tiles = new Player[size, size];
+ undo_stack = new int?[180 * (size - 1)];
for (var x = 0; x < size; x++)
for (var y = 0; y < size; y++)
tiles[x, y] = game.tiles[x, y];
@@ -150,7 +153,7 @@ public class Game : Object
current_color = game.current_color;
n_current_tiles = game.n_current_tiles;
n_opponent_tiles = game.n_opponent_tiles;
- /* don't copy history */
+ /* warning: history not copied */
}
/*\
@@ -207,7 +210,7 @@ public class Game : Object
}
/*\
- * * Public actions (apart undo)
+ * * Actions (apart undo)
\*/
public int place_tile (int x, int y)
@@ -229,9 +232,8 @@ public class Game : Object
if (tiles_turned == 0)
return 0;
- set_tile (x, y, current_color, true);
- number_of_moves++;
- current_color = Player.flip_color (current_color);
+ set_tile (x, y, current_color);
+ end_of_turn ();
if (is_complete ())
complete ();
@@ -244,11 +246,20 @@ public class Game : Object
public void pass ()
requires (!can_move (current_color))
{
- number_of_moves++;
- current_color = Player.flip_color (current_color);
+ end_of_turn ();
+
move ();
}
+ private void end_of_turn ()
+ requires (history_index >= -1 && history_index < undo_stack.length - 2)
+ {
+ current_color = Player.flip_color (current_color);
+ number_of_moves++;
+ history_index++;
+ undo_stack[history_index] = null;
+ }
+
/*\
* * Flipping tiles
\*/
@@ -274,27 +285,21 @@ public class Game : Object
/* Flip the enemy's tiles */
if (apply)
for (var i = 1; i <= enemy_count; i++)
- set_tile (x + i * x_step, y + i * y_step, color, true);
+ {
+ n_opponent_tiles--;
+ /* TODO set_tile() always sets to current_color... */
+ set_tile (x + i * x_step, y + i * y_step, color);
+ }
return enemy_count;
}
- private void set_tile (int x, int y, Player color, bool update_history)
+ private void set_tile (int x, int y, Player color)
+ requires (history_index >= -1 && history_index < undo_stack.length - 2)
{
- if (update_history)
- {
- add_move (x, y, tiles[x, y]);
- n_current_tiles++;
- if (tiles[x, y] != Player.NONE)
- n_opponent_tiles--;
- }
- else
- {
- n_current_tiles--;
- if (color != Player.NONE)
- n_opponent_tiles++;
- }
-
+ n_current_tiles++;
+ history_index++;
+ undo_stack[history_index] = x + y * size;
tiles[x, y] = color;
square_changed (x, y);
}
@@ -303,16 +308,6 @@ public class Game : Object
* * Undo
\*/
- private struct UndoItem
- {
- public int number;
- public int x;
- public int y;
- public Player color;
- public weak UndoItem? next;
- public UndoItem? previous;
- }
-
public bool can_undo (int count = 1)
requires (count == 1 || count == 2)
{
@@ -322,26 +317,38 @@ public class Game : Object
public void undo (int count = 1)
requires (count == 1 || count == 2)
requires (number_of_moves >= count)
+ requires (history_index < undo_stack.length)
{
+ var enemy = current_color;
current_color = Player.flip_color (current_color);
- while (state != null && state.number == number_of_moves - 1)
- {
- set_tile (state.x, state.y, state.color, false);
-
- state = previous_state;
- previous_state = state == null ? null : state.previous;
- };
number_of_moves--;
+ /* pass the end of turn mark of the history */
+ history_index--;
+
+ /* if not pass */
+ if (undo_stack[history_index] != null)
+ {
+ /* last log entry is the placed tile, previous are flipped tiles */
+ unset_tile (undo_stack[history_index], Player.NONE);
+ while (history_index > -1 && undo_stack[history_index] != null)
+ {
+ n_opponent_tiles++;
+ unset_tile (undo_stack[history_index], enemy);
+ }
+ }
+
if (count == 2)
undo (1);
}
- private void add_move (int x, int y, Player color)
+ private void unset_tile (int tile_number, Player replacement_color)
{
- previous_state = state == null ? null : state;
- state = UndoItem () { number = number_of_moves, x = x, y = y, color = color, next = null, previous =
previous_state };
- if (previous_state != null)
- previous_state.next = state;
+ n_current_tiles--;
+ history_index--;
+ var x = tile_number % size;
+ var y = tile_number / size;
+ tiles [x, y] = replacement_color;
+ square_changed (x, y);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]