src/chess/rules.h

changeset 195
27d02ccb0cef
parent 194
619f07c95894
equal deleted inserted replaced
194:619f07c95894 195:27d02ccb0cef
199 static inline char rankchr(Rank rank) {return (char)rank+'1';} 199 static inline char rankchr(Rank rank) {return (char)rank+'1';}
200 static inline char filechr(File file) {return (char)file+'a';} 200 static inline char filechr(File file) {return (char)file+'a';}
201 201
202 202
203 static inline void enpassant_threat_add(GameState *gamestate, 203 static inline void enpassant_threat_add(GameState *gamestate,
204 Rank rank, File file) { 204 File file, Rank rank) {
205 gamestate->board[rank][file] |= ENPASSANT_THREAT; 205 gamestate->board[rank][file] |= ENPASSANT_THREAT;
206 } 206 }
207 207
208 static inline void enpassant_threat_remove(GameState *gamestate, 208 static inline void enpassant_threat_remove(GameState *gamestate,
209 Rank rank, File file) { 209 File file, Rank rank) {
210 gamestate->board[rank][file] &= ~ENPASSANT_THREAT; 210 gamestate->board[rank][file] &= ~ENPASSANT_THREAT;
211 } 211 }
212 212
213 static inline bool enpassant_threat_exists(const GameState *gamestate, 213 static inline bool enpassant_threat_exists(const GameState *gamestate,
214 Rank rank, File file) { 214 File file, Rank rank) {
215 return gamestate->board[rank][file] & ENPASSANT_THREAT; 215 return gamestate->board[rank][file] & ENPASSANT_THREAT;
216 } 216 }
217 217
218 static inline bool is_game_drawn(const GameState *gamestate) { 218 static inline bool is_game_drawn(const GameState *gamestate) {
219 return gamestate->threefold || gamestate->stalemate 219 return gamestate->threefold || gamestate->stalemate
227 227
228 static inline bool is_check_position(const GameState *gamestate) { 228 static inline bool is_check_position(const GameState *gamestate) {
229 return gamestate->moves[gamestate->movecount - 1].check; 229 return gamestate->moves[gamestate->movecount - 1].check;
230 } 230 }
231 231
232 static inline Color field_color(Rank r, File f) { 232 static inline Color field_color(File f, Rank r) {
233 return (r + f) % 2 == 0 ? BLACK : WHITE; 233 return (r + f) % 2 == 0 ? BLACK : WHITE;
234 } 234 }
235 235
236 /** 236 /**
237 * Initializes a game state and prepares the chess board. 237 * Initializes a game state and prepares the chess board.
287 287
288 /** 288 /**
289 * Returns the piece at the specified position. 289 * Returns the piece at the specified position.
290 * 290 *
291 * @param gamestate the current game state 291 * @param gamestate the current game state
292 * @param file the file
292 * @param rank the rank 293 * @param rank the rank
294 * @return the piece at the specified position
295 */
296 Piece piece_at(const GameState *gamestate, File file, Rank rank);
297
298 /**
299 * Places a piece at the specified position in the current game state.
300 *
301 * @param gamestate the current game state
293 * @param file the file 302 * @param file the file
294 * @return the piece at the specified position
295 */
296 Piece piece_at(const GameState *gamestate, Rank rank, File file);
297
298 /**
299 * Places a piece at the specified position in the current game state.
300 *
301 * @param gamestate the current game state
302 * @param rank the rank 303 * @param rank the rank
304 * @param piece the piece to place at the specified position
305 */
306 void piece_set(GameState *gamestate, File file, Rank rank, Piece piece);
307
308 /**
309 * Removes the piece at the specified position in the current game state.
310 *
311 * @param gamestate the current game state
303 * @param file the file 312 * @param file the file
304 * @param piece the piece to place at the specified position
305 */
306 void piece_set(GameState *gamestate, Rank rank, File file, Piece piece);
307
308 /**
309 * Removes the piece at the specified position in the current game state.
310 *
311 * @param gamestate the current game state
312 * @param rank the rank 313 * @param rank the rank
313 * @param file the file 314 */
314 */ 315 static inline void piece_remove(GameState *gamestate, File file, Rank rank) {
315 static inline void piece_remove(GameState *gamestate, Rank rank, File file) { 316 piece_set(gamestate, file, rank, 0);
316 piece_set(gamestate, rank, file, 0);
317 } 317 }
318 318
319 typedef size_t(*moves_generator_func)(const GameState *gamestate, 319 typedef size_t(*moves_generator_func)(const GameState *gamestate,
320 Color c, Rank r, File f, Move *moves); 320 Color c, File f, Rank r, Move *moves);
321 321
322 /** 322 /**
323 * Calculates all allowed moves for a specific piece. 323 * Calculates all allowed moves for a specific piece.
324 * 324 *
325 * Use the macros for the specific pieces instead. 325 * Use the macros for the specific pieces instead.
326 * 326 *
327 * @param gamestate the current gamestate 327 * @param gamestate the current gamestate
328 * @param f the file of the piece
328 * @param r the rank of the piece 329 * @param r the rank of the piece
329 * @param f the file of the piece
330 * @param moves target array for the list of moves 330 * @param moves target array for the list of moves
331 * @return the number of moves stored in the @p moves array 331 * @return the number of moves stored in the @p moves array
332 */ 332 */
333 size_t piece_moves_allowed(const GameState *gamestate, 333 size_t piece_moves_allowed(const GameState *gamestate,
334 Rank r, File f, Move *moves); 334 File f, Rank r, Move *moves);
335 335
336 /** 336 /**
337 * Internal function used to filter out illegal moves. 337 * Internal function used to filter out illegal moves.
338 * 338 *
339 * Use the macros for the specific pieces instead. 339 * Use the macros for the specific pieces instead.
340 * 340 *
341 * @param gamestate the current gamestate 341 * @param gamestate the current gamestate
342 * @param c color of the piece 342 * @param c color of the piece
343 * @param f the file of the piece
343 * @param r the rank of the piece 344 * @param r the rank of the piece
344 * @param f the file of the piece
345 * @param moves target array for the list of moves 345 * @param moves target array for the list of moves
346 * @param func a function that unconditionally generates the moves 346 * @param func a function that unconditionally generates the moves
347 * @return the number of moves stored in the @p moves array 347 * @return the number of moves stored in the @p moves array
348 */ 348 */
349 size_t filter_moves_allowed(const GameState *gamestate, 349 size_t filter_moves_allowed(const GameState *gamestate,
350 Color c, Rank r, File f, Move *moves, moves_generator_func func); 350 Color c, File f, Rank r, Move *moves, moves_generator_func func);
351 351
352 /** 352 /**
353 * Determines a list of theoretically possible moves to the specified field. 353 * Determines a list of theoretically possible moves to the specified field.
354 * 354 *
355 * This will also list moves for pieces that are actually pinned. 355 * This will also list moves for pieces that are actually pinned.
357 * 357 *
358 * The out-parameters may both be NULL, but if any of them is set, the other 358 * The out-parameters may both be NULL, but if any of them is set, the other
359 * must be set, too. 359 * must be set, too.
360 * 360 *
361 * @param gamestate the current game state 361 * @param gamestate the current game state
362 * @param file file of the field to check
362 * @param rank rank of the field to check 363 * @param rank rank of the field to check
363 * @param file file of the field to check
364 * @param color the color of the piece that should move to the field 364 * @param color the color of the piece that should move to the field
365 * @param moves the array where to store the moves 365 * @param moves the array where to store the moves
366 * (must be large enough, 16 is always enough) 366 * (must be large enough, 16 is always enough)
367 * @param movecount a pointer where the number of moves is stored 367 * @param movecount a pointer where the number of moves is stored
368 * @return true, if any piece of the specified color can move to the specified 368 * @return true, if any piece of the specified color can move to the specified
369 * field regardless of being pinned 369 * field regardless of being pinned
370 */ 370 */
371 bool get_candidates(const GameState *gamestate, Rank rank, File file, 371 bool get_candidates(const GameState *gamestate, File file, Rank rank,
372 Color color, Move* moves, size_t* movecount); 372 Color color, Move* moves, size_t* movecount);
373 373
374 /** 374 /**
375 * Determines a list of possible moves to the specified field. 375 * Determines a list of possible moves to the specified field.
376 * 376 *
380 * 380 *
381 * The out-parameters may both be NULL, but if any of them is set, the other 381 * The out-parameters may both be NULL, but if any of them is set, the other
382 * must be set, too. 382 * must be set, too.
383 * 383 *
384 * @param gamestate the current game state 384 * @param gamestate the current game state
385 * @param file file of the field to check
385 * @param rank rank of the field to check 386 * @param rank rank of the field to check
386 * @param file file of the field to check
387 * @param color the color of the piece that should move to the field 387 * @param color the color of the piece that should move to the field
388 * @param moves the array where to store the moves 388 * @param moves the array where to store the moves
389 * (must be large enough, 16 is always enough) 389 * (must be large enough, 16 is always enough)
390 * @param movecount a pointer where the number of moves is stored 390 * @param movecount a pointer where the number of moves is stored
391 * @return true, if any piece of the specified color can move to the specified 391 * @return true, if any piece of the specified color can move to the specified
392 * field and is not pinned 392 * field and is not pinned
393 */ 393 */
394 bool get_real_candidates(const GameState *gamestate, Rank rank, File file, 394 bool get_real_candidates(const GameState *gamestate, File file, Rank rank,
395 Color color, Move* moves, size_t* movecount); 395 Color color, Move* moves, size_t* movecount);
396 396
397 /** 397 /**
398 * Checks, if a specified field is threatened by a piece of a certain color. 398 * Checks, if a specified field is threatened by a piece of a certain color.
399 * 399 *
402 * 402 *
403 * The out-parameters may both be NULL, but if any of them is set, the other 403 * The out-parameters may both be NULL, but if any of them is set, the other
404 * must be set, too. 404 * must be set, too.
405 * 405 *
406 * @param gamestate the current game state 406 * @param gamestate the current game state
407 * @param file file of the field to check
407 * @param rank rank of the field to check 408 * @param rank rank of the field to check
408 * @param file file of the field to check
409 * @param color the color of the piece that should threaten the field 409 * @param color the color of the piece that should threaten the field
410 * @param threats the array where to store the threats 410 * @param threats the array where to store the threats
411 * (must be large enough, 16 is always enough) 411 * (must be large enough, 16 is always enough)
412 * @param threatcount a pointer where the count of threats is stored 412 * @param threatcount a pointer where the count of threats is stored
413 * @return true, if any piece of the specified color threatens the specified 413 * @return true, if any piece of the specified color threatens the specified
414 * field 414 * field
415 */ 415 */
416 bool get_threats(const GameState *gamestate, Rank rank, File file, 416 bool get_threats(const GameState *gamestate, File file, Rank rank,
417 Color color, Move* threats, size_t* threatcount); 417 Color color, Move* threats, size_t* threatcount);
418 418
419 /** 419 /**
420 * Checks, if a specified field is threatened by a piece of a certain color AND 420 * Checks, if a specified field is threatened by a piece of a certain color AND
421 * if this piece is not pinned and therefore able to perform the move. 421 * if this piece is not pinned and therefore able to perform the move.
422 * 422 *
423 * The out-parameters may both be NULL, but if any of them is set, the other 423 * The out-parameters may both be NULL, but if any of them is set, the other
424 * must be set, too. 424 * must be set, too.
425 * 425 *
426 * @param gamestate the current game state 426 * @param gamestate the current game state
427 * @param file file of the field to check
427 * @param rank rank of the field to check 428 * @param rank rank of the field to check
428 * @param file file of the field to check
429 * @param color the color of the piece that should threaten the field 429 * @param color the color of the piece that should threaten the field
430 * @param threats the array where to store the threats 430 * @param threats the array where to store the threats
431 * (must be large enough, 16 is always enough) 431 * (must be large enough, 16 is always enough)
432 * @param threatcount a pointer where the count of threats is stored 432 * @param threatcount a pointer where the count of threats is stored
433 * @return true, if any piece of the specified color threatens the specified 433 * @return true, if any piece of the specified color threatens the specified
434 * field and is not pinned 434 * field and is not pinned
435 */ 435 */
436 bool get_real_threats(const GameState *gamestate, Rank rank, File file, 436 bool get_real_threats(const GameState *gamestate, File file, Rank rank,
437 Color color, Move* threats, size_t* threatcount); 437 Color color, Move* threats, size_t* threatcount);
438 438
439 /** 439 /**
440 * Checks, if a specified field is threatened by a piece of a certain color. 440 * Checks, if a specified field is threatened by a piece of a certain color.
441 * 441 *
442 * A field is threatened, if there is a piece of the specified color that could 442 * A field is threatened, if there is a piece of the specified color that could
443 * capture an opponent piece on this field, regardless of being pinned. 443 * capture an opponent piece on this field, regardless of being pinned.
444 * 444 *
445 * @param gamestate the current game state 445 * @param gamestate the current game state
446 * @param file file of the field to check
446 * @param rank rank of the field to check 447 * @param rank rank of the field to check
447 * @param file file of the field to check
448 * @param color the color of the piece that should cover the field 448 * @param color the color of the piece that should cover the field
449 * @return true, if any piece of the specified color threatens the specified 449 * @return true, if any piece of the specified color threatens the specified
450 * field 450 * field
451 */ 451 */
452 #define is_covered(gamestate, rank, file, color) \ 452 #define is_covered(gamestate, file, rank, color) \
453 get_threats(gamestate, rank, file, color, NULL, NULL) 453 get_threats(gamestate, file, rank, color, NULL, NULL)
454 454
455 /** 455 /**
456 * Checks, if a specified field is attacked by a piece of a certain color. 456 * Checks, if a specified field is attacked by a piece of a certain color.
457 * 457 *
458 * I.e. the field is threatened by a piece AND this piece is not pinned and 458 * I.e. the field is threatened by a piece AND this piece is not pinned and
459 * therefore able to perform the move. 459 * therefore able to perform the move.
460 * 460 *
461 * @param gamestate the current game state 461 * @param gamestate the current game state
462 * @param file file of the field to check
462 * @param rank rank of the field to check 463 * @param rank rank of the field to check
463 * @param file file of the field to check
464 * @param color the color of the piece that should cover the field 464 * @param color the color of the piece that should cover the field
465 * @return true, if any piece of the specified color threatens the specified 465 * @return true, if any piece of the specified color threatens the specified
466 * field and could capture an opponent piece 466 * field and could capture an opponent piece
467 */ 467 */
468 #define is_attacked(gamestate, rank, file, color) \ 468 #define is_attacked(gamestate, file, rank, color) \
469 get_real_threats(gamestate, rank, file, color, NULL, NULL) 469 get_real_threats(gamestate, file, rank, color, NULL, NULL)
470 470
471 /** 471 /**
472 * Checks, if a specified field is protected by a piece of a certain color. 472 * Checks, if a specified field is protected by a piece of a certain color.
473 * 473 *
474 * A field is protected, if any piece except the king can either capture on 474 * A field is protected, if any piece except the king can either capture on
475 * that field or move to that field (and is not pinned). 475 * that field or move to that field (and is not pinned).
476 * 476 *
477 * @param gamestate the current game state 477 * @param gamestate the current game state
478 * @param file file of the field to check
478 * @param rank rank of the field to check 479 * @param rank rank of the field to check
479 * @param file file of the field to check
480 * @param color the color of the piece that should cover the field 480 * @param color the color of the piece that should cover the field
481 * @return true, if any piece (excluding the king) of the specified color 481 * @return true, if any piece (excluding the king) of the specified color
482 * can move to the specified field (including capturing moves) 482 * can move to the specified field (including capturing moves)
483 */ 483 */
484 bool is_protected(const GameState *gamestate, Rank rank, File file, Color color); 484 bool is_protected(const GameState *gamestate,
485 File file, Rank rank, Color color);
485 486
486 /** 487 /**
487 * Checks, if the specified move cannot be performed, because the piece is 488 * Checks, if the specified move cannot be performed, because the piece is
488 * either pinned or cannot remove the check. 489 * either pinned or cannot remove the check.
489 * 490 *

mercurial