From 34b75f1575698759ab180da369be5e65364a9d1e Mon Sep 17 00:00:00 2001 From: pb00067 Date: Tue, 3 Jun 2025 13:52:17 +0200 Subject: [PATCH] Restore integrity of MovePicker::can_move_king_or_pawn PR6005 broken by PR6071 passed STC non regression https://tests.stockfishchess.org/tests/view/6839791f6ec7634154f9d312 LLR: 2.96 (-2.94,2.94) <-1.75,0.25> Total: 31776 W: 8353 L: 8130 D: 15293 Ptnml(0-2): 74, 3566, 8382, 3795, 71 passed LTC non-regression https://tests.stockfishchess.org/tests/view/6839c87a6ec7634154f9d367 LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 120756 W: 31015 L: 30899 D: 58842 Ptnml(0-2): 50, 12732, 34703, 12838, 55 closes https://github.com/official-stockfish/Stockfish/pull/6119 Bench: 1945300 --- src/movepick.cpp | 26 +++++++++++--------------- src/movepick.h | 2 +- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/movepick.cpp b/src/movepick.cpp index d2764fa8..3e7c1016 100644 --- a/src/movepick.cpp +++ b/src/movepick.cpp @@ -56,6 +56,7 @@ enum Stages { QCAPTURE }; + // Sort moves in descending order up to and including a given limit. // The order of moves smaller than the limit is left unspecified. void partial_insertion_sort(ExtMove* begin, ExtMove* end, int limit) { @@ -207,6 +208,7 @@ Move MovePicker::select(Pred filter) { // picking the move with the highest score from a list of generated moves. Move MovePicker::next_move() { + constexpr int goodQuietThreshold = -14000; top: switch (stage) { @@ -222,7 +224,7 @@ top: case PROBCUT_INIT : case QCAPTURE_INIT : cur = endBadCaptures = moves; - endCur = generate(pos, cur); + endCur = endCaptures = generate(pos, cur); score(); partial_insertion_sort(cur, endCur, std::numeric_limits::min()); @@ -244,8 +246,7 @@ top: case QUIET_INIT : if (!skipQuiets) { - cur = endBadQuiets = endBadCaptures; - endCur = generate(pos, cur); + endCur = endGenerated = generate(pos, cur); score(); partial_insertion_sort(cur, endCur, -3560 * depth); @@ -255,12 +256,7 @@ top: [[fallthrough]]; case GOOD_QUIET : - if (!skipQuiets && select([&]() { - if (cur->value > -14000) - return true; - *endBadQuiets++ = *cur; - return false; - })) + if (!skipQuiets && select([&]() { return cur->value > goodQuietThreshold; })) return *(cur - 1); // Prepare the pointers to loop over the bad captures @@ -274,22 +270,22 @@ top: if (select([]() { return true; })) return *(cur - 1); - // Prepare the pointers to loop over the bad quiets - cur = endBadCaptures; - endCur = endBadQuiets; + // Prepare the pointers to loop over quiets again + cur = endCaptures; + endCur = endGenerated; ++stage; [[fallthrough]]; case BAD_QUIET : if (!skipQuiets) - return select([]() { return true; }); + return select([&]() { return cur->value <= goodQuietThreshold; }); return Move::none(); case EVASION_INIT : cur = moves; - endCur = generate(pos, cur); + endCur = endGenerated = generate(pos, cur); score(); partial_insertion_sort(cur, endCur, std::numeric_limits::min()); @@ -315,7 +311,7 @@ bool MovePicker::can_move_king_or_pawn() const { // SEE negative captures shouldn't be returned in GOOD_CAPTURE stage assert(stage > GOOD_CAPTURE && stage != EVASION_INIT); - for (const ExtMove* m = moves; m < endCur; ++m) + for (const ExtMove* m = moves; m < endGenerated; ++m) { PieceType movedPieceType = type_of(pos.moved_piece(*m)); if ((movedPieceType == PAWN || movedPieceType == KING) && pos.legal(*m)) diff --git a/src/movepick.h b/src/movepick.h index b6784fb7..bf0c96c7 100644 --- a/src/movepick.h +++ b/src/movepick.h @@ -67,7 +67,7 @@ class MovePicker { const PieceToHistory** continuationHistory; const PawnHistory* pawnHistory; Move ttMove; - ExtMove * cur, *endCur, *endBadCaptures, *endBadQuiets; + ExtMove * cur, *endCur, *endBadCaptures, *endCaptures, *endGenerated; int stage; int threshold; Depth depth;