1.1 --- a/src/game.c Wed Mar 26 13:16:49 2014 +0100 1.2 +++ b/src/game.c Wed Mar 26 14:12:59 2014 +0100 1.3 @@ -71,6 +71,12 @@ 1.4 } 1.5 } 1.6 1.7 +/** 1.8 + * Applies a move and deletes captured pieces. 1.9 + * 1.10 + * @param board the current board state 1.11 + * @param move the move to apply 1.12 + */ 1.13 static void apply_move(Board board, Move *move) { 1.14 board[move->fromrow][move->fromfile] = 0; 1.15 // TODO: care for en passant capture 1.16 @@ -91,9 +97,20 @@ 1.17 } 1.18 } 1.19 1.20 +/** 1.21 + * Validates move by applying chess rules. 1.22 + * @param board the current board state 1.23 + * @param move the move to validate 1.24 + * @return TRUE, if the move complies to chess rules, FALSE otherwise 1.25 + */ 1.26 static _Bool validate_move(Board board, Move *move) { 1.27 _Bool result; 1.28 1.29 + /* validate indices (don't trust opponent) */ 1.30 + if (!chkidx(move)) { 1.31 + return FALSE; 1.32 + } 1.33 + 1.34 /* does piece exist */ 1.35 result = board[move->fromrow][move->fromfile] == move->piece; 1.36 1.37 @@ -162,7 +179,7 @@ 1.38 * @return TRUE if the location could be retrieved, FALSE if the location is 1.39 * ambiguous 1.40 */ 1.41 -static _Bool getlocation(Board board, Move *move) { 1.42 +static _Bool getlocation(Board board, Move *move) { 1.43 uint8_t piece = move->piece & PIECE_MASK; 1.44 switch (piece) { 1.45 case PAWN: return pawn_getlocation(board, move); 1.46 @@ -203,11 +220,9 @@ 1.47 1.48 if (len == 2) { 1.49 /* pawn move (e.g. "e4") */ 1.50 - if (isfile(mstr[0]) && isrow(mstr[1])) { 1.51 - move->piece = PAWN; 1.52 - move->tofile = fileidx(mstr[0]); 1.53 - move->torow = rowidx(mstr[1]); 1.54 - } 1.55 + move->piece = PAWN; 1.56 + move->tofile = fileidx(mstr[0]); 1.57 + move->torow = rowidx(mstr[1]); 1.58 } else if (len == 3) { 1.59 if (strcmp(mstr, "O-O") == 0) { 1.60 /* king side castling */ 1.61 @@ -216,17 +231,27 @@ 1.62 move->tofile = fileidx('g'); 1.63 move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; 1.64 } else { 1.65 - /* unambiguous move (e.g. "Nf3") */ 1.66 + /* move (e.g. "Nf3") */ 1.67 move->piece = getpiece(mstr[0]); 1.68 - move->tofile = isfile(mstr[1]) ? fileidx(mstr[1]) : POS_UNSPECIFIED; 1.69 - move->torow = isrow(mstr[2]) ? fileidx(mstr[2]) : POS_UNSPECIFIED; 1.70 + move->tofile = fileidx(mstr[1]); 1.71 + move->torow = rowidx(mstr[2]); 1.72 } 1.73 1.74 } else if (len == 4) { 1.75 - /* ambiguous move (e.g. "Ndf3") */ 1.76 - 1.77 - /* unambiguous capture (e.g. "Nxf3", "dxe5") */ 1.78 - 1.79 + move->piece = getpiece(mstr[0]); 1.80 + if (mstr[1] == 'x') { 1.81 + /* capture (e.g. "Nxf3", "dxe5") */ 1.82 + move->capture = TRUE; 1.83 + if (!move->piece) { 1.84 + move->piece = PAWN; 1.85 + move->fromfile = fileidx(mstr[0]); 1.86 + } 1.87 + } else { 1.88 + /* move (e.g. "Ndf3") */ 1.89 + move->fromfile = fileidx(mstr[1]); 1.90 + } 1.91 + move->tofile = fileidx(mstr[2]); 1.92 + move->torow = rowidx(mstr[3]); 1.93 } else if (len == 5) { 1.94 if (strcmp(mstr, "O-O-O") == 0) { 1.95 /* queen side castling "O-O-O" */ 1.96 @@ -235,26 +260,51 @@ 1.97 move->tofile = fileidx('c'); 1.98 move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; 1.99 } else { 1.100 - /* ambiguous capture (e.g. "Ndxf3") */ 1.101 - 1.102 - /* long notation move (e.g. "Nc5a4") */ 1.103 - 1.104 - /* long notation capture (e.g. "e5xf6") */ 1.105 + move->piece = getpiece(mstr[0]); 1.106 + if (mstr[2] == 'x') { 1.107 + move->capture = TRUE; 1.108 + if (move->piece) { 1.109 + /* capture (e.g. "Ndxf3") */ 1.110 + move->fromfile = fileidx(mstr[1]); 1.111 + } else { 1.112 + /* long notation capture (e.g. "e5xf6") */ 1.113 + move->piece = PAWN; 1.114 + move->fromfile = fileidx(mstr[0]); 1.115 + move->fromrow = rowidx(mstr[1]); 1.116 + } 1.117 + } else { 1.118 + /* long notation move (e.g. "Nc5a4") */ 1.119 + move->fromfile = fileidx(mstr[1]); 1.120 + move->fromrow = rowidx(mstr[2]); 1.121 + } 1.122 + move->tofile = fileidx(mstr[3]); 1.123 + move->torow = rowidx(mstr[4]); 1.124 } 1.125 } else if (len == 6) { 1.126 /* long notation capture (e.g. "Nc5xf3") */ 1.127 + if (mstr[3] == 'x') { 1.128 + move->capture = TRUE; 1.129 + move->piece = getpiece(mstr[0]); 1.130 + move->fromfile = fileidx(mstr[1]); 1.131 + move->fromrow = rowidx(mstr[2]); 1.132 + move->tofile = fileidx(mstr[4]); 1.133 + move->torow = rowidx(mstr[5]); 1.134 + } 1.135 } 1.136 1.137 + 1.138 if (move->piece) { 1.139 move->piece |= mycolor; 1.140 + if (move->fromfile == POS_UNSPECIFIED 1.141 + || move->fromrow == POS_UNSPECIFIED) { 1.142 + return getlocation(board, move) && chkidx(move); 1.143 + } else { 1.144 + return chkidx(move); 1.145 + } 1.146 + } else { 1.147 + return FALSE; 1.148 } 1.149 - 1.150 - if (!getlocation(board, move)) { 1.151 - // TODO: return status code to indicate the error type 1.152 - move->piece = 0; 1.153 - } 1.154 - 1.155 - return move->piece != 0; 1.156 + // TODO: return status code to indicate the error type 1.157 } 1.158 1.159 static int sendmove(Board board, uint8_t mycolor, int opponent) {