From 76b054ee9ddcf0e2ec5b012c6b9f9d6bd8a9004e Mon Sep 17 00:00:00 2001 From: Josh-Heaps Date: Mon, 8 Jun 2026 17:28:04 -0600 Subject: [PATCH] More efficient searching --- JoshHeaps.Net/Resources/chess_engine.dll | Bin 146432 -> 157184 bytes native/chess_engine/src/chess_engine.cpp | 55 ++++++++++++++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/JoshHeaps.Net/Resources/chess_engine.dll b/JoshHeaps.Net/Resources/chess_engine.dll index 5167dea8ee8b1ccb418b5091b25b70a2916c96a3..f7f7bfdc03c585b3dac8d98228a4d63c8ea2ec43 100644 GIT binary patch delta 39183 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 E12!|8?EnA( delta 32386 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 #include #include #include @@ -57,8 +58,8 @@ static int parse_skill(const char* options, int fallback) { return v < 1 ? 1 : v > 20 ? 20 : v; } -/* Maps the 1..20 difficulty to a search depth. Kept modest: the search has no move - * ordering or quiescence yet, so deep fixed-depth runs get expensive quickly. */ +/* Maps the 1..20 difficulty to a search depth. Kept modest: the search has no + * quiescence yet, so deep fixed-depth runs get expensive quickly. */ static int depth_for_skill(int skill) { return skill; /* skill 1 -> 2 plies ... skill 20 -> 7 plies */ } @@ -178,6 +179,52 @@ static int evaluate(const chess::Position& pos) { return score; } +static int piece_value(chess::PieceType pt) { + switch (pt) { + case chess::PAWN: return 100; + case chess::KNIGHT: return 320; + case chess::BISHOP: return 330; + case chess::ROOK: return 500; + case chess::QUEEN: return 900; + default: return 0; + } +} + +/* Heuristic for searching the most promising moves first, which makes alpha-beta + * prune far more. Checks rank highest, then captures by MVV-LVA (grab the most + * valuable victim with the least valuable attacker). */ +static int order_score(chess::Position& pos, chess::Move m) { + int score = 0; + + if (pos.gives_check(m)) + score += 1000; + + chess::Piece victim = pos.piece_on(m.to()); + if (victim != chess::NO_PIECE) + score += 100 + 10 * piece_value(chess::type_of(victim)) + - piece_value(chess::type_of(pos.piece_on(m.from()))); + else if (m.type() == chess::EN_PASSANT) + score += 100 + 10 * piece_value(chess::PAWN); + + return score; +} + +/* Sort the move list in place, best-scoring first. Scores are computed once up + * front so gives_check isn't re-evaluated on every comparison. */ +static void order_moves(chess::Position& pos, chess::MoveList& moves) { + struct ScoredMove { int score; chess::Move move; }; + ScoredMove scored[256]; + + for (int i = 0; i < moves.size(); i++) + scored[i] = { order_score(pos, moves.moves[i]), moves.moves[i] }; + + std::sort(scored, scored + moves.size(), + [](const ScoredMove& a, const ScoredMove& b) { return a.score > b.score; }); + + for (int i = 0; i < moves.size(); i++) + moves.moves[i] = scored[i].move; +} + extern "C" { CHESS_API EngineHandle CHESS_CALL engine_create(const char* options) { @@ -205,6 +252,8 @@ static int alpha_beta(chess::Position& pos, int depth, int maxDepth, int bestFor if (moves.size() == 0) return pos.is_draw() ? 0 : whiteToMove ? -200000 + depth : 200000 - depth; + order_moves(pos, moves); + for (int i = 0; i < moves.size(); i++) { chess::Move move = moves.moves[i]; pos.do_move(move); @@ -247,6 +296,8 @@ CHESS_API int CHESS_CALL engine_best_move(EngineHandle engine, if (moves.size() == 0) return CHESS_ERR_NO_MOVE; + order_moves(pos, moves); + int maxDepth = depth_for_skill(engine->skill); int bestForWhite = std::numeric_limits::min();