[gnome-games] chess: Start to get undo to work again
- From: Robert Ancell <rancell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games] chess: Start to get undo to work again
- Date: Tue, 25 Jan 2011 12:10:31 +0000 (UTC)
commit cdcc65b7c49148777a498fdcd81261ec4b94a125
Author: Robert Ancell <robert ancell canonical com>
Date: Tue Jan 25 21:44:15 2011 +1000
chess: Start to get undo to work again
glchess/src/chess-engine-cecp.vala | 7 +++-
glchess/src/chess-engine-uci.vala | 19 ++++++---
glchess/src/chess-engine.vala | 4 ++
glchess/src/chess-game.vala | 31 +++++++++++++++
glchess/src/glchess.vala | 76 +++++++++++++++++++++++++++---------
glchess/src/history.vala | 10 +++++
6 files changed, 121 insertions(+), 26 deletions(-)
---
diff --git a/glchess/src/chess-engine-cecp.vala b/glchess/src/chess-engine-cecp.vala
index a5008c7..cb40419 100644
--- a/glchess/src/chess-engine-cecp.vala
+++ b/glchess/src/chess-engine-cecp.vala
@@ -69,7 +69,7 @@ public class ChessEngineCECP : ChessEngine
public override void start_game ()
{
}
-
+
public override void request_move ()
{
write_line ("go");
@@ -86,4 +86,9 @@ public class ChessEngineCECP : ChessEngine
}
moving = false;
}
+
+ public override void undo ()
+ {
+ write_line ("undo");
+ }
}
diff --git a/glchess/src/chess-engine-uci.vala b/glchess/src/chess-engine-uci.vala
index 842cd5f..a7a9c02 100644
--- a/glchess/src/chess-engine-uci.vala
+++ b/glchess/src/chess-engine-uci.vala
@@ -1,14 +1,14 @@
public class ChessEngineUCI : ChessEngine
{
private char[] buffer;
- private string position_command;
+ private string moves;
private string[] options;
public ChessEngineUCI (string[] options)
{
this.options = options;
buffer = new char[0];
- position_command = "position startpos";
+ moves = "";
starting.connect (start_cb);
}
@@ -24,15 +24,22 @@ public class ChessEngineUCI : ChessEngine
public override void request_move ()
{
+ if (moves != "")
+ write_line ("position startpos moves" + moves);
+ else
+ write_line ("position startpos");
write_line ("go wtime 30000 btime 30000");
}
public override void report_move (ChessMove move)
{
- if (position_command == "position startpos")
- position_command += " moves";
- position_command += " " + move.get_engine ();
- write_line (position_command);
+ moves += " " + move.get_engine ();
+ }
+
+ public override void undo ()
+ {
+ write_line ("stop");
+ moves = moves.slice (0, moves.last_index_of (" "));
}
public override void process_input (char[] data)
diff --git a/glchess/src/chess-engine.vala b/glchess/src/chess-engine.vala
index ece5e4a..fe12607 100644
--- a/glchess/src/chess-engine.vala
+++ b/glchess/src/chess-engine.vala
@@ -73,6 +73,10 @@ public class ChessEngine : Object
{
}
+ public virtual void undo ()
+ {
+ }
+
public void stop ()
{
// FIXME
diff --git a/glchess/src/chess-game.vala b/glchess/src/chess-game.vala
index d5ef9c0..44ab141 100644
--- a/glchess/src/chess-game.vala
+++ b/glchess/src/chess-game.vala
@@ -9,6 +9,7 @@ public class ChessPlayer : Object
public Color color;
public signal void start_turn ();
public signal bool do_move (string move, bool apply);
+ public signal void do_undo ();
public signal bool do_resign ();
public signal bool do_claim_draw ();
@@ -28,6 +29,11 @@ public class ChessPlayer : Object
return do_move (move, apply);
}
+ public void undo ()
+ {
+ do_undo ();
+ }
+
public bool resign ()
{
return do_resign ();
@@ -1134,6 +1140,7 @@ public class ChessGame
public signal void started ();
public signal void turn_started (ChessPlayer player);
public signal void moved (ChessMove move);
+ public signal void undo ();
public signal void ended ();
public ChessPlayer white
@@ -1148,6 +1155,10 @@ public class ChessGame
{
get { return move_stack.data.current_player; }
}
+ public ChessPlayer opponent
+ {
+ get { return move_stack.data.opponent; }
+ }
private ChessClock? _clock;
public ChessClock? clock
{
@@ -1176,9 +1187,11 @@ public class ChessGame
}
white.do_move.connect (move_cb);
+ white.do_undo.connect (undo_cb);
white.do_resign.connect (resign_cb);
white.do_claim_draw.connect (claim_draw_cb);
black.do_move.connect (move_cb);
+ black.do_undo.connect (undo_cb);
black.do_resign.connect (resign_cb);
black.do_claim_draw.connect (claim_draw_cb);
}
@@ -1229,6 +1242,24 @@ public class ChessGame
return true;
}
+ private void undo_cb (ChessPlayer player)
+ {
+ /* If this players turn undo their opponents move then their last move */
+ if (player == current_player)
+ {
+ undo_cb (opponent);
+ return;
+ }
+
+ /* Don't pop off starting move */
+ if (move_stack.next == null)
+ return;
+
+ /* Pop off the move state and notify */
+ move_stack.remove_link (move_stack);
+ undo ();
+ }
+
private bool resign_cb (ChessPlayer player)
{
if (!is_started)
diff --git a/glchess/src/glchess.vala b/glchess/src/glchess.vala
index b89b8b9..76cc26d 100644
--- a/glchess/src/glchess.vala
+++ b/glchess/src/glchess.vala
@@ -110,26 +110,39 @@ public class Application
if (save_duration_timeout != 0)
save_duration_cb ();
- /* Autosave */
- // FIXME: Only once a human has moved
- if (in_history && pgn_game.moves != null)
+ autosave ();
+ settings.sync ();
+ Gtk.main_quit ();
+ }
+
+ private void autosave ()
+ {
+ /* FIXME: Prompt user to save somewhere */
+ if (!in_history)
+ return;
+
+ /* Don't autosave if no moves (e.g. they have been undone) or only the computer has moved */
+ if (pgn_game.moves == null || (
+ (pgn_game.moves.length () == 1 && opponent != null && opponent.color == Color.WHITE)))
{
- try
- {
- if (game_file != null)
- history.update (game_file, "", pgn_game.result);
- else
- game_file = history.add (pgn_game.date, pgn_game.result);
- pgn_game.write (game_file);
- }
- catch (Error e)
- {
- warning ("Failed to autosave: %s", e.message);
- }
+ if (game_file != null)
+ history.remove (game_file);
+ return;
}
- settings.sync ();
- Gtk.main_quit ();
+ try
+ {
+ if (game_file != null)
+ history.update (game_file, "", pgn_game.result);
+ else
+ game_file = history.add (pgn_game.date, pgn_game.result);
+ debug ("Writing current game to %s", game_file.get_path ());
+ pgn_game.write (game_file);
+ }
+ catch (Error e)
+ {
+ warning ("Failed to autosave: %s", e.message);
+ }
}
private void settings_changed_cb (Settings settings, string key)
@@ -243,6 +256,7 @@ public class Application
game.started.connect (game_start_cb);
game.turn_started.connect (game_turn_cb);
game.moved.connect (game_move_cb);
+ game.undo.connect (game_undo_cb);
game.ended.connect (game_end_cb);
if (game.clock != null)
game.clock.tick.connect (game_clock_tick_cb);
@@ -600,8 +614,8 @@ public class Application
if (move.number > pgn_game.moves.length ())
pgn_game.moves.append (move.get_san ());
- Gtk.TreeIter iter;
var model = (Gtk.ListStore) history_combo.model;
+ Gtk.TreeIter iter;
model.append (out iter);
model.set (iter, 1, move.number, -1);
set_move_text (iter, move);
@@ -619,6 +633,30 @@ public class Application
view.queue_draw ();
}
+ private void game_undo_cb (ChessGame game)
+ {
+ /* Notify AI */
+ if (opponent_engine != null)
+ opponent_engine.undo ();
+
+ /* Remove from the PGN game */
+ pgn_game.moves.remove_link (pgn_game.moves.last ());
+
+ /* Remove from the history */
+ var model = (Gtk.ListStore) history_combo.model;
+ Gtk.TreeIter iter;
+ model.iter_nth_child (out iter, null, model.iter_n_children (null) - 1);
+ model.remove (iter);
+
+ /* If watching this move, go back one */
+ if (view_options.move_number > game.n_moves || view_options.move_number == -1)
+ {
+ model.iter_nth_child (out iter, null, model.iter_n_children (null) - 1);
+ history_combo.set_active_iter (iter);
+ view.queue_draw ();
+ }
+ }
+
private void game_end_cb (ChessGame game)
{
string title = "";
@@ -748,7 +786,7 @@ public class Application
[CCode (cname = "G_MODULE_EXPORT undo_move_cb", instance_pos = -1)]
public void undo_move_cb (Gtk.Widget widget)
{
- warning ("FIXME: Undo last move");
+ game.current_player.undo ();
}
[CCode (cname = "G_MODULE_EXPORT quit_cb", instance_pos = -1)]
diff --git a/glchess/src/history.vala b/glchess/src/history.vala
index e540847..4e8d78b 100644
--- a/glchess/src/history.vala
+++ b/glchess/src/history.vala
@@ -58,6 +58,16 @@ public class History
return file;
}
+ public void remove (File file)
+ {
+ var relative_path = history_dir.get_relative_path (file);
+
+ Sqlite.Statement statement;
+ assert (db.prepare_v2 ("DELETE FROM GameTable WHERE path=\"%s\"".printf (relative_path), -1, out statement) == Sqlite.OK);
+ if (statement.step () != Sqlite.DONE)
+ warning ("Failed to remove game from history index: %s", db.errmsg ());
+ }
+
public void update (File file, string fen, string result)
{
var relative_path = history_dir.get_relative_path (file);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]