From b7ad7b31111927e341bdacfae8a2c3893c5c6321 Mon Sep 17 00:00:00 2001 From: Karma Riuk Date: Sun, 2 Feb 2025 21:14:14 +0100 Subject: [PATCH] implemented king legal moves --- cpp/src/pieces/king.cpp | 76 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 cpp/src/pieces/king.cpp diff --git a/cpp/src/pieces/king.cpp b/cpp/src/pieces/king.cpp new file mode 100644 index 0000000..47735c2 --- /dev/null +++ b/cpp/src/pieces/king.cpp @@ -0,0 +1,76 @@ +#include "../board.hpp" +#include "../coords.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()); + if (board_after_move.is_check_for(b.colour_at(xy))) + 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()); + if (dx < 3 && board_after_move.is_check_for(b.colour_at(xy))) + 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_for(b.colour_at(xy))) + return ret; + + // -- Castles + CastleSide castling_rights = b.colour_at(xy) == Colour::White + ? b.w_castle_rights + : b.b_castle_rights; + + if (castling_rights == CastleSide::Neither) + return ret; + + if (castling_rights == CastleSide::King && is_clear_king_side(b, xy)) { + ret.push_back(Move{ + xy.to_index(), + Coords{6, xy.y}.to_index(), + .castle_side = CastleSide::King + }); + } + + if (castling_rights == CastleSide::Queen && is_clear_queen_side(b, xy)) { + ret.push_back(Move{ + xy.to_index(), + Coords{2, xy.y}.to_index(), + .castle_side = CastleSide::Queen + }); + } + + return ret; +}