#include "../board/board.hpp" #include "../utils/coords.hpp" #include "../utils/move.hpp" #include "piece.hpp" static bool is_clear_king_side(const Board& b, const Coords xy) { for (int dx = 1; dx < 3; dx++) { Coords c{xy.x + dx, xy.y}; if (b.squares[c.to_index()] != Piece::None) return false; std::optional move = move_for_position(b, xy, c); Board board_after_move = b.make_move(move.value(), false); board_after_move = board_after_move.skip_turn(); if (board_after_move.is_check()) return false; } return true; } static bool is_clear_queen_side(const Board& b, const Coords xy) { for (int dx = 1; dx < 4; dx++) { Coords c{xy.x - dx, xy.y}; if (b.squares[c.to_index()] != Piece::None) return false; std::optional move = move_for_position(b, xy, c); Board board_after_move = b.make_move(move.value(), false); board_after_move = board_after_move.skip_turn(); if (dx < 3 && board_after_move.is_check()) return false; } return true; } std::vector king_moves(const Board& b, const Coords xy) { std::vector ret; // -- Regular moves for (int dx = -1; dx <= 1; dx++) { for (int dy = -1; dy <= 1; dy++) { if (dx == 0 && dy == 0) // skip staying in the same position continue; Coords c{xy.x + dx, xy.y + dy}; std::optional move = move_for_position(b, xy, c); if (move.has_value()) ret.push_back(move.value()); } } if (b.is_check()) return keep_only_blocking(ret, b); // -- Castles int8_t castling_rights = b.colour_at(xy) == Colour::White ? b.w_castle_rights : b.b_castle_rights; if (castling_rights == CastleSide::NeitherSide) return ret; if (castling_rights & CastleSide::KingSide && is_clear_king_side(b, xy)) { ret.push_back(Move{ xy.to_index(), Coords{6, xy.y}.to_index(), }); } if (castling_rights & CastleSide::QueenSide && is_clear_queen_side(b, xy)) { ret.push_back(Move{ xy.to_index(), Coords{2, xy.y}.to_index(), }); } return ret; }