Fri, 28 Mar 2014 14:32:52 +0100
introduced status codes for get_location to produce detailed error messages + added knight rules
--- a/src/game.c Fri Mar 28 11:45:01 2014 +0100 +++ b/src/game.c Fri Mar 28 14:32:52 2014 +0100 @@ -147,19 +147,19 @@ result = result && !pawn_isblocked(board, move); break; case ROOK: - result = result && rook_chkrules(board, move); + result = result && rook_chkrules(move); result = result && !rook_isblocked(board, move); break; case KNIGHT: - result = result && knight_chkrules(board, move); + result = result && knight_chkrules(move); result = result && !knight_isblocked(board, move); break; case BISHOP: - result = result && bishop_chkrules(board, move); + result = result && bishop_chkrules(move); result = result && !bishop_isblocked(board, move); break; case QUEEN: - result = result && queen_chkrules(board, move); + result = result && queen_chkrules(move); result = result && !queen_isblocked(board, move); break; case KING: @@ -203,10 +203,9 @@ * * @param board the current state of the board * @param move the move date to operate on - * @return TRUE if the location could be retrieved, FALSE if the location is - * ambiguous + * @return status code (see rules/rules.h for the codes) */ -static _Bool getlocation(Board board, Move *move) { +static int getlocation(Board board, Move *move) { uint8_t piece = move->piece & PIECE_MASK; switch (piece) { case PAWN: return pawn_getlocation(board, move); @@ -215,7 +214,7 @@ case BISHOP: return bishop_getlocation(board, move); case QUEEN: return queen_getlocation(board, move); case KING: return king_getlocation(board, move); - default: return FALSE; + default: return INVALID_MOVE_SYNTAX; } } @@ -227,9 +226,9 @@ * @param mycolor the color of the current player * @param mstr the input string to parse * @param move a pointer to object where the move data shall be stored - * @return TRUE, if the move is syntactically valid, FALSE otherwise + * @return status code (see rules/rules.h for the list of codes) */ -static _Bool eval_move(Board board, uint8_t mycolor, char *mstr, Move *move) { +static int eval_move(Board board, uint8_t mycolor, char *mstr, Move *move) { memset(move, 0, sizeof(Move)); move->fromfile = POS_UNSPECIFIED; move->fromrow = POS_UNSPECIFIED; @@ -331,14 +330,13 @@ move->piece |= mycolor; if (move->fromfile == POS_UNSPECIFIED || move->fromrow == POS_UNSPECIFIED) { - return getlocation(board, move) && chkidx(move); + return getlocation(board, move); } else { - return chkidx(move); + return chkidx(move) ? VALID_MOVE_SYNTAX : INVALID_POSITION; } } else { - return FALSE; + return INVALID_MOVE_SYNTAX; } - // TODO: return status code to indicate the error type } static int sendmove(Board board, uint8_t mycolor, int opponent) { @@ -366,6 +364,7 @@ if (strncmp(movestr, "surr", buflen) == 0) { printw("You surrendered!"); + clrtoeol(); refresh(); net_send_code(opponent, NETCODE_SURRENDER); return 1; @@ -385,28 +384,40 @@ } } else { Move move; - if (eval_move(board, mycolor, movestr, &move)) { - net_send_code(opponent, NETCODE_MOVE); - net_send_data(opponent, &move, sizeof(Move)); - code = net_recieve_code(opponent); - move.check = code == NETCODE_CHECK; - move.checkmate = code == NETCODE_CHECKMATE; - // TODO: record move - if (code == NETCODE_DECLINE) { - printw("Invalid move."); - clrtoeol(); - } else { - apply_move(board, &move); - if (move.checkmate) { - printw("Checkmate!"); - return 1; + int eval_result = eval_move(board, mycolor, movestr, &move); + switch (eval_result) { + case VALID_MOVE_SYNTAX: + net_send_code(opponent, NETCODE_MOVE); + net_send_data(opponent, &move, sizeof(Move)); + code = net_recieve_code(opponent); + move.check = code == NETCODE_CHECK; + move.checkmate = code == NETCODE_CHECKMATE; + // TODO: record move + if (code == NETCODE_DECLINE) { + printw("Invalid move."); } else { - return 0; + apply_move(board, &move); + if (move.checkmate) { + printw("Checkmate!"); + clrtoeol(); + return 1; + } else { + return 0; + } } - } - } else { - printw("Can't interpret move - please use algebraic notation."); + break; + case AMBIGUOUS_MOVE: + printw("Ambiguous move - " + "please specify the piece to move."); + break; + case INVALID_POSITION: + printw("Cannot find the piece that shall be moved."); + break; + default: + printw("Can't interpret move - " + "please use algebraic notation."); } + clrtoeol(); } } }
--- a/src/game.h Fri Mar 28 11:45:01 2014 +0100 +++ b/src/game.h Fri Mar 28 14:32:52 2014 +0100 @@ -78,8 +78,8 @@ } Move; #define POS_UNSPECIFIED UINT8_MAX -#define mdst(b,m) b[m->torow][m->tofile] -#define msrc(b,m) b[m->fromrow][m->fromfile] +#define mdst(b,m) b[(m)->torow][(m)->tofile] +#define msrc(b,m) b[(m)->fromrow][(m)->fromfile] #define isidx(idx) ((uint8_t)idx < 8) @@ -89,8 +89,8 @@ #define rowidx(row) (row-'1') #define fileidx(file) (file-'a') -#define chkidx(move) (isidx(move->fromfile) && isidx(move->fromrow) && \ - isidx(move->tofile) && isidx(move->torow)) +#define chkidx(move) (isidx((move)->fromfile) && isidx((move)->fromrow) && \ + isidx((move)->tofile) && isidx((move)->torow)) /* secure versions - use, if index is not checked with isidx() */ #define fileidx_s(c) (isfile(c)?fileidx(c):POS_UNSPECIFIED)
--- a/src/main.c Fri Mar 28 11:45:01 2014 +0100 +++ b/src/main.c Fri Mar 28 14:32:52 2014 +0100 @@ -159,7 +159,7 @@ "Example: -t 150s\n" ); return EXIT_SUCCESS; - } + } tchess_window = initscr(); cbreak(); if (has_colors()) {
--- a/src/rules/bishop.c Fri Mar 28 11:45:01 2014 +0100 +++ b/src/rules/bishop.c Fri Mar 28 14:32:52 2014 +0100 @@ -28,8 +28,9 @@ */ #include "bishop.h" +#include "rules.h" -_Bool bishop_chkrules(Board board, Move* move) { +_Bool bishop_chkrules(Move* move) { // TODO: implement return FALSE; } @@ -39,7 +40,7 @@ return TRUE; } -_Bool bishop_getlocation(Board board, Move *move) { +int bishop_getlocation(Board board, Move *move) { // TODO: implement - return FALSE; + return INVALID_MOVE_SYNTAX; }
--- a/src/rules/bishop.h Fri Mar 28 11:45:01 2014 +0100 +++ b/src/rules/bishop.h Fri Mar 28 14:32:52 2014 +0100 @@ -36,9 +36,9 @@ extern "C" { #endif -_Bool bishop_chkrules(Board board, Move *move); +_Bool bishop_chkrules(Move *move); _Bool bishop_isblocked(Board board, Move *move); -_Bool bishop_getlocation(Board board, Move *move); +int bishop_getlocation(Board board, Move *move); #ifdef __cplusplus }
--- a/src/rules/king.c Fri Mar 28 11:45:01 2014 +0100 +++ b/src/rules/king.c Fri Mar 28 14:32:52 2014 +0100 @@ -27,6 +27,7 @@ * */ +#include "rules.h" #include "king.h" _Bool king_chkrules(Board board, Move* move) { @@ -39,7 +40,7 @@ return TRUE; } -_Bool king_getlocation(Board board, Move *move) { +int king_getlocation(Board board, Move *move) { // TODO: implement - return FALSE; + return INVALID_MOVE_SYNTAX; }
--- a/src/rules/king.h Fri Mar 28 11:45:01 2014 +0100 +++ b/src/rules/king.h Fri Mar 28 14:32:52 2014 +0100 @@ -39,7 +39,7 @@ _Bool king_chkrules(Board board, Move *move); _Bool king_isblocked(Board board, Move *move); -_Bool king_getlocation(Board board, Move *move); +int king_getlocation(Board board, Move *move); #ifdef __cplusplus }
--- a/src/rules/knight.c Fri Mar 28 11:45:01 2014 +0100 +++ b/src/rules/knight.c Fri Mar 28 14:32:52 2014 +0100 @@ -28,18 +28,106 @@ */ #include "knight.h" +#include "rules.h" +#include <math.h> -_Bool knight_chkrules(Board board, Move *move) { - // TODO: implement - return FALSE; +_Bool knight_chkrules(Move *move) { + int dx = abs(move->fromfile - move->tofile); + int dy = abs(move->fromrow - move->torow); + + return (dx == 2 && dy == 1) || (dx == 1 && dy == 2); +} + +static int knight_getloc_fixedrow(Board board, Move *move) { + int d = 3 - abs(move->fromrow - move->torow); + + if (d == 1 || d == 2) { + if (move->tofile < 6 && + board[move->fromrow][move->tofile + d] == move->piece) { + if (move->fromfile == POS_UNSPECIFIED) { + move->fromfile = move->tofile + d; + return VALID_MOVE_SYNTAX; + } else { + return AMBIGUOUS_MOVE; + } + } + if (move->tofile > 1 && + board[move->fromrow][move->tofile - d] == move->piece) { + if (move->fromfile == POS_UNSPECIFIED) { + move->fromfile = move->tofile - d; + return VALID_MOVE_SYNTAX; + } else { + return AMBIGUOUS_MOVE; + } + } + } + + return INVALID_POSITION; } -_Bool knight_isblocked(Board board, Move *move) { - // TODO: implement - return TRUE; +static int knight_getloc_fixedfile(Board board, Move *move) { + int d = 3 - abs(move->fromfile - move->tofile); + + if (d == 1 || d == 2) { + if (move->torow < 6 && + board[move->torow + d][move->fromfile] == move->piece) { + if (move->fromrow == POS_UNSPECIFIED) { + move->fromrow = move->torow + d; + return VALID_MOVE_SYNTAX; + } else { + return AMBIGUOUS_MOVE; + } + } + if (move->torow > 1 && + board[move->torow - d][move->fromfile] == move->piece) { + if (move->fromrow == POS_UNSPECIFIED) { + move->fromrow = move->torow - d; + return VALID_MOVE_SYNTAX; + } else { + return AMBIGUOUS_MOVE; + } + } + } + + return INVALID_POSITION; } -_Bool knight_getlocation(Board board, Move *move) { - // TODO: implement - return FALSE; +int knight_getlocation(Board board, Move *move) { + + if (move->fromfile != POS_UNSPECIFIED) { + return knight_getloc_fixedfile(board, move); + } + + if (move->fromrow != POS_UNSPECIFIED) { + return knight_getloc_fixedrow(board, move); + } + + for (int x = -2 ; x <= 2 ; x++) { + if (x == 0) { + continue; + } + for (int y = -2 ; y <= 2 ; y++) { + if (y == 0 || y == x) { + continue; + } + uint8_t cx = move->tofile + x; + uint8_t cy = move->torow + y; + + if (isidx(cx) && isidx(cy) && board[cy][cx] == move->piece) { + if (move->fromfile == POS_UNSPECIFIED + && move->fromrow == POS_UNSPECIFIED) { + move->fromfile = cx; + move->fromrow = cy; + } else { + return AMBIGUOUS_MOVE; + } + } + } + } + + if (move->fromfile == POS_UNSPECIFIED || move->fromrow == POS_UNSPECIFIED) { + return INVALID_POSITION; + } else { + return VALID_MOVE_SYNTAX; + } }
--- a/src/rules/knight.h Fri Mar 28 11:45:01 2014 +0100 +++ b/src/rules/knight.h Fri Mar 28 14:32:52 2014 +0100 @@ -36,9 +36,9 @@ extern "C" { #endif -_Bool knight_chkrules(Board board, Move *move); -_Bool knight_isblocked(Board board, Move *move); -_Bool knight_getlocation(Board board, Move *move); +_Bool knight_chkrules(Move *move); +#define knight_isblocked(b,m) FALSE +int knight_getlocation(Board board, Move *move); #ifdef __cplusplus }
--- a/src/rules/pawn.c Fri Mar 28 11:45:01 2014 +0100 +++ b/src/rules/pawn.c Fri Mar 28 14:32:52 2014 +0100 @@ -28,6 +28,7 @@ */ #include "pawn.h" +#include "rules.h" _Bool pawn_chkrules(Board board, Move *move) { int8_t d = ((move->piece & COLOR_MASK) == WHITE ? -1 : 1); @@ -56,7 +57,7 @@ return mdst(board,move) && !move->capture; } -_Bool pawn_getlocation(Board board, Move *move) { +int pawn_getlocation(Board board, Move *move) { int8_t d = ((move->piece & COLOR_MASK) == WHITE ? -1 : 1); if (move->fromfile == POS_UNSPECIFIED) { @@ -64,7 +65,7 @@ } move->fromrow = move->torow + d; if (move->fromrow > 6) { - return FALSE; + return INVALID_POSITION; } else { /* advanced first move */ if (move->fromrow == (d < 0 ? 2 : 5) && @@ -72,9 +73,9 @@ move->fromrow += d; if (move->fromrow > 6) { - return FALSE; + return INVALID_POSITION; } } } - return TRUE; + return VALID_MOVE_SYNTAX; }
--- a/src/rules/pawn.h Fri Mar 28 11:45:01 2014 +0100 +++ b/src/rules/pawn.h Fri Mar 28 14:32:52 2014 +0100 @@ -38,7 +38,7 @@ _Bool pawn_chkrules(Board board, Move *move); _Bool pawn_isblocked(Board board, Move *move); -_Bool pawn_getlocation(Board board, Move *move); +int pawn_getlocation(Board board, Move *move); #ifdef __cplusplus }
--- a/src/rules/queen.c Fri Mar 28 11:45:01 2014 +0100 +++ b/src/rules/queen.c Fri Mar 28 14:32:52 2014 +0100 @@ -27,9 +27,10 @@ * */ +#include "rules.h" #include "queen.h" -_Bool queen_chkrules(Board board, Move* move) { +_Bool queen_chkrules(Move* move) { // TODO: implement return FALSE; } @@ -39,7 +40,7 @@ return TRUE; } -_Bool queen_getlocation(Board board, Move *move) { +int queen_getlocation(Board board, Move *move) { // TODO: implement - return FALSE; + return INVALID_MOVE_SYNTAX; }
--- a/src/rules/queen.h Fri Mar 28 11:45:01 2014 +0100 +++ b/src/rules/queen.h Fri Mar 28 14:32:52 2014 +0100 @@ -36,9 +36,9 @@ extern "C" { #endif -_Bool queen_chkrules(Board board, Move *move); +_Bool queen_chkrules(Move *move); _Bool queen_isblocked(Board board, Move *move); -_Bool queen_getlocation(Board board, Move *move); +int queen_getlocation(Board board, Move *move); #ifdef __cplusplus }
--- a/src/rules/rook.c Fri Mar 28 11:45:01 2014 +0100 +++ b/src/rules/rook.c Fri Mar 28 14:32:52 2014 +0100 @@ -27,9 +27,10 @@ * */ +#include "rules.h" #include "rook.h" -_Bool rook_chkrules(Board board, Move *move) { +_Bool rook_chkrules(Move *move) { // TODO: implement return FALSE; } @@ -39,7 +40,7 @@ return TRUE; } -_Bool rook_getlocation(Board board, Move *move) { +int rook_getlocation(Board board, Move *move) { // TODO: implement - return FALSE; + return INVALID_MOVE_SYNTAX; }
--- a/src/rules/rook.h Fri Mar 28 11:45:01 2014 +0100 +++ b/src/rules/rook.h Fri Mar 28 14:32:52 2014 +0100 @@ -36,9 +36,9 @@ extern "C" { #endif -_Bool rook_chkrules(Board board, Move *move); +_Bool rook_chkrules(Move *move); _Bool rook_isblocked(Board board, Move *move); -_Bool rook_getlocation(Board board, Move *move); +int rook_getlocation(Board board, Move *move); #ifdef __cplusplus }
--- a/src/rules/rules.h Fri Mar 28 11:45:01 2014 +0100 +++ b/src/rules/rules.h Fri Mar 28 14:32:52 2014 +0100 @@ -37,5 +37,10 @@ #include "queen.h" #include "king.h" +#define VALID_MOVE_SYNTAX 0 +#define INVALID_MOVE_SYNTAX 1 +#define INVALID_POSITION 2 +#define AMBIGUOUS_MOVE 3 + #endif /* RULES_H */