From 4eb36e67eca586a662298bfe8cc5392fbfa698e0 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 15 Aug 2026 17:01:54 +0200 Subject: implementing memory optimazied move using uint16_t instead of a four integers and one byte --- src/moves.cpp | 144 +++++++++++++++++++++++++++------------------------------- 1 file changed, 68 insertions(+), 76 deletions(-) (limited to 'src/moves.cpp') diff --git a/src/moves.cpp b/src/moves.cpp index 812e734..a80f4c7 100644 --- a/src/moves.cpp +++ b/src/moves.cpp @@ -36,16 +36,16 @@ constexpr std::array computeKnightAttacks() { constexpr std::array KNIGHT_ATTACKS = computeKnightAttacks(); -static void GenerateKnightMoves(Game *b, std::vector &moves, +static void GenerateKnightMoves(Game *b, std::vector &moves, bool GenerateQuietMoves) { uint64_t knights = b->PieceBitboards[b->turn][KNIGHT]; while (knights != 0) { - int from = __builtin_ctzll(knights); + uint8_t from = static_cast(__builtin_ctzll(knights)); knights &= knights - 1; uint64_t knight_attacks = KNIGHT_ATTACKS[static_cast(from)]; while (knight_attacks != 0) { - int next = __builtin_ctzll(knight_attacks); + uint8_t next = static_cast(__builtin_ctzll(knight_attacks)); knight_attacks &= knight_attacks - 1; bool hasFriendlyPiece = @@ -59,13 +59,12 @@ static void GenerateKnightMoves(Game *b, std::vector &moves, if (!GenerateQuietMoves && !isCaptuare) { continue; } - moves.push_back( - {.From = IndexToPosition(from), .To = IndexToPosition(next)}); + moves.push_back(CreateMove(from, next)); } } }; -void GeneratePawnMoves(Game *b, int from, std::vector &moves, +void GeneratePawnMoves(Game *b, uint8_t from, std::vector &moves, bool quietMoves) { Piece pawn = b->pieces[from]; if (pawn.type != PAWN) { @@ -86,80 +85,73 @@ void GeneratePawnMoves(Game *b, int from, std::vector &moves, if (b->pieces[next].type == NONEPIECE && quietMoves) { if (position.rank + (pawn.color ? 1 : -1) == 0 || position.rank + (pawn.color ? 1 : -1) == 7) { - moves.push_back({ - .From = position, - .To = IndexToPosition(next), - .promotion = QUEEN, - }); - moves.push_back({ - .From = position, - .To = IndexToPosition(next), - .promotion = ROOK, - }); - moves.push_back({ - .From = position, - .To = IndexToPosition(next), - .promotion = BISHOP, - }); - moves.push_back({ - .From = position, - .To = IndexToPosition(next), - .promotion = KNIGHT, - }); + moves.push_back( + CreateMove(static_cast(PositionToIndex(position)), + static_cast(next), QUEEN)); + + moves.push_back( + CreateMove(static_cast(PositionToIndex(position)), + static_cast(next), ROOK)); + + moves.push_back( + CreateMove(static_cast(PositionToIndex(position)), + static_cast(next), BISHOP)); + moves.push_back( + CreateMove(static_cast(PositionToIndex(position)), + static_cast(next), KNIGHT)); } else { - moves.push_back({.From = position, .To = IndexToPosition(next)}); + moves.push_back( + CreateMove(static_cast(PositionToIndex(position)), + static_cast(next))); } int startingRank = pawn.color ? 1 : 6; - int twoSteps = from + (step * 2); + uint8_t twoSteps = static_cast(from + (step * 2)); if (position.rank == startingRank && b->pieces[twoSteps].type == NONEPIECE) { - moves.push_back({.From = position, .To = IndexToPosition(twoSteps)}); + moves.push_back(CreateMove( + static_cast(PositionToIndex(position)), twoSteps)); } }; for (int fileOffset : {-1, 1}) { - int targetFile = position.file + fileOffset; - int targetRank = position.rank + (pawn.color ? 1 : -1); + uint8_t targetFile = static_cast(position.file + fileOffset); + uint8_t targetRank = + static_cast(position.rank + (pawn.color ? 1 : -1)); - if (targetFile < 0 || targetFile >= 8) { + if (targetFile >= 8) { + continue; + } + if (targetRank >= 8) { continue; } - int target = (targetRank * 8) + targetFile; + uint8_t target = static_cast((targetRank * 8)) + targetFile; if (IndexToPosition(target) == b->enPassant && b->canEnpassant) { - moves.push_back({.From = position, .To = IndexToPosition(target)}); + moves.push_back( + CreateMove(static_cast(PositionToIndex(position)), target)); } if (b->pieces[target].type != NONEPIECE && b->pieces[target].color != pawn.color) { if (targetRank == 0 || targetRank == 7) { - moves.push_back({ - .From = position, - .To = IndexToPosition(target), - .promotion = QUEEN, - }); - moves.push_back({.From = position, - .To = IndexToPosition(target), - .promotion = ROOK}); - moves.push_back({ - .From = position, - .To = IndexToPosition(target), - .promotion = BISHOP, - }); - moves.push_back({ - .From = position, - .To = IndexToPosition(target), - .promotion = KNIGHT, - }); + moves.push_back(CreateMove( + static_cast(PositionToIndex(position)), target, QUEEN)); + moves.push_back(CreateMove( + static_cast(PositionToIndex(position)), target, ROOK)); + moves.push_back(CreateMove( + static_cast(PositionToIndex(position)), target, BISHOP)); + moves.push_back(CreateMove( + static_cast(PositionToIndex(position)), target, KNIGHT)); } else { - moves.push_back({.From = position, .To = IndexToPosition(target)}); + moves.push_back(CreateMove( + static_cast(PositionToIndex(position)), target)); } } } }; -void GenerateKingMoves(Game *g, int from, std::vector &moves, +void GenerateKingMoves(Game *g, int from, std::vector &moves, bool GenerateQuietMoves) { if (g->pieces[from].type != KING) { assert(false && "calling generate king moves on non king"); @@ -171,8 +163,8 @@ void GenerateKingMoves(Game *g, int from, std::vector &moves, } constexpr std::array king_moves{-1, 1, 8, -8, -9, 9, -7, 7}; for (int offset : king_moves) { - int next = from + offset; - if (next >= 64 || next < 0) { + uint8_t next = static_cast(from + offset); + if (next >= 64) { continue; } if (std::abs((next % 8) - (from % 8)) > 1) { @@ -187,13 +179,12 @@ void GenerateKingMoves(Game *g, int from, std::vector &moves, continue; } - moves.push_back( - {.From = IndexToPosition(from), .To = IndexToPosition(next)}); + moves.push_back(CreateMove(static_cast(from), next)); } }; -std::vector GetPseudoLegalMoves(Game *g, bool GenerateQuietMoves) { - std::vector moves; +std::vector GetPseudoLegalMoves(Game *g, bool GenerateQuietMoves) { + std::vector moves; moves.reserve(40); GenerateKnightMoves(g, moves, GenerateQuietMoves); @@ -203,7 +194,7 @@ std::vector GetPseudoLegalMoves(Game *g, bool GenerateQuietMoves) { uint64_t piece_bitboard = g->PieceBitboard; while (piece_bitboard != 0) { - int i = __builtin_ctzll(piece_bitboard); + uint8_t i = static_cast(__builtin_ctzll(piece_bitboard)); piece_bitboard &= piece_bitboard - 1; Piece piece = g->pieces[i]; if (piece.type == NONEPIECE) { @@ -331,12 +322,12 @@ bool IsSquareAttacked(Game *g, Position square, bool byColor) { return false; } -std::vector GetLegalMoves(Game *g, bool quietMove) { - std::vector moves = GetPseudoLegalMoves(g, quietMove); - std::vector legalMoves; +std::vector GetLegalMoves(Game *g, bool quietMove) { + std::vector moves = GetPseudoLegalMoves(g, quietMove); + std::vector legalMoves; legalMoves.reserve(moves.size()); - for (const Move &move : moves) { + for (const uint16_t &move : moves) { UndoMove undo = MakeMove(move, g); bool legal = true; @@ -390,7 +381,8 @@ Position IndexToPosition(int i) { void GenerateSlidingMoves(Game *b, int from, const std::array &directions, - std::vector &moves, bool GenerateQuietMoves) { + std::vector &moves, + bool GenerateQuietMoves) { for (uint i = 0; i < directions.size(); i++) { int direction = directions[i]; @@ -421,14 +413,14 @@ void GenerateSlidingMoves(Game *b, int from, continue; } moves.push_back( - {.From = IndexToPosition(from), .To = IndexToPosition(i2)}); + CreateMove(static_cast(from), static_cast(i2))); if (b->pieces[i2].color != b->turn && b->pieces[i2].type != NONEPIECE) { break; } } }; }; -void GenerateCastlingMoves(int from, Game *g, std::vector &moves) { +void GenerateCastlingMoves(int from, Game *g, std::vector &moves) { Piece piece = g->pieces[from]; if (piece.type != KING) { assert(false && "Calling generate castling moves on non king piece"); @@ -460,25 +452,25 @@ void GenerateCastlingMoves(int from, Game *g, std::vector &moves) { if (g->turn) { // white if (!oneToRight && !twoToRight && g->whiteCastleKing && pathIsSafe(1)) { - moves.push_back( - {.From = IndexToPosition(from), .To = IndexToPosition(from + 2)}); + moves.push_back(CreateMove(static_cast(from), + static_cast(from + 2))); } if (!oneToLeft && !twoToLeft && !threeToLeft && g->whiteCastleQueen && pathIsSafe(-1)) { - moves.push_back( - {.From = IndexToPosition(from), .To = IndexToPosition(from - 2)}); + moves.push_back(CreateMove(static_cast(from), + static_cast(from - 2))); } } if (!g->turn) { // black if (!oneToRight && !twoToRight && g->blackCastleKing && pathIsSafe(1)) { - moves.push_back( - {.From = IndexToPosition(from), .To = IndexToPosition(from + 2)}); + moves.push_back(CreateMove(static_cast(from), + static_cast(from + 2))); } if (!oneToLeft && !twoToLeft && !threeToLeft && g->blackCastleQueen && pathIsSafe(-1)) { - moves.push_back( - {.From = IndexToPosition(from), .To = IndexToPosition(from - 2)}); + moves.push_back(CreateMove(static_cast(from), + static_cast(from - 2))); } } } -- cgit v1.2.3