From 05035f72d77a18321d39e118ed28858b8c25bdad Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 21 Aug 2026 18:35:02 +0200 Subject: refactor(search): making code nicer and little faster --- src/board/board.cpp | 8 -------- src/board/board.hpp | 2 -- src/bot.cpp | 51 ++++++++++++++++++++++++++++----------------------- src/evaluate.cpp | 12 ------------ src/moves.cpp | 32 +++++++++++++++----------------- src/moves.hpp | 2 +- src/uci.cpp | 1 - 7 files changed, 44 insertions(+), 64 deletions(-) diff --git a/src/board/board.cpp b/src/board/board.cpp index 7084c9d..48d0975 100644 --- a/src/board/board.cpp +++ b/src/board/board.cpp @@ -169,8 +169,6 @@ Undo MakeMove(uint16_t move, Game *g) { undo.oldHalfMoveClock = g->halfMoveClock; undo.oldMoveClock = g->MoveClock; - undo.oldState = g->state; - undo.OldWhiteCastleKing = g->whiteCastleKing; undo.OldWhiteCastleQueen = g->whiteCastleQueen; undo.OldBlackCastleKing = g->blackCastleKing; @@ -196,10 +194,6 @@ Undo MakeMove(uint16_t move, Game *g) { g->halfMoveClock = 0; } - if (g->halfMoveClock >= 100) { - g->state = DRAW; - } - // Playing enpasstant xorEnpassantKey(g); // remove existing key @@ -408,8 +402,6 @@ void UndoMove(Undo undo, Game *g) { g->halfMoveClock = undo.oldHalfMoveClock; g->MoveClock = undo.oldMoveClock; - g->state = undo.oldState; - g->whiteCastleKing = undo.OldWhiteCastleKing; g->whiteCastleQueen = undo.OldWhiteCastleQueen; g->blackCastleKing = undo.OldBlackCastleKing; diff --git a/src/board/board.hpp b/src/board/board.hpp index f9947ed..1b3ded1 100644 --- a/src/board/board.hpp +++ b/src/board/board.hpp @@ -67,7 +67,6 @@ struct Game { int MoveClock = 0; Position enPassant; bool canEnpassant = false; - GameState state = TURN; uint64_t hash = 0; std::vector history; std::unordered_map *Transpositions = nullptr; @@ -98,7 +97,6 @@ struct Undo { int oldHalfMoveClock; int oldMoveClock; uint64_t Hash; - GameState oldState; // castling bool wasCastle = false; diff --git a/src/bot.cpp b/src/bot.cpp index 9e9b624..8fe491e 100644 --- a/src/bot.cpp +++ b/src/bot.cpp @@ -18,8 +18,8 @@ #include "hash.hpp" #include "moves.hpp" -constexpr int DEFAULT_TIME = 7; -constexpr int Q_DEPTH_LIMIT = 4; +constexpr int DEFAULT_TIME = 10; +constexpr int Q_DEPTH_LIMIT = 10; constexpr int BOOK_DEPTH = 100; constexpr int MATE = 10000; @@ -113,20 +113,21 @@ static int quiescenceSearch(Game *b, int qdepth, int alpha, int beta, int ply) { } } - const int standPat = EvaluateBoard(b); + auto moves = GetSortedLegalMoves(b, ALL, nullptr); - switch (b->state) { + GameState state = GetboardState(b, moves); + switch (state) { case WHITE_WON: case BLACK_WON: return -(MATE - ply); - break; case DRAW: return 0; - break; case TURN: break; } + const int standPat = EvaluateBoard(b); + if (qdepth >= Q_DEPTH_LIMIT) { return standPat; } @@ -136,9 +137,10 @@ static int quiescenceSearch(Game *b, int qdepth, int alpha, int beta, int ply) { } alpha = std::max(alpha, standPat); - auto moves = GetSortedLegalMoves(b, CAPTUARES_ONLY, nullptr); - for (uint16_t move : moves) { + if (((1ULL << getToValueFromMove(move)) & b->PieceBitboard) == 0) { + continue; + } Undo undo = MakeMove(move, b); int score = -quiescenceSearch(b, qdepth + 1, -beta, -alpha, ply + 1); @@ -155,7 +157,7 @@ static int quiescenceSearch(Game *b, int qdepth, int alpha, int beta, int ply) { }; return alpha; }; -static int search(int depth, Game *b, int alpha, int beta, int ply) { +static int search(int depth, Game *g, int alpha, int beta, int ply) { if (timeToThingMS == -1) { assert(false && "Expected set time: internal error"); exit(1); @@ -171,13 +173,13 @@ static int search(int depth, Game *b, int alpha, int beta, int ply) { return 0; } } - if (isRepetionDraw(b->hash, b)) { + if (isRepetionDraw(g->hash, g)) { return 0; }; TranspositionsEntry *entry = nullptr; - if (auto it = b->Transpositions->find(b->hash); - it != b->Transpositions->end()) { + if (auto it = g->Transpositions->find(g->hash); + it != g->Transpositions->end()) { entry = &it->second; if (entry->depth >= depth) { if (entry->flag == EXACT) { @@ -196,17 +198,20 @@ static int search(int depth, Game *b, int alpha, int beta, int ply) { } if (depth <= 0) { - return quiescenceSearch(b, 0, alpha, beta, ply); + return quiescenceSearch(g, 0, alpha, beta, ply); } uint16_t ttBestMove = entry != nullptr ? entry->bestMove : uint16_t{}; - std::vector moves = GetSortedLegalMoves(b, ALL, &ttBestMove); + std::vector moves = GetSortedLegalMoves(g, ALL, &ttBestMove); - if (moves.empty()) { - if (IsSquareAttacked(*b, FindKing(*b, b->turn), !b->turn)) { - return -(MATE - ply); // mated - } - return 0; // stalemate + switch (GetboardState(g, moves)) { + case WHITE_WON: + case BLACK_WON: + return -(MATE - ply); + case DRAW: + return 0; + case TURN: + break; } uint16_t bestMove = moves[0]; @@ -214,11 +219,11 @@ static int search(int depth, Game *b, int alpha, int beta, int ply) { int bestScore = -INF; for (uint16_t move : moves) { - Undo undo = MakeMove(move, b); + Undo undo = MakeMove(move, g); - int score = -search(depth - 1, b, -beta, -alpha, ply + 1); + int score = -search(depth - 1, g, -beta, -alpha, ply + 1); - UndoMove(undo, b); + UndoMove(undo, g); if (searchStopped) { break; } @@ -239,7 +244,7 @@ static int search(int depth, Game *b, int alpha, int beta, int ply) { flag = UPPERBOUND; } - (*b->Transpositions)[b->hash] = { + (*g->Transpositions)[g->hash] = { .depth = depth, .Eval = bestScore, .flag = flag, .bestMove = bestMove}; } return bestScore; diff --git a/src/evaluate.cpp b/src/evaluate.cpp index bb65c7f..7db6734 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -205,18 +205,6 @@ bool IsEndgame(const Game *g) { } int EvaluateBoardForWhite(Game *g) { - g->state = GetNewGameState(g); - switch (g->state) { - case WHITE_WON: - return MATE; - case BLACK_WON: - return -MATE; - case DRAW: - return 0; - case TURN: - break; - } - int score = 0; bool isEndGame = IsEndgame(g); diff --git a/src/moves.cpp b/src/moves.cpp index 8990621..9f75c25 100644 --- a/src/moves.cpp +++ b/src/moves.cpp @@ -594,26 +594,24 @@ bool IsSquareAttacked(const Game &g, Position square, bool byColor) { g.PieceBitboards[static_cast(byColor)][QUEEN]; return bishop_attacks > 0; } -GameState GetNewGameState(Game *g) { - // make sure we dont override game ending states - if (g->state == DRAW || g->state == WHITE_WON || g->state == BLACK_WON) { - return g->state; +GameState GetboardState(Game *g, const std::vector &moves) { + if (g->halfMoveClock >= 100) { + return DRAW; } - - auto legalMoves = GetLegalMoves(g, ALL); - - if (legalMoves.empty()) { - Position kingPosition = FindKing(*g, g->turn); - - bool check = IsSquareAttacked(*g, kingPosition, !g->turn); - - if (check) { - g->state = g->turn ? BLACK_WON : WHITE_WON; - } else { - g->state = DRAW; + if (isRepetionDraw(g->hash, g)) { + return DRAW; + }; + if (moves.empty()) { + const bool isCheck = IsSquareAttacked(*g, FindKing(*g, g->turn), !g->turn); + if (isCheck) { + if (g->turn) { + return BLACK_WON; + } + return WHITE_WON; } + return DRAW; } - return g->state; + return TURN; } static void GenerateCastlingMoves(const uint8_t &from, const Game &g, diff --git a/src/moves.hpp b/src/moves.hpp index 47e41c0..0e8174c 100644 --- a/src/moves.hpp +++ b/src/moves.hpp @@ -21,6 +21,6 @@ constexpr Position IndexToPosition(int i) { return {.rank = rank, .file = file}; } bool IsSquareAttacked(const Game &g, Position square, bool byColor); -GameState GetNewGameState(Game *g); +GameState GetboardState(Game *g, const std::vector &moves); #endif /* SRC_MOVES_H_ */ diff --git a/src/uci.cpp b/src/uci.cpp index e65bf73..7cff997 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -86,7 +86,6 @@ Game initBoard( Game g{}; g.enPassant = IndexToPosition(0); // default value g.canEnpassant = false; - g.state = TURN; g.turn = true; g.halfMoveClock = 0; g.MoveClock = 0; -- cgit v1.2.3