1.1 --- a/src/game.c Sat Mar 29 16:53:58 2014 +0100 1.2 +++ b/src/game.c Mon Mar 31 11:16:32 2014 +0200 1.3 @@ -28,64 +28,13 @@ 1.4 */ 1.5 1.6 #include "game.h" 1.7 +#include "network.h" 1.8 #include "input.h" 1.9 -#include "rules/rules.h" 1.10 #include <ncurses.h> 1.11 #include <string.h> 1.12 1.13 static const uint8_t boardx = 10, boardy = 10; 1.14 1.15 -static uint8_t getpiecechr(uint8_t piece) { 1.16 - switch (piece & PIECE_MASK) { 1.17 - case ROOK: return 'R'; 1.18 - case KNIGHT: return 'N'; 1.19 - case BISHOP: return 'B'; 1.20 - case QUEEN: return 'Q'; 1.21 - case KING: return 'K'; 1.22 - default: return '\0'; 1.23 - } 1.24 -} 1.25 - 1.26 -/** 1.27 - * Maps a character to a piece. 1.28 - * 1.29 - * Does not work for pawns, since they don't have a character. 1.30 - * 1.31 - * @param c one of R,N,B,Q,K 1.32 - * @return numeric value for the specified piece 1.33 - */ 1.34 -static uint8_t getpiece(char c) { 1.35 - switch (c) { 1.36 - case 'R': return ROOK; 1.37 - case 'N': return KNIGHT; 1.38 - case 'B': return BISHOP; 1.39 - case 'Q': return QUEEN; 1.40 - case 'K': return KING; 1.41 - default: return 0; 1.42 - } 1.43 -} 1.44 - 1.45 -/** 1.46 - * Guesses the location of a piece for short algebraic notation. 1.47 - * 1.48 - * @param board the current state of the board 1.49 - * @param move the move date to operate on 1.50 - * @return status code (see rules/rules.h for the codes) 1.51 - */ 1.52 -static int getlocation(Board board, Move *move) { 1.53 - uint8_t piece = move->piece & PIECE_MASK; 1.54 - switch (piece) { 1.55 - case PAWN: return pawn_getlocation(board, move); 1.56 - case ROOK: return rook_getlocation(board, move); 1.57 - case KNIGHT: return knight_getlocation(board, move); 1.58 - case BISHOP: return bishop_getlocation(board, move); 1.59 - case QUEEN: return queen_getlocation(board, move); 1.60 - case KING: return king_getlocation(board, move); 1.61 - default: return INVALID_MOVE_SYNTAX; 1.62 - } 1.63 -} 1.64 - 1.65 - 1.66 static void draw_board(Board board, MoveListRoot *movelist, uint8_t mycolor) { 1.67 1.68 for (uint8_t y = 0 ; y < 8 ; y++) { 1.69 @@ -158,255 +107,6 @@ 1.70 } 1.71 } 1.72 1.73 -/** 1.74 - * Applies a move and deletes captured pieces. 1.75 - * 1.76 - * @param board the current board state 1.77 - * @param move the move to apply 1.78 - */ 1.79 -static void apply_move(Board board, Move *move) { 1.80 - uint8_t piece = move->piece & PIECE_MASK; 1.81 - uint8_t color = move->piece & COLOR_MASK; 1.82 - 1.83 - /* en passant capture */ 1.84 - if (move->capture && piece == PAWN && 1.85 - mdst(board, move) == 0) { 1.86 - board[move->fromrow][move->tofile] = 0; 1.87 - } 1.88 - 1.89 - /* remove old en passant threats */ 1.90 - for (uint8_t file = 0 ; file < 8 ; file++) { 1.91 - board[3][file] &= ~ENPASSANT_THREAT; 1.92 - board[4][file] &= ~ENPASSANT_THREAT; 1.93 - } 1.94 - 1.95 - /* add new en passant threat */ 1.96 - if (piece == PAWN && ( 1.97 - (move->fromrow == 1 && move->torow == 3) || 1.98 - (move->fromrow == 6 && move->torow == 4))) { 1.99 - move->piece |= ENPASSANT_THREAT; 1.100 - } 1.101 - 1.102 - /* move (and maybe capture or promote) */ 1.103 - msrc(board, move) = 0; 1.104 - if (move->promotion) { 1.105 - mdst(board, move) = move->promotion; 1.106 - } else { 1.107 - mdst(board, move) = move->piece; 1.108 - } 1.109 - 1.110 - /* castling */ 1.111 - if (piece == KING && 1.112 - move->fromfile == fileidx('e')) { 1.113 - 1.114 - if (move->tofile == fileidx('g')) { 1.115 - board[move->torow][fileidx('h')] = 0; 1.116 - board[move->torow][fileidx('f')] = color|ROOK; 1.117 - } else if (move->tofile == fileidx('c')) { 1.118 - board[move->torow][fileidx('a')] = 0; 1.119 - board[move->torow][fileidx('d')] = color|ROOK; 1.120 - } 1.121 - } 1.122 -} 1.123 - 1.124 -/** 1.125 - * Validates move by applying chess rules. 1.126 - * @param board the current board state 1.127 - * @param move the move to validate 1.128 - * @return TRUE, if the move complies to chess rules, FALSE otherwise 1.129 - */ 1.130 -static _Bool validate_move(Board board, Move *move) { 1.131 - _Bool result; 1.132 - 1.133 - /* validate indices (don't trust opponent) */ 1.134 - if (!chkidx(move)) { 1.135 - return FALSE; 1.136 - } 1.137 - 1.138 - /* does piece exist */ 1.139 - result = msrc(board, move) == move->piece; 1.140 - 1.141 - /* can't capture own pieces */ 1.142 - if ((mdst(board, move) & COLOR_MASK) == (move->piece & COLOR_MASK)) { 1.143 - return FALSE; 1.144 - } 1.145 - 1.146 - /* validate individual rules */ 1.147 - switch (move->piece & PIECE_MASK) { 1.148 - case PAWN: 1.149 - result = result && pawn_chkrules(board, move); 1.150 - result = result && !pawn_isblocked(board, move); 1.151 - break; 1.152 - case ROOK: 1.153 - result = result && rook_chkrules(move); 1.154 - result = result && !rook_isblocked(board, move); 1.155 - break; 1.156 - case KNIGHT: 1.157 - result = result && knight_chkrules(move); 1.158 - result = result && !knight_isblocked(board, move); 1.159 - break; 1.160 - case BISHOP: 1.161 - result = result && bishop_chkrules(move); 1.162 - result = result && !bishop_isblocked(board, move); 1.163 - break; 1.164 - case QUEEN: 1.165 - result = result && queen_chkrules(move); 1.166 - result = result && !queen_isblocked(board, move); 1.167 - break; 1.168 - case KING: 1.169 - result = result && king_chkrules(board, move); 1.170 - result = result && !king_isblocked(board, move); 1.171 - break; 1.172 - default: 1.173 - result = FALSE; 1.174 - } 1.175 - 1.176 - /* is piece pinned */ 1.177 - // TODO: make it so 1.178 - 1.179 - /* correct check and checkmate flags */ 1.180 - // TODO: make it so 1.181 - 1.182 - return result; 1.183 -} 1.184 - 1.185 -/** 1.186 - * Evaluates a move syntactically and stores the move data in the specified 1.187 - * object. 1.188 - * 1.189 - * @param board the current state of the board 1.190 - * @param mycolor the color of the current player 1.191 - * @param mstr the input string to parse 1.192 - * @param move a pointer to object where the move data shall be stored 1.193 - * @return status code (see rules/rules.h for the list of codes) 1.194 - */ 1.195 -static int eval_move(Board board, uint8_t mycolor, char *mstr, Move *move) { 1.196 - memset(move, 0, sizeof(Move)); 1.197 - move->fromfile = POS_UNSPECIFIED; 1.198 - move->fromrow = POS_UNSPECIFIED; 1.199 - 1.200 - size_t len = strlen(mstr); 1.201 - 1.202 - /* evaluate check/checkmate flags */ 1.203 - if (mstr[len-1] == '+') { 1.204 - len--; mstr[len] = '\0'; 1.205 - move->check = TRUE; 1.206 - } else if (mstr[len-1] == '#') { 1.207 - len--; mstr[len] = '\0'; 1.208 - move->checkmate = TRUE; 1.209 - } 1.210 - 1.211 - /* evaluate promotion */ 1.212 - if (len > 3 && mstr[len-2] == '=') { 1.213 - move->promotion = getpiece(mstr[len-1]); 1.214 - if (!move->promotion) { 1.215 - return INVALID_MOVE_SYNTAX; 1.216 - } else { 1.217 - move->promotion |= mycolor; 1.218 - len -= 2; 1.219 - mstr[len] = 0; 1.220 - } 1.221 - } 1.222 - 1.223 - if (len == 2) { 1.224 - /* pawn move (e.g. "e4") */ 1.225 - move->piece = PAWN; 1.226 - move->tofile = fileidx(mstr[0]); 1.227 - move->torow = rowidx(mstr[1]); 1.228 - } else if (len == 3) { 1.229 - if (strcmp(mstr, "O-O") == 0) { 1.230 - /* king side castling */ 1.231 - move->piece = KING; 1.232 - move->fromfile = fileidx('e'); 1.233 - move->tofile = fileidx('g'); 1.234 - move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; 1.235 - } else { 1.236 - /* move (e.g. "Nf3") */ 1.237 - move->piece = getpiece(mstr[0]); 1.238 - move->tofile = fileidx(mstr[1]); 1.239 - move->torow = rowidx(mstr[2]); 1.240 - } 1.241 - 1.242 - } else if (len == 4) { 1.243 - move->piece = getpiece(mstr[0]); 1.244 - if (!move->piece) { 1.245 - move->piece = PAWN; 1.246 - move->fromfile = fileidx(mstr[0]); 1.247 - } 1.248 - if (mstr[1] == 'x') { 1.249 - /* capture (e.g. "Nxf3", "dxe5") */ 1.250 - move->capture = TRUE; 1.251 - } else { 1.252 - /* move (e.g. "Ndf3", "N2c3", "e2e4") */ 1.253 - if (isfile(mstr[1])) { 1.254 - move->fromfile = fileidx(mstr[1]); 1.255 - if (move->piece == PAWN) { 1.256 - move->piece = 0; 1.257 - } 1.258 - } else { 1.259 - move->fromrow = rowidx(mstr[1]); 1.260 - } 1.261 - } 1.262 - move->tofile = fileidx(mstr[2]); 1.263 - move->torow = rowidx(mstr[3]); 1.264 - } else if (len == 5) { 1.265 - if (strcmp(mstr, "O-O-O") == 0) { 1.266 - /* queen side castling "O-O-O" */ 1.267 - move->piece = KING; 1.268 - move->fromfile = fileidx('e'); 1.269 - move->tofile = fileidx('c'); 1.270 - move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; 1.271 - } else { 1.272 - move->piece = getpiece(mstr[0]); 1.273 - if (mstr[2] == 'x') { 1.274 - move->capture = TRUE; 1.275 - if (move->piece) { 1.276 - /* capture (e.g. "Ndxf3") */ 1.277 - move->fromfile = fileidx(mstr[1]); 1.278 - } else { 1.279 - /* long notation capture (e.g. "e5xf6") */ 1.280 - move->piece = PAWN; 1.281 - move->fromfile = fileidx(mstr[0]); 1.282 - move->fromrow = rowidx(mstr[1]); 1.283 - } 1.284 - } else { 1.285 - /* long notation move (e.g. "Nc5a4") */ 1.286 - move->fromfile = fileidx(mstr[1]); 1.287 - move->fromrow = rowidx(mstr[2]); 1.288 - } 1.289 - move->tofile = fileidx(mstr[3]); 1.290 - move->torow = rowidx(mstr[4]); 1.291 - } 1.292 - } else if (len == 6) { 1.293 - /* long notation capture (e.g. "Nc5xf3") */ 1.294 - if (mstr[3] == 'x') { 1.295 - move->capture = TRUE; 1.296 - move->piece = getpiece(mstr[0]); 1.297 - move->fromfile = fileidx(mstr[1]); 1.298 - move->fromrow = rowidx(mstr[2]); 1.299 - move->tofile = fileidx(mstr[4]); 1.300 - move->torow = rowidx(mstr[5]); 1.301 - } 1.302 - } 1.303 - 1.304 - 1.305 - if (move->piece) { 1.306 - if (move->piece == PAWN && move->torow == (mycolor==WHITE?7:0) 1.307 - && !move->promotion) { 1.308 - return NEED_PROMOTION; 1.309 - } 1.310 - 1.311 - move->piece |= mycolor; 1.312 - if (move->fromfile == POS_UNSPECIFIED 1.313 - || move->fromrow == POS_UNSPECIFIED) { 1.314 - return getlocation(board, move); 1.315 - } else { 1.316 - return chkidx(move) ? VALID_MOVE_SYNTAX : INVALID_POSITION; 1.317 - } 1.318 - } else { 1.319 - return INVALID_MOVE_SYNTAX; 1.320 - } 1.321 -} 1.322 1.323 static int sendmove(Board board, MoveListRoot *movelist, 1.324 uint8_t mycolor, int opponent) {