diff options
| author | Adam <adammegarules1@gmail.com> | 2026-08-11 13:53:26 +0200 |
|---|---|---|
| committer | Adam <adammegarules1@gmail.com> | 2026-08-11 13:53:26 +0200 |
| commit | 4dc1623d5e313a9e03fc8e3fc96bb495325a3283 (patch) | |
| tree | 8653eb1040ef405ad7d73fca4bab496d801c4337 | |
| parent | 8afc1355db1e78d1f4c4d13071d23f43efe1f20d (diff) | |
improving code
| -rw-r--r-- | src/moves.cpp | 180 | ||||
| -rw-r--r-- | src/uci.cpp | 240 | ||||
| -rw-r--r-- | src/uci.hpp | 1 |
3 files changed, 219 insertions, 202 deletions
diff --git a/src/moves.cpp b/src/moves.cpp index a236536..b7b1688 100644 --- a/src/moves.cpp +++ b/src/moves.cpp @@ -38,7 +38,7 @@ constexpr std::array<std::uint64_t, 64> KNIGHT_ATTACKS = computeKnightAttacks(); static void GenerateKnightMoves(Game *b, std::vector<Move> &moves, bool GenerateQuietMoves) { - + uint64_t knights = b->PieceBitboards[b->turn][KNIGHT]; while (knights != 0) { int from = __builtin_ctzll(knights); @@ -83,24 +83,38 @@ void GeneratePawnMoves(Game *b, int from, std::vector<Move> &moves, } // if piece it want to move to is none and it as legal move - if (quietMoves) { - if (b->pieces[next].type == NONEPIECE) { - if (position.rank + (pawn.color ? 1 : -1) == 0 || - position.rank + (pawn.color ? 1 : -1) == 7) { - moves.push_back({position, IndexToPosition(next), QUEEN}); - moves.push_back({position, IndexToPosition(next), ROOK}); - moves.push_back({position, IndexToPosition(next), BISHOP}); - moves.push_back({position, IndexToPosition(next), KNIGHT}); - } else { - moves.push_back({position, IndexToPosition(next)}); - } + 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, + }); + } else { + moves.push_back({.From = position, .To = IndexToPosition(next)}); + } - int startingRank = pawn.color ? 1 : 6; - int twoSteps = from + step * 2; - if (position.rank == startingRank && - b->pieces[twoSteps].type == NONEPIECE) { - moves.push_back({position, IndexToPosition(twoSteps)}); - } + int startingRank = pawn.color ? 1 : 6; + int twoSteps = from + (step * 2); + if (position.rank == startingRank && + b->pieces[twoSteps].type == NONEPIECE) { + moves.push_back({position, IndexToPosition(twoSteps)}); } }; @@ -108,39 +122,51 @@ void GeneratePawnMoves(Game *b, int from, std::vector<Move> &moves, int targetFile = position.file + fileOffset; int targetRank = position.rank + (pawn.color ? 1 : -1); - if (targetFile < 0 || targetFile >= 8) - continue; - - if (targetRank < 0 || targetRank >= 8) + if (targetFile < 0 || targetFile >= 8) { continue; + } - int target = targetRank * 8 + targetFile; + int target = (targetRank * 8) + targetFile; if (IndexToPosition(target) == b->enPassant && b->canEnpassant) { - moves.push_back({position, IndexToPosition(target)}); + moves.push_back({.From = position, .To = IndexToPosition(target)}); } if (b->pieces[target].type != NONEPIECE && b->pieces[target].color != pawn.color) { if (targetRank == 0 || targetRank == 7) { - moves.push_back({position, IndexToPosition(target), QUEEN}); - moves.push_back({position, IndexToPosition(target), ROOK}); - moves.push_back({position, IndexToPosition(target), BISHOP}); - moves.push_back({position, IndexToPosition(target), KNIGHT}); + 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, + }); } else { - moves.push_back({position, IndexToPosition(target)}); + moves.push_back({.From = position, .To = IndexToPosition(target)}); + moves.push_back({.From = position, .To = IndexToPosition(target)}); } } } - // the end }; -void GenerateKingMoves(Game *b, int from, std::vector<Move> &moves, +void GenerateKingMoves(Game *g, int from, std::vector<Move> &moves, bool GenerateQuietMoves) { - if (b->pieces[from].type != KING) { + if (g->pieces[from].type != KING) { assert(false && "calling generate king moves on non king"); return; } - if (b->pieces[from].color != b->turn) { + if (g->pieces[from].color != g->turn) { assert(false && "calling generate king moves on king of opposite color"); return; } @@ -153,12 +179,12 @@ void GenerateKingMoves(Game *b, int from, std::vector<Move> &moves, if (std::abs((next % 8) - (from % 8)) > 1) { continue; }; - if (b->pieces[next].type != NONEPIECE) { - if (b->pieces[next].color == b->turn) { + if (g->pieces[next].type != NONEPIECE) { + if (g->pieces[next].color == g->turn) { continue; }; } - if (!GenerateQuietMoves && b->pieces[next].type == NONEPIECE) { + if (!GenerateQuietMoves && g->pieces[next].type == NONEPIECE) { continue; } @@ -166,44 +192,44 @@ void GenerateKingMoves(Game *b, int from, std::vector<Move> &moves, } }; -std::vector<Move> GetPseudoLegalMoves(Game *b, bool GenerateQuietMoves) { +std::vector<Move> GetPseudoLegalMoves(Game *g, bool GenerateQuietMoves) { std::vector<Move> moves; moves.reserve(40); - GenerateKnightMoves(b, moves, GenerateQuietMoves); + GenerateKnightMoves(g, moves, GenerateQuietMoves); constexpr std::array<int, 4> rook_Moves{-1, 1, 8, -8}; constexpr std::array<int, 4> bishop_Moves{-9, 9, -7, 7}; - uint64_t piece_bitboard = b->PieceBitboard; + uint64_t piece_bitboard = g->PieceBitboard; while (piece_bitboard != 0) { int i = __builtin_ctzll(piece_bitboard); piece_bitboard &= piece_bitboard - 1; - Piece piece = b->pieces[i]; + Piece piece = g->pieces[i]; if (piece.type == NONEPIECE) { assert(false && "got none piece in piece bitboard"); } - if (piece.color != b->turn) { + if (piece.color != g->turn) { continue; } if (piece.type == PAWN) { - GeneratePawnMoves(b, i, moves, GenerateQuietMoves); + GeneratePawnMoves(g, i, moves, GenerateQuietMoves); } if (piece.type == BISHOP) { - GenerateSlidingMoves(b, i, bishop_Moves, moves, GenerateQuietMoves); + GenerateSlidingMoves(g, i, bishop_Moves, moves, GenerateQuietMoves); } if (piece.type == ROOK) { - GenerateSlidingMoves(b, i, rook_Moves, moves, GenerateQuietMoves); + GenerateSlidingMoves(g, i, rook_Moves, moves, GenerateQuietMoves); } if (piece.type == QUEEN) { - GenerateSlidingMoves(b, i, rook_Moves, moves, GenerateQuietMoves); - GenerateSlidingMoves(b, i, bishop_Moves, moves, GenerateQuietMoves); + GenerateSlidingMoves(g, i, rook_Moves, moves, GenerateQuietMoves); + GenerateSlidingMoves(g, i, bishop_Moves, moves, GenerateQuietMoves); } if (piece.type == KING) { - GenerateKingMoves(b, i, moves, GenerateQuietMoves); + GenerateKingMoves(g, i, moves, GenerateQuietMoves); if (GenerateQuietMoves) { - GenerateCastlingMoves(i, b, moves); + GenerateCastlingMoves(i, g, moves); } }; }; @@ -356,9 +382,9 @@ GameState GetNewGameState(Game *g) { } Position IndexToPosition(int i) { - uint8_t rank = static_cast<uint8_t>(i / 8); // 0-7 - uint8_t file = static_cast<uint8_t>(i % 8); // 0-7 - return {rank, file}; + auto rank = static_cast<uint8_t>(i / 8); // 0-7 + auto file = static_cast<uint8_t>(i % 8); // 0-7 + return {.rank = rank, .file = file}; } void GenerateSlidingMoves(Game *b, int from, @@ -375,8 +401,9 @@ void GenerateSlidingMoves(Game *b, int from, if (direction == 7 || direction == -7 || direction == 9 || direction == -9) { - if (std::abs(newFile - oldFile) != 1) + if (std::abs(newFile - oldFile) != 1) { break; + } } if (i2 >= 64 || i2 < 0) { break; @@ -392,7 +419,8 @@ void GenerateSlidingMoves(Game *b, int from, if (!GenerateQuietMoves && b->pieces[i2].type == NONEPIECE) { continue; } - moves.push_back({IndexToPosition(from), IndexToPosition(i2)}); + moves.push_back( + {.From = IndexToPosition(from), .To = IndexToPosition(i2)}); if (b->pieces[i2].color != b->turn && b->pieces[i2].type != NONEPIECE) { break; } @@ -412,11 +440,11 @@ void GenerateCastlingMoves(int from, Game *g, std::vector<Move> &moves) { if (from != 4 && g->turn) { return; } - bool oneToRight = g->PieceBitboard & (1ULL << (from + 1)); - bool twoToRight = g->PieceBitboard & (1ULL << (from + 2)); - bool oneToLeft = g->PieceBitboard & (1ULL << (from - 1)); - bool twoToLeft = g->PieceBitboard & (1ULL << (from - 2)); - bool threeToLeft = g->PieceBitboard & (1ULL << (from - 3)); + bool oneToRight = (g->PieceBitboard & (1ULL << (from + 1))) > 0; + bool twoToRight = (g->PieceBitboard & (1ULL << (from + 2))) > 0; + bool oneToLeft = (g->PieceBitboard & (1ULL << (from - 1))) > 0; + bool twoToLeft = (g->PieceBitboard & (1ULL << (from - 2))) > 0; + bool threeToLeft = (g->PieceBitboard & (1ULL << (from - 3))) > 0; Position kingPosition = FindKing(g, g->turn); @@ -426,36 +454,30 @@ void GenerateCastlingMoves(int from, Game *g, std::vector<Move> &moves) { } auto pathIsSafe = [&](int step) { return !IsSquareAttacked(g, IndexToPosition(from + step), !g->turn) && - !IsSquareAttacked(g, IndexToPosition(from + 2 * step), !g->turn); + !IsSquareAttacked(g, IndexToPosition(from + (2 * step)), !g->turn); }; if (g->turn) { // white - if (!oneToRight && !twoToRight && g->whiteCastleKing) { - if (pathIsSafe(1)) { - moves.push_back( - {.From = IndexToPosition(from), .To = IndexToPosition(from + 2)}); - } + if (!oneToRight && !twoToRight && g->whiteCastleKing && pathIsSafe(1)) { + moves.push_back( + {.From = IndexToPosition(from), .To = IndexToPosition(from + 2)}); } - if (!oneToLeft && !twoToLeft && !threeToLeft && g->whiteCastleQueen) { - if (pathIsSafe(-1)) { - moves.push_back( - {.From = IndexToPosition(from), .To = IndexToPosition(from - 2)}); - } + if (!oneToLeft && !twoToLeft && !threeToLeft && g->whiteCastleQueen && + pathIsSafe(-1)) { + moves.push_back( + {.From = IndexToPosition(from), .To = IndexToPosition(from - 2)}); } } if (!g->turn) { // black - if (!oneToRight && !twoToRight && g->blackCastleKing) { - if (pathIsSafe(1)) { - moves.push_back( - {.From = IndexToPosition(from), .To = IndexToPosition(from + 2)}); - } + if (!oneToRight && !twoToRight && g->blackCastleKing && pathIsSafe(1)) { + moves.push_back( + {.From = IndexToPosition(from), .To = IndexToPosition(from + 2)}); } - if (!oneToLeft && !twoToLeft && !threeToLeft && g->blackCastleQueen) { - if (pathIsSafe(-1)) { - moves.push_back( - {.From = IndexToPosition(from), .To = IndexToPosition(from - 2)}); - } + if (!oneToLeft && !twoToLeft && !threeToLeft && g->blackCastleQueen && + pathIsSafe(-1)) { + moves.push_back( + {.From = IndexToPosition(from), .To = IndexToPosition(from - 2)}); } } } diff --git a/src/uci.cpp b/src/uci.cpp index 23fe123..cc5ae18 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -1,6 +1,8 @@ +#include <array> #include <cassert> #include <cctype> #include <chrono> +#include <cstddef> #include <cstdint> #include <cstdlib> #include <fstream> @@ -23,24 +25,7 @@ static const std::string starting_fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"; -std::ofstream uciLog("cache/uci_log.txt", std::ios::app); - -void LogUci(const std::string &message) { - if (!uciLog.is_open()) { - return; - } - - auto now = std::chrono::system_clock::now(); - auto time = std::chrono::system_clock::to_time_t(now); - - uciLog << "[" << std::put_time(std::localtime(&time), "%H:%M:%S") << "] " - << message << "\n"; - - uciLog.flush(); -} -using namespace std; - -Move UciToMove(const string &uci) { +Move UciToMove(const std::string &uci) { Position from; Position to; PieceType promotion = NONEPIECE; @@ -71,7 +56,7 @@ Move UciToMove(const string &uci) { break; default: assert(false && "Unexpected promotion type"); - cout << "Unexpected promotion type"; + std::cout << "Unexpected promotion type"; exit(1); } } @@ -115,7 +100,7 @@ static void PrintBitboard(uint64_t bb, const std::string &name) { } static void DebugBitboards(const Game *g) { - static constexpr const char *pieceNames[] = { + static constexpr const std::array<std::string, 7> pieceNames = { "None", "Pawn", "Knight", "Bishop", "Rook", "Queen", "King", }; @@ -135,7 +120,8 @@ static void DebugBitboards(const Game *g) { std::cout << (color ? "White\n" : "Black\n"); for (int type = PAWN; type <= KING; ++type) { - PrintBitboard(g->PieceBitboards[color][type], pieceNames[type]); + PrintBitboard(g->PieceBitboards[color][type], + pieceNames[static_cast<size_t>(type)]); } } } @@ -145,16 +131,16 @@ static void printPromotionLetter(PieceType p) { } switch (p) { case QUEEN: - cout << "q"; + std::cout << "q"; break; case ROOK: - cout << "r"; + std::cout << "r"; break; case KNIGHT: - cout << "n"; + std::cout << "n"; break; case BISHOP: - cout << "b"; + std::cout << "b"; break; default: assert(false && "Unexpected promotion type"); @@ -168,7 +154,7 @@ static void printBoard(Game *g) { Piece piece = g->pieces[(rank * 8) + file]; if (piece.type == NONEPIECE) { - print(" 00"); + std::print(" 00"); continue; }; std::print(" {0}{1}", static_cast<int>(piece.type), @@ -178,14 +164,108 @@ static void printBoard(Game *g) { std::print(" | {0}\n", rank + 1); } } +static void GoCommand(Game *game, std::string &cmd) { + std::stringstream ss(cmd); + + std::string token; + int depth = -1; + + int wtime = -1; + int btime = -1; + + int wncr = 0; + int bncr = 0; + + ss >> token; // go + + while (ss >> token) { + if (token == "depth") { + ss >> depth; + } + if (token == "wtime") { + ss >> wtime; + } + if (token == "btime") { + ss >> btime; + } + if (token == "incr") { + ss >> wncr; + bncr = wncr; + } + if (token == "winc") { + ss >> wncr; + } + if (token == "binc") { + ss >> bncr; + } + } + + if (depth != -1 && depth <= 0) { + std::cout << "Fatal: Depth must be positive integer"; + exit(1); + } + move_options options = { + .wtime = wtime, + .btime = btime, + .wncr = wncr, + .bncr = bncr, + }; + Move best = GetBestMove(game, depth, options); + + std::cout << "bestmove "; + std::cout << static_cast<char>(best.From.file + 'a') << 1 + best.From.rank + << static_cast<char>(best.To.file + 'a') << 1 + best.To.rank; + + printPromotionLetter(best.promotion); + + std::cout << "\n"; + std::cout.flush(); +} +static void positionCommnad(Game *game, std::string &cmd) { + std::stringstream ss(cmd); + std::string token; + + ss >> token; // position + + ss >> token; + + if (token == "startpos") { + *game = initBoard(starting_fen, game->Transpositions); + } else if (token == "fen") { + std::string fen; + std::string part; + + // FEN has spaces, need 6 parts + for (int i = 0; i < 6; i++) { + ss >> part; + if (i != 0) { + fen += ' '; + } + fen += part; + } + + *game = initBoard(fen, game->Transpositions); + } + + // check for moves + while (ss >> token) { + if (token == "moves") { + break; + } + } + + while (ss >> token) { + Move move = UciToMove(token); + + MakeMove(move, game); + } +} void Uci() { - unordered_map<uint64_t, TranspositionsEntry> transpositions = {}; + std::unordered_map<uint64_t, TranspositionsEntry> transpositions = {}; Game game = initBoard(starting_fen, &transpositions); - string cmd; - - while (getline(cin, cmd)) { - LogUci("GUI -> ENGINE: " + cmd); + std::string cmd; + while (getline(std::cin, cmd)) { if (cmd == "quit") { return; } @@ -196,9 +276,9 @@ void Uci() { DebugBitboards(&game); } if (cmd == "uci") { - cout << "id name " << engine_info(); - cout << "uciok\n"; - cout.flush(); + std::cout << "id name " << engine_info(); + std::cout << "uciok\n"; + std::cout.flush(); } if (cmd == "ucinewgame") { game = @@ -206,98 +286,14 @@ void Uci() { &transpositions); } if (cmd == "isready") { - cout << "readyok\n"; - cout.flush(); + std::cout << "readyok\n"; + std::cout.flush(); } if (cmd.starts_with("go")) { - stringstream ss(cmd); - - string token; - int depth = -1; - - int wtime = -1; - int btime = -1; - - int wncr = 0; - int bncr = 0; - - ss >> token; // go - - while (ss >> token) { - if (token == "depth") { - ss >> depth; - } - if (token == "wtime") { - ss >> wtime; - } - if (token == "btime") { - ss >> btime; - } - if (token == "incr") { - ss >> wncr; - bncr = wncr; - } - } - - if (depth != -1 && depth <= 0) { - cout << "Fatal: Depth must be positive integer"; - exit(1); - } - move_options options = { - .wtime = wtime, - .btime = btime, - .wncr = wncr, - .bncr = bncr, - }; - Move best = GetBestMove(&game, depth, options); - - cout << "bestmove "; - cout << static_cast<char>(best.From.file + 'a') << 1 + best.From.rank - << static_cast<char>(best.To.file + 'a') << 1 + best.To.rank; - - printPromotionLetter(best.promotion); - - cout << "\n"; - cout.flush(); + GoCommand(&game, cmd); } if (cmd.starts_with("position")) { - stringstream ss(cmd); - string token; - - ss >> token; // position - - ss >> token; - - if (token == "startpos") { - game = initBoard(starting_fen, &transpositions); - } else if (token == "fen") { - string fen; - string part; - - // FEN has spaces, need 6 parts - for (int i = 0; i < 6; i++) { - ss >> part; - if (i != 0) { - fen += " "; - } - fen += part; - } - - game = initBoard(fen, &transpositions); - } - - // check for moves - while (ss >> token) { - if (token == "moves") { - break; - } - } - - while (ss >> token) { - Move move = UciToMove(token); - - MakeMove(move, &game); - } + positionCommnad(&game, cmd); } } } diff --git a/src/uci.hpp b/src/uci.hpp index 8160442..19fd021 100644 --- a/src/uci.hpp +++ b/src/uci.hpp @@ -6,7 +6,6 @@ #include <unordered_map> Move UciToMove(const std::string &uci); -void LogUci(const std::string &message); void Uci(); Game initBoard( const std::string &startingFEN, |
