[gnome-games/glchess-vala] Check FEN state is valid after move
- From: Robert Ancell <rancell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games/glchess-vala] Check FEN state is valid after move
- Date: Tue, 28 Dec 2010 04:38:21 +0000 (UTC)
commit ab6ac4b95abf773fb09e22b26034746430ee8871
Author: Robert Ancell <robert ancell canonical com>
Date: Tue Dec 28 15:38:09 2010 +1100
Check FEN state is valid after move
glchess/src/chess-game.vala | 117 ++++++++++++++++++++++++++++++++++---
glchess/src/test-chess-game.vala | 28 ++++++---
2 files changed, 126 insertions(+), 19 deletions(-)
---
diff --git a/glchess/src/chess-game.vala b/glchess/src/chess-game.vala
index 5bcbc8d..d7408c6 100644
--- a/glchess/src/chess-game.vala
+++ b/glchess/src/chess-game.vala
@@ -58,6 +58,38 @@ public class ChessPiece
public signal void promoted ();
public signal void died ();
+ public unichar symbol
+ {
+ get
+ {
+ unichar c = ' ';
+ switch (type)
+ {
+ case PieceType.PAWN:
+ c = 'p';
+ break;
+ case PieceType.ROOK:
+ c = 'r';
+ break;
+ case PieceType.KNIGHT:
+ c = 'k';
+ break;
+ case PieceType.BISHOP:
+ c = 'b';
+ break;
+ case PieceType.QUEEN:
+ c = 'q';
+ break;
+ case PieceType.KING:
+ c = 'k';
+ break;
+ }
+ if (player.color == Color.WHITE)
+ c = c.toupper ();
+ return c;
+ }
+ }
+
public ChessPiece (ChessPlayer player, PieceType type)
{
this.player = player;
@@ -122,24 +154,24 @@ public class ChessState
public int en_passant_index = -1;
public bool in_check;
- public ChessPiece[] board;
+ public ChessPiece board[64];
public ChessMove? last_move = null;
/* Bitmap of all the pieces */
private int64 piece_masks[2];
- public ChessState (string? state = null)
+ private ChessState.empty ()
+ {
+ }
+
+ public ChessState (string fen)
{
players[Color.WHITE] = new ChessPlayer (Color.WHITE);
players[Color.BLACK] = new ChessPlayer (Color.BLACK);
- board = new ChessPiece[64];
for (int i = 0; i < 64; i++)
board[i] = null;
- if (state == null)
- return;
-
- string[] fields = state.split (" ");
+ string[] fields = fen.split (" ");
//if (fields.length != 6)
// throw new Error ("Invalid FEN string");
@@ -221,7 +253,7 @@ public class ChessState
public ChessState copy ()
{
- ChessState state = new ChessState ();
+ ChessState state = new ChessState.empty ();
state.number = number;
state.players[Color.WHITE] = players[Color.WHITE];
@@ -243,6 +275,71 @@ public class ChessState
return state;
}
+ public string get_fen ()
+ {
+ var value = new StringBuilder ();
+
+ for (int rank = 7; rank >= 0; rank--)
+ {
+ int skip_count = 0;
+ for (int file = 0; file < 8; file++)
+ {
+ ChessPiece? p = board[get_index (rank, file)];
+ if (p == null)
+ skip_count++;
+ else
+ {
+ if (skip_count > 0)
+ {
+ value.append_printf ("%d", skip_count);
+ skip_count = 0;
+ }
+ value.append_printf ("%c", (int) p.symbol);
+ }
+ }
+ if (skip_count > 0)
+ value.append_printf ("%d", skip_count);
+ if (rank != 0)
+ value.append_c ('/');
+ }
+
+ value.append_c (' ');
+ if (current_player.color == Color.WHITE)
+ value.append_c ('w');
+ else
+ value.append_c ('b');
+
+ value.append_c (' ');
+ if (can_castle_kingside[Color.WHITE])
+ value.append_c ('K');
+ if (can_castle_queenside[Color.WHITE])
+ value.append_c ('Q');
+ if (can_castle_kingside[Color.BLACK])
+ value.append_c ('k');
+ if (can_castle_queenside[Color.BLACK])
+ value.append_c ('q');
+ if (!(can_castle_kingside[Color.WHITE] | can_castle_queenside[Color.WHITE] | can_castle_kingside[Color.BLACK] | can_castle_queenside[Color.BLACK]))
+ value.append_c ('-');
+
+ value.append_c (' ');
+ if (en_passant_index >= 0)
+ value.append_printf ("%c%d", 'a' + get_file (en_passant_index), get_rank (en_passant_index) + 1);
+ else
+ value.append_c ('-');
+
+ // FIXME: Halfmove count
+ value.append_c (' ');
+ value.append_c ('0');
+
+ value.append_c (' ');
+ if (current_player.color == Color.WHITE)
+ value.append_printf ("%d", number / 2);
+ else
+ value.append_printf ("%d", number / 2 + 1);
+
+ return value.str;
+ }
+
public int get_index (int rank, int file)
{
return rank * 8 + file;
@@ -712,10 +809,10 @@ public class ChessGame
get { return move_stack.data.current_player; }
}
- public ChessGame (string state = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")
+ public ChessGame (string fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")
{
is_started = false;
- move_stack.prepend (new ChessState (state));
+ move_stack.prepend (new ChessState (fen));
result = ChessResult.IN_PROGRESS;
white.do_move.connect (move_cb);
diff --git a/glchess/src/test-chess-game.vala b/glchess/src/test-chess-game.vala
index 0d969f0..b11df85 100644
--- a/glchess/src/test-chess-game.vala
+++ b/glchess/src/test-chess-game.vala
@@ -3,50 +3,60 @@ class GlChess
static int test_count = 0;
static int failure_count = 0;
- private static void test_good_move (string fen, string move)
+ private static void test_good_move (string fen, string move, string result_fen)
{
ChessState state = new ChessState (fen);
- if (!state.move (move, false))
+ test_count++;
+ if (!state.move (move))
{
stderr.printf ("Not allowed to do valid move: %s : %s\n", fen, move);
failure_count++;
}
- test_count++;
+ else if (state.get_fen () != result_fen)
+ {
+ stderr.printf ("Move led to invalid result: %s : %s -> %s, not %s\n", fen, move, state.get_fen (), result_fen);
+ failure_count++;
+ }
}
private static void test_bad_move (string fen, string move)
{
ChessState state = new ChessState (fen);
+ test_count++;
if (state.move (move, false))
{
stderr.printf ("Allowed to do invalid move: %s : %s\n", fen, move);
failure_count++;
}
- test_count++;
}
public static int main (string[] args)
{
/* Pawn move */
- test_good_move ("8/8/8/8/8/8/P7/8 w - - 0 1", "a2a3");
+ test_good_move ("8/8/8/8/8/8/P7/8 w - - 0 1", "a2a3",
+ "8/8/8/8/8/P7/8/8 b - - 0 1");
/* Pawn march */
- test_good_move ("8/8/8/8/8/8/P7/8 w - - 0 1", "a2a4");
+ test_good_move ("8/8/8/8/8/8/P7/8 w - - 0 1", "a2a4",
+ "8/8/8/8/P7/8/8/8 b - a3 0 1");
/* Pawn march only allowed from baseline */
test_bad_move ("8/8/8/8/8/P7/8/8 w - - 0 1", "a2a5");
/* En passant */
- test_good_move ("8/8/8/pP6/8/8/8/8 w - a6 0 1", "b5a6");
+ test_good_move ("8/8/8/pP6/8/8/8/8 w - a6 0 1", "b5a6",
+ "8/8/P7/8/8/8/8/8 b - - 0 1");
/* Can't en passant if wasn't allowed */
test_bad_move ("8/8/8/pP6/8/8/8/8 w - - 0 1", "b5a6");
/* Castle kingside */
- test_good_move ("8/8/8/8/8/8/8/4K2R w K - 0 1", "O-O");
+ test_good_move ("8/8/8/8/8/8/8/4K2R w K - 0 1", "O-O",
+ "8/8/8/8/8/8/8/5RK1 b - - 0 1");
/* Castle queenside */
- test_good_move ("8/8/8/8/8/8/8/R3K3 w Q - 0 1", "O-O-O");
+ test_good_move ("8/8/8/8/8/8/8/R3K3 w Q - 0 1", "O-O-O",
+ "8/8/8/8/8/8/8/2KR4 b - - 0 1");
/* Can't castle if pieces moved */
test_bad_move ("8/8/8/8/8/8/8/4K2R w - - 0 1", "O-O");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]