Skip to content

Commit 515b66f

Browse files
peregrineshahinvondele
authored andcommitted
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 #4333 by preventing calls to from_sq and to_sq functions over null-moves and none-moves. closes #4448 bench: 4980082
1 parent f0556dc commit 515b66f

File tree

3 files changed

+21
-14
lines changed

3 files changed

+21
-14
lines changed

src/search.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ namespace {
605605
(ss+2)->killers[0] = (ss+2)->killers[1] = MOVE_NONE;
606606
(ss+2)->cutoffCnt = 0;
607607
ss->doubleExtensions = (ss-1)->doubleExtensions;
608-
Square prevSq = to_sq((ss-1)->currentMove);
608+
Square prevSq = is_ok((ss-1)->currentMove) ? to_sq((ss-1)->currentMove) : SQ_NONE;
609609

610610
// Initialize statScore to zero for the grandchildren of the current position.
611611
// So statScore is shared between all grandchildren and only the first grandchild
@@ -647,7 +647,7 @@ namespace {
647647
update_quiet_stats(pos, ss, ttMove, stat_bonus(depth));
648648

649649
// Extra penalty for early quiet moves of the previous ply (~0 Elo on STC, ~2 Elo on LTC)
650-
if ((ss-1)->moveCount <= 2 && !priorCapture)
650+
if (prevSq != SQ_NONE && (ss-1)->moveCount <= 2 && !priorCapture)
651651
update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -stat_bonus(depth + 1));
652652
}
653653
// Penalty for a quiet ttMove that fails low (~1 Elo)
@@ -935,7 +935,7 @@ namespace {
935935
nullptr , (ss-4)->continuationHistory,
936936
nullptr , (ss-6)->continuationHistory };
937937

938-
Move countermove = thisThread->counterMoves[pos.piece_on(prevSq)][prevSq];
938+
Move countermove = prevSq != SQ_NONE ? thisThread->counterMoves[pos.piece_on(prevSq)][prevSq] : MOVE_NONE;
939939

940940
MovePicker mp(pos, ttMove, depth, &thisThread->mainHistory,
941941
&captureHistory,
@@ -1383,7 +1383,7 @@ namespace {
13831383
quietsSearched, quietCount, capturesSearched, captureCount, depth);
13841384

13851385
// Bonus for prior countermove that caused the fail low
1386-
else if (!priorCapture)
1386+
else if (!priorCapture && prevSq != SQ_NONE)
13871387
{
13881388
int bonus = (depth > 5) + (PvNode || cutNode) + (bestValue < alpha - 97 * depth) + ((ss-1)->moveCount > 10);
13891389
update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, stat_bonus(depth) * bonus);
@@ -1525,7 +1525,7 @@ namespace {
15251525
// to search the moves. Because the depth is <= 0 here, only captures,
15261526
// queen promotions, and other checks (only if depth >= DEPTH_QS_CHECKS)
15271527
// will be generated.
1528-
Square prevSq = to_sq((ss-1)->currentMove);
1528+
Square prevSq = (ss-1)->currentMove != MOVE_NULL ? to_sq((ss-1)->currentMove) : SQ_NONE;
15291529
MovePicker mp(pos, ttMove, depth, &thisThread->mainHistory,
15301530
&thisThread->captureHistory,
15311531
contHist,
@@ -1714,7 +1714,8 @@ namespace {
17141714
Thread* thisThread = pos.this_thread();
17151715
CapturePieceToHistory& captureHistory = thisThread->captureHistory;
17161716
Piece moved_piece = pos.moved_piece(bestMove);
1717-
PieceType captured = type_of(pos.piece_on(to_sq(bestMove)));
1717+
PieceType captured;
1718+
17181719
int bonus1 = stat_bonus(depth + 1);
17191720

17201721
if (!pos.capture_stage(bestMove))
@@ -1733,12 +1734,16 @@ namespace {
17331734
}
17341735
}
17351736
else
1737+
{
17361738
// Increase stats for the best move in case it was a capture move
1739+
captured = type_of(pos.piece_on(to_sq(bestMove)));
17371740
captureHistory[moved_piece][to_sq(bestMove)][captured] << bonus1;
1741+
}
17381742

17391743
// Extra penalty for a quiet early move that was not a TT move or
17401744
// main killer move in previous ply when it gets refuted.
1741-
if ( ((ss-1)->moveCount == 1 + (ss-1)->ttHit || ((ss-1)->currentMove == (ss-1)->killers[0]))
1745+
if ( prevSq != SQ_NONE
1746+
&& ((ss-1)->moveCount == 1 + (ss-1)->ttHit || ((ss-1)->currentMove == (ss-1)->killers[0]))
17421747
&& !pos.captured_piece())
17431748
update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -bonus1);
17441749

src/types.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,10 @@ inline Color color_of(Piece pc) {
416416
return Color(pc >> 3);
417417
}
418418

419+
constexpr bool is_ok(Move m) {
420+
return m != MOVE_NONE && m != MOVE_NULL;
421+
}
422+
419423
constexpr bool is_ok(Square s) {
420424
return s >= SQ_A1 && s <= SQ_H8;
421425
}
@@ -445,10 +449,12 @@ constexpr Direction pawn_push(Color c) {
445449
}
446450

447451
constexpr Square from_sq(Move m) {
452+
assert(is_ok(m));
448453
return Square((m >> 6) & 0x3F);
449454
}
450455

451456
constexpr Square to_sq(Move m) {
457+
assert(is_ok(m));
452458
return Square(m & 0x3F);
453459
}
454460

@@ -473,10 +479,6 @@ constexpr Move make(Square from, Square to, PieceType pt = KNIGHT) {
473479
return Move(T + ((pt - KNIGHT) << 12) + (from << 6) + to);
474480
}
475481

476-
constexpr bool is_ok(Move m) {
477-
return from_sq(m) != to_sq(m); // Catch MOVE_NULL and MOVE_NONE
478-
}
479-
480482
/// Based on a congruential pseudo random number generator
481483
constexpr Key make_key(uint64_t seed) {
482484
return seed * 6364136223846793005ULL + 1442695040888963407ULL;

src/uci.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,15 +358,15 @@ std::string UCI::square(Square s) {
358358

359359
string UCI::move(Move m, bool chess960) {
360360

361-
Square from = from_sq(m);
362-
Square to = to_sq(m);
363-
364361
if (m == MOVE_NONE)
365362
return "(none)";
366363

367364
if (m == MOVE_NULL)
368365
return "0000";
369366

367+
Square from = from_sq(m);
368+
Square to = to_sq(m);
369+
370370
if (type_of(m) == CASTLING && !chess960)
371371
to = make_square(to > from ? FILE_G : FILE_C, rank_of(from));
372372

0 commit comments

Comments
 (0)