aboutsummaryrefslogtreecommitdiff
path: root/src/bot.cpp
diff options
context:
space:
mode:
authorAdam <adammegarules1@gmail.com>2026-08-15 17:01:54 +0200
committerAdam <adammegarules1@gmail.com>2026-08-15 17:01:54 +0200
commit4eb36e67eca586a662298bfe8cc5392fbfa698e0 (patch)
tree6c232d59d1566377fbaeec035f4f799618f63421 /src/bot.cpp
parentc1d6113da12bfbe92ae718d93dd56e25556e52cb (diff)
implementing memory optimazied move using uint16_t instead of a four integers and one byte
Diffstat (limited to 'src/bot.cpp')
-rw-r--r--src/bot.cpp76
1 files changed, 43 insertions, 33 deletions
diff --git a/src/bot.cpp b/src/bot.cpp
index 5db3939..43a76f4 100644
--- a/src/bot.cpp
+++ b/src/bot.cpp
@@ -1,9 +1,3 @@
-#include "bot.hpp"
-#include "board/board.hpp"
-#include "evaluate.hpp"
-#include "moves.hpp"
-#include "zobrist.hpp"
-
#include <algorithm>
#include <array>
#include <cassert>
@@ -16,6 +10,12 @@
#include <ratio>
#include <vector>
+#include "board/board.hpp"
+#include "bot.hpp"
+#include "evaluate.hpp"
+#include "moves.hpp"
+#include "zobrist.hpp"
+
constexpr int MAXIMUM_DEPTH = 10;
constexpr int MAXIMUM_TIME_PER_MOVE = 7;
constexpr int Q_DEPTH_LIMIT = 4;
@@ -33,8 +33,12 @@ double timeToThingMS = -1;
std::chrono::time_point<std::chrono::steady_clock> searchStartTime;
bool searchStopped = false;
-static int ScoreMove(const Game *board, const Move &move,
- const Move *bestMove) {
+static int ScoreMove(const Game *board, const uint16_t &move,
+ const uint16_t *bestMove) {
+ uint8_t from = getFromValueFromMove(move);
+ uint8_t to = getToValueFromMove(move);
+ PieceType promotion = getPromotionTypeFromMove(move);
+
// Indexed by PieceType (NONE, PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING).
static constexpr std::array<int, 7> PIECE_VALUES = {
0, // NONEPIECE
@@ -54,8 +58,8 @@ static int ScoreMove(const Game *board, const Move &move,
score += 1000000;
}
- const Piece moving = board->pieces[PositionToIndex(move.From)];
- const Piece captured = board->pieces[PositionToIndex(move.To)];
+ const Piece moving = board->pieces[from];
+ const Piece captured = board->pieces[to];
// MVV-LVA: value the capture by what we win, penalise by what we spend.
if (captured.type != NONEPIECE) {
@@ -64,21 +68,27 @@ static int ScoreMove(const Game *board, const Move &move,
score -= PIECE_VALUES[moving.type];
}
- if (move.promotion != NONEPIECE) {
- score += 8000;
+ // promotion bonus
+ if (IndexToPosition(to).rank == (board->turn ? 7 : 0)) {
+ if (promotion == QUEEN) {
+ score += 8000;
+ }
+ score += 3000;
}
- if (move.To.rank == (board->turn ? 6 : 1) && moving.type == PAWN) {
+ if (IndexToPosition(to).rank == (board->turn ? 6 : 1) &&
+ moving.type == PAWN) {
score += 8000;
}
return score;
}
-static std::vector<Move> GetSortedLegalMoves(Game *g, bool generateQuietMoves,
- const Move *bestMove) {
+static std::vector<uint16_t> GetSortedLegalMoves(Game *g,
+ bool generateQuietMoves,
+ const uint16_t *bestMove) {
auto moves = GetLegalMoves(g, generateQuietMoves);
- std::ranges::sort(moves, [&](const Move &a, const Move &c) {
+ std::ranges::sort(moves, [&](const uint16_t &a, const uint16_t &c) {
return ScoreMove(g, a, bestMove) > ScoreMove(g, c, bestMove);
});
return moves;
@@ -112,7 +122,7 @@ static int quiescenceSearch(Game *b, int qdepth, int alpha, int beta, int ply) {
auto moves = GetSortedLegalMoves(b, false, nullptr);
- for (Move move : moves) {
+ for (uint16_t move : moves) {
UndoMove undo = MakeMove(move, b);
int score = -quiescenceSearch(b, qdepth + 1, -beta, -alpha, ply + 1);
@@ -127,16 +137,16 @@ 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) {
+ if (timeToThingMS == -1) {
+ assert(false && "Expected set time: internal error");
+ exit(1);
+ }
Nodes++;
if ((Nodes & 2047) == 0) {
double elapsedMiliseconds =
std::chrono::duration<double, std::milli>(
std::chrono::steady_clock::now() - searchStartTime)
.count();
- if (timeToThingMS == -1) {
- assert(false && "Expected set time");
- exit(1);
- }
if (elapsedMiliseconds >= timeToThingMS) {
searchStopped = true;
return 0;
@@ -173,22 +183,21 @@ static int search(int depth, Game *b, int alpha, int beta, int ply) {
return quiescenceSearch(b, 0, alpha, beta, ply);
}
- Move ttBestMove = entry != nullptr ? entry->bestMove : Move{};
- std::vector<Move> moves = GetSortedLegalMoves(b, true, &ttBestMove);
+ uint16_t ttBestMove = entry != nullptr ? entry->bestMove : uint16_t{};
+ std::vector<uint16_t> moves = GetSortedLegalMoves(b, true, &ttBestMove);
if (moves.empty()) {
- const Position king = FindKing(b, b->turn);
- if (IsSquareAttacked(b, king, !b->turn)) {
+ if (IsSquareAttacked(b, FindKing(b, b->turn), !b->turn)) {
return -(MATE - ply); // mated
}
return 0; // stalemate
}
- Move bestMove = moves[0];
+ uint16_t bestMove = moves[0];
const int alphaOrig = alpha;
int bestScore = -INF;
- for (Move move : moves) {
+ for (uint16_t move : moves) {
UndoMove undo = MakeMove(move, b);
int score = -search(depth - 1, b, -beta, -alpha, ply + 1);
@@ -221,14 +230,15 @@ static int search(int depth, Game *b, int alpha, int beta, int ply) {
}
struct SearchResult {
- Move bestMove;
+ uint16_t bestMove;
int score;
};
// Searches every root move to `depth` plies and returns the best one.
// `previousBest` is the best move from the previous iteration (used for move
// ordering, the core win of iterative deepening).
-static SearchResult SearchDepth(Game *b, int depth, const Move *previousBest) {
+static SearchResult SearchDepth(Game *b, int depth,
+ const uint16_t *previousBest) {
auto moves = GetSortedLegalMoves(b, true, previousBest);
if (moves.empty()) {
@@ -238,12 +248,12 @@ static SearchResult SearchDepth(Game *b, int depth, const Move *previousBest) {
};
}
- Move bestMove = moves[0];
+ uint16_t bestMove = moves[0];
int bestEval = -INF;
int alpha = -INF;
int beta = INF;
- for (Move move : moves) {
+ for (uint16_t move : moves) {
UndoMove undo = MakeMove(move, b);
int eval = -search(depth - 1, b, -beta, -alpha, 1);
@@ -278,7 +288,7 @@ static void PrintInfo(const int depth, const int engineScore,
}
}
-Move GetBestMove(Game *b, int maxDepth, move_options options) {
+uint16_t GetBestMove(Game *b, int maxDepth, move_options options) {
searchStopped = false;
Nodes = 0;
@@ -290,7 +300,7 @@ Move GetBestMove(Game *b, int maxDepth, move_options options) {
return {};
}
- Move bestMove = legalMoves[0];
+ uint16_t bestMove = legalMoves[0];
searchStartTime = std::chrono::steady_clock::now();