mirror of
https://github.com/official-stockfish/Stockfish.git
synced 2026-07-22 12:47:08 +00:00
Fix undefined behavior in stalemate trap detection.
An important part of it is a function which detects if we can move a king or pawn. If this function called before quiet move generation phase the end of the checked move list is undefined (Thanks to AliceRoselia pointing out we have some problem because of wrong bench in a test). This problem exists also in master but is really rarely triggered (thanks to vondele which found one) but it seen significant more often if the capture order score is increased. This fix now simply assumes in this case (and other similiar cases) that a king or pawn can move without checking any moves. Passed non-regression STC (with default book): LLR: 3.03 (-2.94,2.94) <-1.75,0.25> Total: 203008 W: 52465 L: 52424 D: 98119 Ptnml(0-2): 498, 20293, 59893, 20310, 510 https://tests.stockfishchess.org/tests/view/68a06ec5fd8719b088c8dc1a Passed non-regression STC (with stalemates book): LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 31616 W: 14418 L: 14366 D: 2832 Ptnml(0-2): 1, 189, 15375, 243, 0 https://tests.stockfishchess.org/tests/view/68a07538fd8719b088c8dc1f closes https://github.com/official-stockfish/Stockfish/pull/6235 Bench: 2996176
This commit is contained in:
committed by
Joost VandeVondele
parent
4b6b13ce5a
commit
c56bd10cb5
+7
-2
@@ -318,8 +318,13 @@ void MovePicker::skip_quiet_moves() { skipQuiets = true; }
|
||||
|
||||
// this function must be called after all quiet moves and captures have been generated
|
||||
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);
|
||||
|
||||
assert((GOOD_QUIET <= stage && stage <= BAD_QUIET) || stage == EVASION);
|
||||
|
||||
// Until good capture state no quiet moves are generated for comparison so simply assume king or pawns can move.
|
||||
// Do the same for other states that don't have a valid available move list.
|
||||
if ((GOOD_QUIET > stage || stage > BAD_QUIET) && stage != EVASION)
|
||||
return true;
|
||||
|
||||
for (const ExtMove* m = moves; m < endGenerated; ++m)
|
||||
{
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ class MovePicker {
|
||||
const PieceToHistory** continuationHistory;
|
||||
const PawnHistory* pawnHistory;
|
||||
Move ttMove;
|
||||
ExtMove * cur, *endCur, *endBadCaptures, *endCaptures, *endGenerated;
|
||||
ExtMove * cur, *endCur, *endBadCaptures, *endCaptures, *endGenerated = moves;
|
||||
int stage;
|
||||
int threshold;
|
||||
Depth depth;
|
||||
|
||||
Reference in New Issue
Block a user