diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/bot.cpp | 147 | ||||
| -rw-r--r-- | src/evaluate.cpp | 8 | ||||
| -rw-r--r-- | src/evaluate.hpp | 5 |
3 files changed, 57 insertions, 103 deletions
diff --git a/src/bot.cpp b/src/bot.cpp index c269665..b5d2b57 100644 --- a/src/bot.cpp +++ b/src/bot.cpp @@ -11,11 +11,10 @@ #include <ctime> #include <iostream> #include <iterator> -#include <limits> #include <vector> constexpr int MAXIMUM_DEPTH = 10; -constexpr int MAXIMUM_TIME_PER_MOVE = 6; +constexpr int MAXIMUM_TIME_PER_MOVE = 7; constexpr int Q_DEPTH_LIMIT = 4; constexpr int MATE = 10000; @@ -79,15 +78,16 @@ static std::vector<Move> GetSortedLegalMoves(Game *g, bool generateQuietMoves, // faster than a real mate-in-1). White perspective throughout. static int quiescenceSearch(Game *b, int qdepth, int alpha, int beta, int ply) { // Runs GetNewGameState internally, so b->state is up to date afterwards. - const int standPat = EvaluateBoardForWhite(b); + const int standPat = EvaluateBoard(b); switch (b->state) { case WHITE_WON: - return MATE - ply; // black is mated case BLACK_WON: - return -(MATE - ply); // white is mated + return -(MATE - ply); + break; case DRAW: return 0; + break; case TURN: break; } @@ -96,48 +96,28 @@ static int quiescenceSearch(Game *b, int qdepth, int alpha, int beta, int ply) { return standPat; } - auto moves = GetSortedLegalMoves(b, false, nullptr); + if (standPat >= beta) { + return beta; + } + alpha = std::max(alpha, standPat); - if (b->turn) { - if (standPat >= beta) { - return beta; - } - alpha = std::max(alpha, standPat); + auto moves = GetSortedLegalMoves(b, false, nullptr); - for (Move move : moves) { - UndoMove undo = MakeMove(move, b); + for (Move move : moves) { + UndoMove undo = MakeMove(move, b); - int score = quiescenceSearch(b, qdepth + 1, alpha, beta, ply + 1); + int score = -quiescenceSearch(b, qdepth + 1, -beta, -alpha, ply + 1); - UnMakeMove(undo, b); + UnMakeMove(undo, b); - if (score >= beta) { - return beta; - } - alpha = std::max(alpha, score); - } - return alpha; - } else { - if (standPat <= alpha) { - return alpha; + if (score >= beta) { + return beta; } - beta = std::min(beta, standPat); - - for (Move move : moves) { - UndoMove undo = MakeMove(move, b); - - int score = quiescenceSearch(b, qdepth + 1, alpha, beta, ply + 1); - - UnMakeMove(undo, b); + alpha = std::max(alpha, score); + }; + return alpha; +}; - if (score <= alpha) { - return alpha; - } - beta = std::min(beta, score); - } - return beta; - } -} static int search(int depth, Game *b, int alpha, int beta, int ply) { const uint64_t gameHash = GenerateZobristKey(b); @@ -176,72 +156,43 @@ static int search(int depth, Game *b, int alpha, int beta, int ply) { if (moves.empty()) { const Position king = FindKing(b, b->turn); if (IsSquareAttacked(b, king, !b->turn)) { - return b->turn ? -(MATE - ply) : (MATE - ply); // mated + return -(MATE - ply); // mated } return 0; // stalemate } Move bestMove = moves[0]; const int alphaOrig = alpha; + int bestScore = -INF; - if (b->turn) { // white maximizes - int bestScore = std::numeric_limits<int>::lowest(); - - for (Move move : moves) { - UndoMove undo = MakeMove(move, b); + for (Move move : moves) { + UndoMove undo = MakeMove(move, b); - int score = search(depth - 1, b, alpha, beta, ply + 1); + int score = -search(depth - 1, b, -beta, -alpha, ply + 1); - UnMakeMove(undo, b); + UnMakeMove(undo, b); - if (score > bestScore) { - bestScore = score; - bestMove = move; - } - alpha = std::max(alpha, score); - if (alpha >= beta) { - break; - } + if (score > bestScore) { + bestScore = score; + bestMove = move; } - - const Flag flag = bestScore <= alphaOrig ? UPPERBOUND - : bestScore >= beta ? LOWERBOUND - : EXACT; - (*b->Transpositions)[gameHash] = { - .depth = depth, .Eval = bestScore, .flag = flag, .bestMove = bestMove}; - return bestScore; - } else { // black minimizes - int bestScore = std::numeric_limits<int>::max(); - - for (Move move : moves) { - UndoMove undo = MakeMove(move, b); - - int score = search(depth - 1, b, alpha, beta, ply + 1); - - UnMakeMove(undo, b); - - if (score < bestScore) { - bestScore = score; - bestMove = move; - } - beta = std::min(beta, score); - if (alpha >= beta) { - break; - } + alpha = std::max(alpha, score); + if (alpha >= beta) { + break; } - - const Flag flag = bestScore <= alphaOrig ? UPPERBOUND - : bestScore >= beta ? LOWERBOUND - : EXACT; - (*b->Transpositions)[gameHash] = { - .depth = depth, .Eval = bestScore, .flag = flag, .bestMove = bestMove}; - return bestScore; } + + const Flag flag = bestScore <= alphaOrig ? UPPERBOUND + : bestScore >= beta ? LOWERBOUND + : EXACT; + (*b->Transpositions)[gameHash] = { + .depth = depth, .Eval = bestScore, .flag = flag, .bestMove = bestMove}; + return bestScore; } struct SearchResult { Move bestMove; - int score; // white perspective + int score; }; // Searches every root move to `depth` plies and returns the best one. @@ -255,26 +206,18 @@ static SearchResult SearchDepth(Game *b, int depth, const Move *previousBest) { } Move bestMove = moves[0]; - int bestEval = b->turn ? std::numeric_limits<int>::lowest() - : std::numeric_limits<int>::max(); + int bestEval = -INF; for (Move move : moves) { UndoMove undo = MakeMove(move, b); - int eval = search(depth - 1, b, -INF, INF, 1); + int eval = -search(depth - 1, b, -INF, INF, 1); UnMakeMove(undo, b); - if (b->turn) { - if (eval > bestEval) { - bestEval = eval; - bestMove = move; - } - } else { - if (eval < bestEval) { - bestEval = eval; - bestMove = move; - } + if (eval > bestEval) { + bestEval = eval; + bestMove = move; } } diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 3e4f72f..8b9ff3d 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -78,6 +78,11 @@ static int KING_TABLE_EARLY[64] = { 20, 30, 10, 0, 0, 10, 30, 20, // }; +int EvaluateBoard(Game *g) { + int score = EvaluateBoardForWhite(g); + return g->turn ? score : score * -1; +}; + /* * i cound have come up with better name. * this function just takes square and if color is black rotate it @@ -181,7 +186,8 @@ bool IsEndgame(const Game *g) { } int EvaluateBoardForWhite(Game *g) { - switch (GetNewGameState(g)) { + g->state = GetNewGameState(g); + switch (g->state) { case WHITE_WON: return MATE; case BLACK_WON: diff --git a/src/evaluate.hpp b/src/evaluate.hpp index 66b362d..0bb9654 100644 --- a/src/evaluate.hpp +++ b/src/evaluate.hpp @@ -9,6 +9,11 @@ */ int EvaluateBoardForWhite(Game *g); +/* + * Evaluate board for white wrapper that return score for current player + */ +int EvaluateBoard(Game *g); + bool IsEndgame(const Game *g); #endif /* SRC_EVALUATE_H_ */ |
