Wed, 26 Mar 2014 14:12:59 +0100
completed eval_move
Makefile | file | annotate | diff | comparison | revisions | |
src/game.c | file | annotate | diff | comparison | revisions | |
src/game.h | file | annotate | diff | comparison | revisions |
--- a/Makefile Wed Mar 26 13:16:49 2014 +0100 +++ b/Makefile Wed Mar 26 14:12:59 2014 +0100 @@ -28,9 +28,7 @@ include conf.mk -all: clean compile - -compile: build build/rules +all: build build/rules cd src; $(MAKE) build:
--- a/src/game.c Wed Mar 26 13:16:49 2014 +0100 +++ b/src/game.c Wed Mar 26 14:12:59 2014 +0100 @@ -71,6 +71,12 @@ } } +/** + * Applies a move and deletes captured pieces. + * + * @param board the current board state + * @param move the move to apply + */ static void apply_move(Board board, Move *move) { board[move->fromrow][move->fromfile] = 0; // TODO: care for en passant capture @@ -91,9 +97,20 @@ } } +/** + * Validates move by applying chess rules. + * @param board the current board state + * @param move the move to validate + * @return TRUE, if the move complies to chess rules, FALSE otherwise + */ static _Bool validate_move(Board board, Move *move) { _Bool result; + /* validate indices (don't trust opponent) */ + if (!chkidx(move)) { + return FALSE; + } + /* does piece exist */ result = board[move->fromrow][move->fromfile] == move->piece; @@ -162,7 +179,7 @@ * @return TRUE if the location could be retrieved, FALSE if the location is * ambiguous */ -static _Bool getlocation(Board board, Move *move) { +static _Bool getlocation(Board board, Move *move) { uint8_t piece = move->piece & PIECE_MASK; switch (piece) { case PAWN: return pawn_getlocation(board, move); @@ -203,11 +220,9 @@ if (len == 2) { /* pawn move (e.g. "e4") */ - if (isfile(mstr[0]) && isrow(mstr[1])) { - move->piece = PAWN; - move->tofile = fileidx(mstr[0]); - move->torow = rowidx(mstr[1]); - } + move->piece = PAWN; + move->tofile = fileidx(mstr[0]); + move->torow = rowidx(mstr[1]); } else if (len == 3) { if (strcmp(mstr, "O-O") == 0) { /* king side castling */ @@ -216,17 +231,27 @@ move->tofile = fileidx('g'); move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; } else { - /* unambiguous move (e.g. "Nf3") */ + /* move (e.g. "Nf3") */ move->piece = getpiece(mstr[0]); - move->tofile = isfile(mstr[1]) ? fileidx(mstr[1]) : POS_UNSPECIFIED; - move->torow = isrow(mstr[2]) ? fileidx(mstr[2]) : POS_UNSPECIFIED; + move->tofile = fileidx(mstr[1]); + move->torow = rowidx(mstr[2]); } } else if (len == 4) { - /* ambiguous move (e.g. "Ndf3") */ - - /* unambiguous capture (e.g. "Nxf3", "dxe5") */ - + move->piece = getpiece(mstr[0]); + if (mstr[1] == 'x') { + /* capture (e.g. "Nxf3", "dxe5") */ + move->capture = TRUE; + if (!move->piece) { + move->piece = PAWN; + move->fromfile = fileidx(mstr[0]); + } + } else { + /* move (e.g. "Ndf3") */ + move->fromfile = fileidx(mstr[1]); + } + move->tofile = fileidx(mstr[2]); + move->torow = rowidx(mstr[3]); } else if (len == 5) { if (strcmp(mstr, "O-O-O") == 0) { /* queen side castling "O-O-O" */ @@ -235,26 +260,51 @@ move->tofile = fileidx('c'); move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; } else { - /* ambiguous capture (e.g. "Ndxf3") */ - - /* long notation move (e.g. "Nc5a4") */ - - /* long notation capture (e.g. "e5xf6") */ + move->piece = getpiece(mstr[0]); + if (mstr[2] == 'x') { + move->capture = TRUE; + if (move->piece) { + /* capture (e.g. "Ndxf3") */ + move->fromfile = fileidx(mstr[1]); + } else { + /* long notation capture (e.g. "e5xf6") */ + move->piece = PAWN; + move->fromfile = fileidx(mstr[0]); + move->fromrow = rowidx(mstr[1]); + } + } else { + /* long notation move (e.g. "Nc5a4") */ + move->fromfile = fileidx(mstr[1]); + move->fromrow = rowidx(mstr[2]); + } + move->tofile = fileidx(mstr[3]); + move->torow = rowidx(mstr[4]); } } else if (len == 6) { /* long notation capture (e.g. "Nc5xf3") */ + if (mstr[3] == 'x') { + move->capture = TRUE; + move->piece = getpiece(mstr[0]); + move->fromfile = fileidx(mstr[1]); + move->fromrow = rowidx(mstr[2]); + move->tofile = fileidx(mstr[4]); + move->torow = rowidx(mstr[5]); + } } + if (move->piece) { move->piece |= mycolor; + if (move->fromfile == POS_UNSPECIFIED + || move->fromrow == POS_UNSPECIFIED) { + return getlocation(board, move) && chkidx(move); + } else { + return chkidx(move); + } + } else { + return FALSE; } - - if (!getlocation(board, move)) { - // TODO: return status code to indicate the error type - move->piece = 0; - } - - return move->piece != 0; + // TODO: return status code to indicate the error type } static int sendmove(Board board, uint8_t mycolor, int opponent) {
--- a/src/game.h Wed Mar 26 13:16:49 2014 +0100 +++ b/src/game.h Wed Mar 26 14:12:59 2014 +0100 @@ -78,11 +78,21 @@ #define POS_UNSPECIFIED UINT8_MAX +#define isidx(idx) ((uint8_t)idx < 8) + #define isfile(file) (file >= 'a' && file <= 'h') #define isrow(row) (row >= '1' && row <= '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)) + +/* secure versions - use, if index is not checked with isidx() */ +#define fileidx_s(c) (isfile(c)?fileidx(c):POS_UNSPECIFIED) +#define rowidx_s(c) (isrow(c)?rowidx(c):POS_UNSPECIFIED) + void game_start(Settings *settings, int opponent); #ifdef __cplusplus