# HG changeset patch # User Mike Becker # Date 1395841995 -3600 # Node ID 970748b9a73b8d3f9a22fc9bf109423094aa94ed # Parent faec61c4901fd9d40698b84c315ab292a7063f16 fixed crucial bug where both players could move at the same time + added pawn rules (TODO: en passant) diff -r faec61c4901f -r 970748b9a73b src/game.c --- a/src/game.c Wed Mar 26 14:12:59 2014 +0100 +++ b/src/game.c Wed Mar 26 14:53:15 2014 +0100 @@ -78,9 +78,9 @@ * @param move the move to apply */ static void apply_move(Board board, Move *move) { - board[move->fromrow][move->fromfile] = 0; + msrc(board, move) = 0; // TODO: care for en passant capture - board[move->torow][move->tofile] = move->piece; + mdst(board, move) = move->piece; /* castling */ if ((move->piece & PIECE_MASK) == KING && @@ -112,8 +112,14 @@ } /* does piece exist */ - result = board[move->fromrow][move->fromfile] == move->piece; + result = msrc(board, move) == move->piece; + /* can't capture own pieces */ + if ((mdst(board, move) & COLOR_MASK) == (move->piece & COLOR_MASK)) { + return FALSE; + } + + /* validate individual rules */ switch (move->piece & PIECE_MASK) { case PAWN: result = result && pawn_chkrules(board, move); @@ -247,8 +253,9 @@ move->fromfile = fileidx(mstr[0]); } } else { - /* move (e.g. "Ndf3") */ - move->fromfile = fileidx(mstr[1]); + /* move (e.g. "Ndf3", "N2c3") */ + move->fromfile = isfile(mstr[1]) ? + fileidx(mstr[1]) : rowidx(mstr[1]); } move->tofile = fileidx(mstr[2]); move->torow = rowidx(mstr[3]); @@ -366,6 +373,8 @@ if (move.checkmate) { printw("Checkmate!"); return 1; + } else { + return 0; } } } else { diff -r faec61c4901f -r 970748b9a73b src/game.h --- a/src/game.h Wed Mar 26 14:12:59 2014 +0100 +++ b/src/game.h Wed Mar 26 14:53:15 2014 +0100 @@ -37,8 +37,9 @@ extern "C" { #endif -#define PIECE_MASK 0x0F -#define COLOR_MASK 0xF0 +#define PIECE_MASK 0x0F +#define COLOR_MASK 0x30 +#define ENPASSANT_THREAT 0x40 #define WHITE 0x10 #define BLACK 0x20 @@ -77,6 +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 isidx(idx) ((uint8_t)idx < 8) diff -r faec61c4901f -r 970748b9a73b src/rules/pawn.c --- a/src/rules/pawn.c Wed Mar 26 14:12:59 2014 +0100 +++ b/src/rules/pawn.c Wed Mar 26 14:53:15 2014 +0100 @@ -30,28 +30,44 @@ #include "pawn.h" _Bool pawn_chkrules(Board board, Move *move) { - // TODO: implement - return TRUE; + int8_t d = ((move->piece & COLOR_MASK) == WHITE ? -1 : 1); + if (move->capture) { + if (move->fromrow == move->torow + d && ( + move->fromfile == move->tofile + 1 || + move->fromfile == move->tofile - 1)) { + // TODO: en passant + return mdst(board,move) != 0; /* color has been checked */ + } else { + return FALSE; + } + } else { + if (move->fromfile == move->tofile) { + return (move->fromrow == move->torow + d) || + (move->fromrow == (d < 0 ? 1 : 6) && /* advanced first move */ + move->fromrow == move->torow + d*2); + } else { + return FALSE; + } + } } _Bool pawn_isblocked(Board board, Move *move) { - // TODO: implement - return FALSE; + return mdst(board,move) && !move->capture; } _Bool pawn_getlocation(Board board, Move *move) { int8_t d = ((move->piece & COLOR_MASK) == WHITE ? -1 : 1); - // TODO: battle moves - - move->fromfile = move->tofile; + if (move->fromfile == POS_UNSPECIFIED) { + move->fromfile = move->tofile; + } move->fromrow = move->torow + d; if (move->fromrow > 6) { return FALSE; } else { /* advanced first move */ if (move->fromrow == (d < 0 ? 2 : 5) && - board[move->fromrow][move->fromfile] != move->piece) { + msrc(board,move) != move->piece) { move->fromrow += d; if (move->fromrow > 6) {