void chess_game_iterator_init(ChessGameIterator* iter, ChessGame* game) { iter->game = game; chess_position_copy(&game->initial_position, &iter->position); iter->variation = game->root_variation; chess_array_init(&iter->unmoves, sizeof(ChessUnmove)); }
static ChessBoolean move_is_legal(const ChessPosition* position, ChessMove move) { ChessPosition temp_position; chess_position_copy(position, &temp_position); chess_position_make_move(&temp_position, move); chess_position_set_to_move(&temp_position, chess_position_to_move(position)); return !chess_position_is_check(&temp_position); }
void chess_game_reset_position(ChessGame* game, const ChessPosition* position) { chess_position_copy(position, &game->initial_position); chess_variation_truncate(game->root_variation); game->result = chess_position_check_result(position); chess_string_clear(&game->event); chess_string_clear(&game->site); chess_string_clear(&game->date); chess_string_clear(&game->round); chess_string_clear(&game->white); chess_string_clear(&game->black); cleanup_extra_tags(game); game->extra = NULL; }
ChessGame* chess_game_new_position(const ChessPosition* position) { ChessGame* game = chess_alloc(sizeof(ChessGame)); memset(game, 0, sizeof(ChessGame)); chess_position_copy(position, &game->initial_position); game->root_variation = chess_variation_new(); chess_string_init(&game->event); chess_string_init(&game->site); chess_string_init(&game->date); chess_string_init(&game->round); chess_string_init(&game->white); chess_string_init(&game->black); return game; }
ChessBoolean chess_position_validate(ChessPosition* position) { ChessSquare sq, other_king; ChessRank rank; ChessPiece pc; ChessPosition temp_position; chess_position_copy(position, &temp_position); temp_position.wking = CHESS_SQUARE_INVALID; temp_position.bking = CHESS_SQUARE_INVALID; for (sq = CHESS_SQUARE_A1; sq <= CHESS_SQUARE_H8; ++sq) { pc = position->piece[sq]; if (pc == CHESS_PIECE_WHITE_KING) { if (temp_position.wking != CHESS_SQUARE_INVALID) return CHESS_FALSE; /* Too many white kings */ temp_position.wking = sq; } else if (pc == CHESS_PIECE_BLACK_KING) { if (temp_position.bking != CHESS_SQUARE_INVALID) return CHESS_FALSE; /* Too many black kings */ temp_position.bking = sq; } else if (pc == CHESS_PIECE_WHITE_PAWN || pc == CHESS_PIECE_BLACK_PAWN) { rank = chess_square_rank(sq); if (rank == CHESS_RANK_1 || rank == CHESS_RANK_8) { /* Pawn on first or last rank */ return CHESS_FALSE; } } } if (temp_position.wking == CHESS_SQUARE_INVALID || temp_position.bking == CHESS_SQUARE_INVALID) { /* No white king or black king */ return CHESS_FALSE; } /* Clear any impossible castling states */ if (temp_position.piece[CHESS_SQUARE_E1] != CHESS_PIECE_WHITE_KING) { temp_position.castle &= ~CHESS_CASTLE_STATE_WKQ; } if (temp_position.piece[CHESS_SQUARE_H1] != CHESS_PIECE_WHITE_ROOK) { temp_position.castle &= ~CHESS_CASTLE_STATE_WK; } if (temp_position.piece[CHESS_SQUARE_A1] != CHESS_PIECE_WHITE_ROOK) { temp_position.castle &= ~CHESS_CASTLE_STATE_WQ; } if (temp_position.piece[CHESS_SQUARE_E8] != CHESS_PIECE_BLACK_KING) { temp_position.castle &= ~CHESS_CASTLE_STATE_BKQ; } if (temp_position.piece[CHESS_SQUARE_H8] != CHESS_PIECE_BLACK_ROOK) { temp_position.castle &= ~CHESS_CASTLE_STATE_BK; } if (temp_position.piece[CHESS_SQUARE_A8] != CHESS_PIECE_BLACK_ROOK) { temp_position.castle &= ~CHESS_CASTLE_STATE_BQ; } /* Clear en passant state if it's not valid */ if (temp_position.ep != CHESS_FILE_INVALID) { /* Valid would mean that a pawn (possibly) just moved to its 4th rank */ if ((temp_position.to_move == CHESS_COLOR_WHITE && temp_position.piece[chess_square_from_fr(temp_position.ep, CHESS_RANK_5)] != CHESS_PIECE_BLACK_PAWN) || (temp_position.to_move == CHESS_COLOR_BLACK && temp_position.piece[chess_square_from_fr(temp_position.ep, CHESS_RANK_4)] != CHESS_PIECE_WHITE_PAWN)) { temp_position.ep = CHESS_FILE_INVALID; } } other_king = (temp_position.to_move == CHESS_COLOR_WHITE) ? temp_position.bking : temp_position.wking; if (chess_generate_is_square_attacked(&temp_position, other_king, temp_position.to_move)) { /* Opponent's king is en prise */ return CHESS_FALSE; } /* All checks passed! */ chess_position_copy(&temp_position, position); return CHESS_TRUE; }
void chess_game_iterator_step_to_start(ChessGameIterator* iter) { chess_position_copy(&iter->game->initial_position, &iter->position); iter->variation = iter->game->root_variation; chess_array_clear(&iter->unmoves); }
void chess_game_set_initial_position(ChessGame* game, const ChessPosition* position) { chess_position_copy(position, &game->initial_position); chess_variation_truncate(game->root_variation); }