caching checks and no legal moves

This commit is contained in:
Karma Riuk 2025-02-07 14:15:10 +01:00
parent 182d183247
commit 8edde1a8b1
2 changed files with 24 additions and 9 deletions

View File

@ -94,6 +94,10 @@ Board Board::setup_fen_position(std::string fen) {
index = fen.find(' ', index) + 1; index = fen.find(' ', index) + 1;
board.n_full_moves = std::stoi(fen.substr(index)); board.n_full_moves = std::stoi(fen.substr(index));
board.w_check = board.is_check_for(White);
board.b_check = board.is_check_for(Black);
board.w_nlm = board.no_legal_moves_for(White);
board.b_nlm = board.no_legal_moves_for(Black);
return board; return board;
} }
@ -312,10 +316,11 @@ int8_t Board::get_king_of(int8_t colour) const {
bool Board::is_check_for(int8_t colour) const { bool Board::is_check_for(int8_t colour) const {
int8_t king_idx = this->get_king_of(colour); int8_t king_idx = this->get_king_of(colour);
for (int i = 0; i < 64; i++) { std::vector<Move> all_moves;
all_moves.reserve(50);
for (int8_t i = 0; i < 64; i++) {
if (this->squares[i] == Piece::None || colour_at(i) == colour) if (this->squares[i] == Piece::None || colour_at(i) == colour)
continue; continue;
std::vector<int8_t> targets;
if (piece_at(i) == King) { if (piece_at(i) == King) {
// special case for the king, because it creates infinite recursion // special case for the king, because it creates infinite recursion
// (since he looks if he's walking into a check) // (since he looks if he's walking into a check)
@ -324,7 +329,7 @@ bool Board::is_check_for(int8_t colour) const {
for (int dy = -1; dy <= 1; dy++) { for (int dy = -1; dy <= 1; dy++) {
Coords c{king_pos.x + dx, king_pos.y + dy}; Coords c{king_pos.x + dx, king_pos.y + dy};
if (c.is_within_bounds()) if (c.is_within_bounds())
targets.push_back(c.to_index()); all_moves.push_back(Move{i, c.to_index()});
} }
} }
} else { } else {
@ -334,11 +339,14 @@ bool Board::is_check_for(int8_t colour) const {
Coords::from_index(i), Coords::from_index(i),
true true
); );
targets = to_target_square(moves);
all_moves.insert(all_moves.end(), moves.begin(), moves.end());
} }
if (std::find(targets.begin(), targets.end(), king_idx)
!= targets.end()) for (const Move& move : all_moves)
return true; if (move.target_square == king_idx)
return true;
all_moves.clear();
} }
return false; return false;
} }

View File

@ -10,6 +10,7 @@ struct Board {
private: private:
int8_t get_king_of(int8_t) const; int8_t get_king_of(int8_t) const;
bool no_legal_moves_for(int8_t) const; bool no_legal_moves_for(int8_t) const;
bool w_nlm = false, b_nlm = false, w_check = false, b_check = false;
public: public:
int8_t squares[64] = {Piece::None}; int8_t squares[64] = {Piece::None};
@ -35,11 +36,17 @@ struct Board {
std::vector<Move> all_legal_moves() const; std::vector<Move> all_legal_moves() const;
bool is_checkmate_for(int8_t colour) const { bool is_checkmate_for(int8_t colour) const {
return is_check_for(colour) && no_legal_moves_for(colour); if (colour == White)
return w_nlm && w_check;
return b_nlm && b_check;
// return no_legal_moves_for(colour) && is_check_for(colour);
} }
bool is_stalemate_for(int8_t colour) const { bool is_stalemate_for(int8_t colour) const {
return !is_check_for(colour) && no_legal_moves_for(colour); if (colour == White)
return w_nlm && !w_check;
return b_nlm && !b_check;
// return no_legal_moves_for(colour) && !is_check_for(colour);
} }
bool is_terminal() const { bool is_terminal() const {