diff -r 4d030da07c88 -r 3ab0c2e1a4e2 src/chess/king.c --- a/src/chess/king.c Tue Apr 01 10:28:08 2014 +0200 +++ b/src/chess/king.c Tue Apr 01 12:30:25 2014 +0200 @@ -29,18 +29,88 @@ #include "rules.h" #include "king.h" +#include -_Bool king_chkrules(GameState *gamestate, Move* move) { - // TODO: implement +static _Bool king_castling_chkmoved(GameState *gamestate, + uint8_t row, uint8_t file) { + + MoveList *ml = gamestate->movelist; + while (ml) { + if (ml->move.fromfile == file && ml->move.fromrow == row) { + return 1; + } + ml = ml->next; + } + return 0; } +_Bool king_chkrules(GameState *gamestate, Move* move) { + if (abs(move->torow - move->fromrow) <= 1 && + abs(move->tofile - move->fromfile) <= 1) { + return 1; + } else { + /* castling */ + if (move->fromrow == move->torow && + move->fromrow == ((move->piece&COLOR_MASK) == WHITE ? 0 : 7) && + move->fromfile == fileidx('e') && + (move->tofile == fileidx('c') || move->tofile == fileidx('g'))) { + + return !king_castling_chkmoved(gamestate, + move->fromrow, move->fromfile) && + !king_castling_chkmoved(gamestate, move->fromrow, + move->tofile == fileidx('c') ? 0 : 7); + } else { + return 0; + } + } +} + _Bool king_isblocked(GameState *gamestate, Move *move) { - // TODO: implement - return 1; + + uint8_t opponent_color = opponent_color(move->piece&COLOR_MASK); + _Bool blocked = is_covered(gamestate, move->torow, move->tofile, + opponent_color); + + if (abs(move->tofile - move->fromfile) == 2) { + if (move->tofile == fileidx('c')) { + blocked |= gamestate->board[move->torow][fileidx('b')]; + } + uint8_t midfile = (move->tofile+move->fromfile)/2; + blocked |= gamestate->lastmove->move.check || + gamestate->board[move->torow][midfile] || + is_covered(gamestate, move->torow, midfile, opponent_color); + } + + return blocked; } int king_getlocation(GameState *gamestate, Move *move) { - // TODO: implement - return INVALID_MOVE_SYNTAX; + + uint8_t file, row; + + for (int f = -1 ; f <= 1 ; f++) { + for (int r = -1 ; r <= 1 ; r++) { + if (f == 0 && r == 0) { + continue; + } + file = move->tofile + f; + row = move->torow + r; + if (isidx(file) && isidx(row)) { + if (gamestate->board[row][file] == move->piece) { + if ((move->fromfile != POS_UNSPECIFIED + && move->fromfile != file) || + (move->fromrow != POS_UNSPECIFIED + && move->fromrow != row)) { + return INVALID_POSITION; + } + move->fromfile = file; + move->fromrow = row; + return VALID_MOVE_SYNTAX; + } + } + } + } + + return INVALID_POSITION; }