Simplify & improve stalemate detection

Change is functional because now we verify for stalemate also on captures and when not giving check.

Green STC test on stalemate-book
https://tests.stockfishchess.org/tests/view/682d878f6ec7634154f9ad2f
Elo: 2.29 ± 1.3 (95%) LOS: 100.0%
Total: 10000 W: 4637 L: 4571 D: 792
Ptnml(0-2): 2, 132, 4664, 202, 0
nElo: 12.42 ± 6.8 (95%) PairsRatio: 1.51

Green LTC test on stalemate-book
https://tests.stockfishchess.org/tests/view/682daa2d6ec7634154f9ad67
Elo: 0.80 ± 0.8 (95%) LOS: 96.9%
Total: 10000 W: 4727 L: 4704 D: 569
Ptnml(0-2): 0, 64, 4849, 87, 0
nElo: 6.51 ± 6.8 (95%) PairsRatio: 1.36

Passed non-regression test @ LTC
https://tests.stockfishchess.org/tests/view/682dd10d6ec7634154f9adb3
LLR: 2.95 (-2.94,2.94) <-1.75,0.25>
Total: 148512 W: 38135 L: 38046 D: 72331
Ptnml(0-2): 55, 15759, 42558, 15810, 74

N.B.: The unique concern I have, is that due changes in future a negative SEE
capture see might be returned in GOOD_CAPTURE stage. In this case the assert in
can_move_king_or_pawn() will trigger since we must guarantee that all moves
(also quiets) are generated in movepicker when calling can_move_king_or_pawn().

closes https://github.com/official-stockfish/Stockfish/pull/6088

bench: 2178135
This commit is contained in:
pb00067
2025-05-23 09:29:32 +02:00
committed by Joost VandeVondele
parent 472cc764be
commit f58d923fe0
2 changed files with 3 additions and 4 deletions

View File

@@ -314,7 +314,8 @@ 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() {
assert(stage == GOOD_QUIET || stage == BAD_QUIET || stage == EVASION);
// SEE negative captures shouldn't be returned in GOOD_CAPTURE stage
assert(stage > GOOD_CAPTURE && stage != EVASION_INIT);
for (ExtMove* m = moves; m < endMoves; ++m)
{

View File

@@ -1073,9 +1073,7 @@ moves_loop: // When in check, search starts here
if (!pos.see_ge(move, -158 * depth - seeHist))
{
bool mayStalemateTrap =
depth > 2 && givesCheck && alpha < 0
&& !capture // we consider that captures will likely destroy the stalemate configuration
&& pos.non_pawn_material(us) == PieceValue[movedPiece]
depth > 2 && alpha < 0 && pos.non_pawn_material(us) == PieceValue[movedPiece]
&& PieceValue[movedPiece] >= RookValue
// it can't be stalemate if we moved a piece adjacent to the king
&& !(attacks_bb<KING>(pos.square<KING>(us)) & move.from_sq())