1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-07-12 03:59:15 +00:00

Fix null move issue

Fix altering for stats landing on B1 Square after a null move and fix considering counter-moves on A1 for root node.

fixes https://github.com/official-stockfish/Stockfish/issues/4333 by preventing calls to from_sq and to_sq functions over null-moves and none-moves.

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

bench: 4980082
This commit is contained in:
peregrineshahin 2023-03-12 01:22:55 +03:00 committed by Joost VandeVondele
parent f0556dcbe3
commit 515b66f188
3 changed files with 21 additions and 14 deletions

View file

@ -605,7 +605,7 @@ namespace {
(ss+2)->killers[0] = (ss+2)->killers[1] = MOVE_NONE; (ss+2)->killers[0] = (ss+2)->killers[1] = MOVE_NONE;
(ss+2)->cutoffCnt = 0; (ss+2)->cutoffCnt = 0;
ss->doubleExtensions = (ss-1)->doubleExtensions; ss->doubleExtensions = (ss-1)->doubleExtensions;
Square prevSq = to_sq((ss-1)->currentMove); Square prevSq = is_ok((ss-1)->currentMove) ? to_sq((ss-1)->currentMove) : SQ_NONE;
// Initialize statScore to zero for the grandchildren of the current position. // Initialize statScore to zero for the grandchildren of the current position.
// So statScore is shared between all grandchildren and only the first grandchild // So statScore is shared between all grandchildren and only the first grandchild
@ -647,7 +647,7 @@ namespace {
update_quiet_stats(pos, ss, ttMove, stat_bonus(depth)); update_quiet_stats(pos, ss, ttMove, stat_bonus(depth));
// Extra penalty for early quiet moves of the previous ply (~0 Elo on STC, ~2 Elo on LTC) // Extra penalty for early quiet moves of the previous ply (~0 Elo on STC, ~2 Elo on LTC)
if ((ss-1)->moveCount <= 2 && !priorCapture) if (prevSq != SQ_NONE && (ss-1)->moveCount <= 2 && !priorCapture)
update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -stat_bonus(depth + 1)); update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -stat_bonus(depth + 1));
} }
// Penalty for a quiet ttMove that fails low (~1 Elo) // Penalty for a quiet ttMove that fails low (~1 Elo)
@ -935,7 +935,7 @@ moves_loop: // When in check, search starts here
nullptr , (ss-4)->continuationHistory, nullptr , (ss-4)->continuationHistory,
nullptr , (ss-6)->continuationHistory }; nullptr , (ss-6)->continuationHistory };
Move countermove = thisThread->counterMoves[pos.piece_on(prevSq)][prevSq]; Move countermove = prevSq != SQ_NONE ? thisThread->counterMoves[pos.piece_on(prevSq)][prevSq] : MOVE_NONE;
MovePicker mp(pos, ttMove, depth, &thisThread->mainHistory, MovePicker mp(pos, ttMove, depth, &thisThread->mainHistory,
&captureHistory, &captureHistory,
@ -1383,7 +1383,7 @@ moves_loop: // When in check, search starts here
quietsSearched, quietCount, capturesSearched, captureCount, depth); quietsSearched, quietCount, capturesSearched, captureCount, depth);
// Bonus for prior countermove that caused the fail low // Bonus for prior countermove that caused the fail low
else if (!priorCapture) else if (!priorCapture && prevSq != SQ_NONE)
{ {
int bonus = (depth > 5) + (PvNode || cutNode) + (bestValue < alpha - 97 * depth) + ((ss-1)->moveCount > 10); int bonus = (depth > 5) + (PvNode || cutNode) + (bestValue < alpha - 97 * depth) + ((ss-1)->moveCount > 10);
update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, stat_bonus(depth) * bonus); update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, stat_bonus(depth) * bonus);
@ -1525,7 +1525,7 @@ moves_loop: // When in check, search starts here
// to search the moves. Because the depth is <= 0 here, only captures, // to search the moves. Because the depth is <= 0 here, only captures,
// queen promotions, and other checks (only if depth >= DEPTH_QS_CHECKS) // queen promotions, and other checks (only if depth >= DEPTH_QS_CHECKS)
// will be generated. // will be generated.
Square prevSq = to_sq((ss-1)->currentMove); Square prevSq = (ss-1)->currentMove != MOVE_NULL ? to_sq((ss-1)->currentMove) : SQ_NONE;
MovePicker mp(pos, ttMove, depth, &thisThread->mainHistory, MovePicker mp(pos, ttMove, depth, &thisThread->mainHistory,
&thisThread->captureHistory, &thisThread->captureHistory,
contHist, contHist,
@ -1714,7 +1714,8 @@ moves_loop: // When in check, search starts here
Thread* thisThread = pos.this_thread(); Thread* thisThread = pos.this_thread();
CapturePieceToHistory& captureHistory = thisThread->captureHistory; CapturePieceToHistory& captureHistory = thisThread->captureHistory;
Piece moved_piece = pos.moved_piece(bestMove); Piece moved_piece = pos.moved_piece(bestMove);
PieceType captured = type_of(pos.piece_on(to_sq(bestMove))); PieceType captured;
int bonus1 = stat_bonus(depth + 1); int bonus1 = stat_bonus(depth + 1);
if (!pos.capture_stage(bestMove)) if (!pos.capture_stage(bestMove))
@ -1733,12 +1734,16 @@ moves_loop: // When in check, search starts here
} }
} }
else else
{
// Increase stats for the best move in case it was a capture move // Increase stats for the best move in case it was a capture move
captured = type_of(pos.piece_on(to_sq(bestMove)));
captureHistory[moved_piece][to_sq(bestMove)][captured] << bonus1; captureHistory[moved_piece][to_sq(bestMove)][captured] << bonus1;
}
// Extra penalty for a quiet early move that was not a TT move or // Extra penalty for a quiet early move that was not a TT move or
// main killer move in previous ply when it gets refuted. // main killer move in previous ply when it gets refuted.
if ( ((ss-1)->moveCount == 1 + (ss-1)->ttHit || ((ss-1)->currentMove == (ss-1)->killers[0])) if ( prevSq != SQ_NONE
&& ((ss-1)->moveCount == 1 + (ss-1)->ttHit || ((ss-1)->currentMove == (ss-1)->killers[0]))
&& !pos.captured_piece()) && !pos.captured_piece())
update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -bonus1); update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -bonus1);

View file

@ -416,6 +416,10 @@ inline Color color_of(Piece pc) {
return Color(pc >> 3); return Color(pc >> 3);
} }
constexpr bool is_ok(Move m) {
return m != MOVE_NONE && m != MOVE_NULL;
}
constexpr bool is_ok(Square s) { constexpr bool is_ok(Square s) {
return s >= SQ_A1 && s <= SQ_H8; return s >= SQ_A1 && s <= SQ_H8;
} }
@ -445,10 +449,12 @@ constexpr Direction pawn_push(Color c) {
} }
constexpr Square from_sq(Move m) { constexpr Square from_sq(Move m) {
assert(is_ok(m));
return Square((m >> 6) & 0x3F); return Square((m >> 6) & 0x3F);
} }
constexpr Square to_sq(Move m) { constexpr Square to_sq(Move m) {
assert(is_ok(m));
return Square(m & 0x3F); return Square(m & 0x3F);
} }
@ -473,10 +479,6 @@ constexpr Move make(Square from, Square to, PieceType pt = KNIGHT) {
return Move(T + ((pt - KNIGHT) << 12) + (from << 6) + to); return Move(T + ((pt - KNIGHT) << 12) + (from << 6) + to);
} }
constexpr bool is_ok(Move m) {
return from_sq(m) != to_sq(m); // Catch MOVE_NULL and MOVE_NONE
}
/// Based on a congruential pseudo random number generator /// Based on a congruential pseudo random number generator
constexpr Key make_key(uint64_t seed) { constexpr Key make_key(uint64_t seed) {
return seed * 6364136223846793005ULL + 1442695040888963407ULL; return seed * 6364136223846793005ULL + 1442695040888963407ULL;

View file

@ -358,15 +358,15 @@ std::string UCI::square(Square s) {
string UCI::move(Move m, bool chess960) { string UCI::move(Move m, bool chess960) {
Square from = from_sq(m);
Square to = to_sq(m);
if (m == MOVE_NONE) if (m == MOVE_NONE)
return "(none)"; return "(none)";
if (m == MOVE_NULL) if (m == MOVE_NULL)
return "0000"; return "0000";
Square from = from_sq(m);
Square to = to_sq(m);
if (type_of(m) == CASTLING && !chess960) if (type_of(m) == CASTLING && !chess960)
to = make_square(to > from ? FILE_G : FILE_C, rank_of(from)); to = make_square(to > from ? FILE_G : FILE_C, rank_of(from));