src/game.c

changeset 13
faec61c4901f
parent 12
84880c7e1ea6
child 14
970748b9a73b
equal deleted inserted replaced
12:84880c7e1ea6 13:faec61c4901f
69 mvaddch(boardy+1, x, 'a'+i); 69 mvaddch(boardy+1, x, 'a'+i);
70 mvaddch(y, boardx-2, '1'+i); 70 mvaddch(y, boardx-2, '1'+i);
71 } 71 }
72 } 72 }
73 73
74 /**
75 * Applies a move and deletes captured pieces.
76 *
77 * @param board the current board state
78 * @param move the move to apply
79 */
74 static void apply_move(Board board, Move *move) { 80 static void apply_move(Board board, Move *move) {
75 board[move->fromrow][move->fromfile] = 0; 81 board[move->fromrow][move->fromfile] = 0;
76 // TODO: care for en passant capture 82 // TODO: care for en passant capture
77 board[move->torow][move->tofile] = move->piece; 83 board[move->torow][move->tofile] = move->piece;
78 84
89 board[move->torow][fileidx('d')] = color|ROOK; 95 board[move->torow][fileidx('d')] = color|ROOK;
90 } 96 }
91 } 97 }
92 } 98 }
93 99
100 /**
101 * Validates move by applying chess rules.
102 * @param board the current board state
103 * @param move the move to validate
104 * @return TRUE, if the move complies to chess rules, FALSE otherwise
105 */
94 static _Bool validate_move(Board board, Move *move) { 106 static _Bool validate_move(Board board, Move *move) {
95 _Bool result; 107 _Bool result;
108
109 /* validate indices (don't trust opponent) */
110 if (!chkidx(move)) {
111 return FALSE;
112 }
96 113
97 /* does piece exist */ 114 /* does piece exist */
98 result = board[move->fromrow][move->fromfile] == move->piece; 115 result = board[move->fromrow][move->fromfile] == move->piece;
99 116
100 switch (move->piece & PIECE_MASK) { 117 switch (move->piece & PIECE_MASK) {
160 * @param board the current state of the board 177 * @param board the current state of the board
161 * @param move the move date to operate on 178 * @param move the move date to operate on
162 * @return TRUE if the location could be retrieved, FALSE if the location is 179 * @return TRUE if the location could be retrieved, FALSE if the location is
163 * ambiguous 180 * ambiguous
164 */ 181 */
165 static _Bool getlocation(Board board, Move *move) { 182 static _Bool getlocation(Board board, Move *move) {
166 uint8_t piece = move->piece & PIECE_MASK; 183 uint8_t piece = move->piece & PIECE_MASK;
167 switch (piece) { 184 switch (piece) {
168 case PAWN: return pawn_getlocation(board, move); 185 case PAWN: return pawn_getlocation(board, move);
169 case ROOK: return rook_getlocation(board, move); 186 case ROOK: return rook_getlocation(board, move);
170 case KNIGHT: return knight_getlocation(board, move); 187 case KNIGHT: return knight_getlocation(board, move);
201 move->checkmate = TRUE; 218 move->checkmate = TRUE;
202 } 219 }
203 220
204 if (len == 2) { 221 if (len == 2) {
205 /* pawn move (e.g. "e4") */ 222 /* pawn move (e.g. "e4") */
206 if (isfile(mstr[0]) && isrow(mstr[1])) { 223 move->piece = PAWN;
207 move->piece = PAWN; 224 move->tofile = fileidx(mstr[0]);
208 move->tofile = fileidx(mstr[0]); 225 move->torow = rowidx(mstr[1]);
209 move->torow = rowidx(mstr[1]);
210 }
211 } else if (len == 3) { 226 } else if (len == 3) {
212 if (strcmp(mstr, "O-O") == 0) { 227 if (strcmp(mstr, "O-O") == 0) {
213 /* king side castling */ 228 /* king side castling */
214 move->piece = KING; 229 move->piece = KING;
215 move->fromfile = fileidx('e'); 230 move->fromfile = fileidx('e');
216 move->tofile = fileidx('g'); 231 move->tofile = fileidx('g');
217 move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; 232 move->fromrow = move->torow = mycolor == WHITE ? 0 : 7;
218 } else { 233 } else {
219 /* unambiguous move (e.g. "Nf3") */ 234 /* move (e.g. "Nf3") */
220 move->piece = getpiece(mstr[0]); 235 move->piece = getpiece(mstr[0]);
221 move->tofile = isfile(mstr[1]) ? fileidx(mstr[1]) : POS_UNSPECIFIED; 236 move->tofile = fileidx(mstr[1]);
222 move->torow = isrow(mstr[2]) ? fileidx(mstr[2]) : POS_UNSPECIFIED; 237 move->torow = rowidx(mstr[2]);
223 } 238 }
224 239
225 } else if (len == 4) { 240 } else if (len == 4) {
226 /* ambiguous move (e.g. "Ndf3") */ 241 move->piece = getpiece(mstr[0]);
227 242 if (mstr[1] == 'x') {
228 /* unambiguous capture (e.g. "Nxf3", "dxe5") */ 243 /* capture (e.g. "Nxf3", "dxe5") */
229 244 move->capture = TRUE;
245 if (!move->piece) {
246 move->piece = PAWN;
247 move->fromfile = fileidx(mstr[0]);
248 }
249 } else {
250 /* move (e.g. "Ndf3") */
251 move->fromfile = fileidx(mstr[1]);
252 }
253 move->tofile = fileidx(mstr[2]);
254 move->torow = rowidx(mstr[3]);
230 } else if (len == 5) { 255 } else if (len == 5) {
231 if (strcmp(mstr, "O-O-O") == 0) { 256 if (strcmp(mstr, "O-O-O") == 0) {
232 /* queen side castling "O-O-O" */ 257 /* queen side castling "O-O-O" */
233 move->piece = KING; 258 move->piece = KING;
234 move->fromfile = fileidx('e'); 259 move->fromfile = fileidx('e');
235 move->tofile = fileidx('c'); 260 move->tofile = fileidx('c');
236 move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; 261 move->fromrow = move->torow = mycolor == WHITE ? 0 : 7;
237 } else { 262 } else {
238 /* ambiguous capture (e.g. "Ndxf3") */ 263 move->piece = getpiece(mstr[0]);
239 264 if (mstr[2] == 'x') {
240 /* long notation move (e.g. "Nc5a4") */ 265 move->capture = TRUE;
241 266 if (move->piece) {
242 /* long notation capture (e.g. "e5xf6") */ 267 /* capture (e.g. "Ndxf3") */
268 move->fromfile = fileidx(mstr[1]);
269 } else {
270 /* long notation capture (e.g. "e5xf6") */
271 move->piece = PAWN;
272 move->fromfile = fileidx(mstr[0]);
273 move->fromrow = rowidx(mstr[1]);
274 }
275 } else {
276 /* long notation move (e.g. "Nc5a4") */
277 move->fromfile = fileidx(mstr[1]);
278 move->fromrow = rowidx(mstr[2]);
279 }
280 move->tofile = fileidx(mstr[3]);
281 move->torow = rowidx(mstr[4]);
243 } 282 }
244 } else if (len == 6) { 283 } else if (len == 6) {
245 /* long notation capture (e.g. "Nc5xf3") */ 284 /* long notation capture (e.g. "Nc5xf3") */
246 } 285 if (mstr[3] == 'x') {
247 286 move->capture = TRUE;
287 move->piece = getpiece(mstr[0]);
288 move->fromfile = fileidx(mstr[1]);
289 move->fromrow = rowidx(mstr[2]);
290 move->tofile = fileidx(mstr[4]);
291 move->torow = rowidx(mstr[5]);
292 }
293 }
294
295
248 if (move->piece) { 296 if (move->piece) {
249 move->piece |= mycolor; 297 move->piece |= mycolor;
250 } 298 if (move->fromfile == POS_UNSPECIFIED
251 299 || move->fromrow == POS_UNSPECIFIED) {
252 if (!getlocation(board, move)) { 300 return getlocation(board, move) && chkidx(move);
253 // TODO: return status code to indicate the error type 301 } else {
254 move->piece = 0; 302 return chkidx(move);
255 } 303 }
256 304 } else {
257 return move->piece != 0; 305 return FALSE;
306 }
307 // TODO: return status code to indicate the error type
258 } 308 }
259 309
260 static int sendmove(Board board, uint8_t mycolor, int opponent) { 310 static int sendmove(Board board, uint8_t mycolor, int opponent) {
261 const size_t buflen = 8; 311 const size_t buflen = 8;
262 char movestr[buflen]; 312 char movestr[buflen];

mercurial