for (int d = 1; d < 64; ++d)
for (int mc = 1; mc < 64; ++mc)
{
- double r = log(d) * log(mc) / 1.95;
+ double slope = d > 2 ? 0.88 * d + 0.36 : d;
+ double r = log(slope) * log(mc) / 1.95;
Reductions[NonPV][imp][d][mc] = int(std::round(r));
Reductions[PV][imp][d][mc] = std::max(Reductions[NonPV][imp][d][mc] - 1, 0);
std::memset(ss-4, 0, 7 * sizeof(Stack));
for (int i = 4; i > 0; i--)
- (ss-i)->contHistory = this->contHistory[NO_PIECE][0].get(); // Use as sentinel
+ (ss-i)->continuationHistory = this->continuationHistory[NO_PIECE][0].get(); // Use as sentinel
bestValue = delta = alpha = -VALUE_INFINITE;
beta = VALUE_INFINITE;
if (idx > 0)
{
int i = (idx - 1) % 20;
- if (((rootDepth / ONE_PLY + rootPos.game_ply() + SkipPhase[i]) / SkipSize[i]) % 2)
+ if (((rootDepth / ONE_PLY + SkipPhase[i]) / SkipSize[i]) % 2)
continue; // Retry with an incremented rootDepth
}
(ss+1)->ply = ss->ply + 1;
ss->currentMove = (ss+1)->excludedMove = bestMove = MOVE_NONE;
- ss->contHistory = thisThread->contHistory[NO_PIECE][0].get();
+ ss->continuationHistory = thisThread->continuationHistory[NO_PIECE][0].get();
(ss+2)->killers[0] = (ss+2)->killers[1] = MOVE_NONE;
Square prevSq = to_sq((ss-1)->currentMove);
Depth R = ((823 + 67 * depth / ONE_PLY) / 256 + std::min((eval - beta) / PawnValueMg, 3)) * ONE_PLY;
ss->currentMove = MOVE_NULL;
- ss->contHistory = thisThread->contHistory[NO_PIECE][0].get();
+ ss->continuationHistory = thisThread->continuationHistory[NO_PIECE][0].get();
pos.do_null_move(st);
probCutCount++;
ss->currentMove = move;
- ss->contHistory = thisThread->contHistory[pos.moved_piece(move)][to_sq(move)].get();
+ ss->continuationHistory = thisThread->continuationHistory[pos.moved_piece(move)][to_sq(move)].get();
assert(depth >= 5 * ONE_PLY);
moves_loop: // When in check, search starts from here
- const PieceToHistory* contHist[] = { (ss-1)->contHistory, (ss-2)->contHistory, nullptr, (ss-4)->contHistory };
+ const PieceToHistory* contHist[] = { (ss-1)->continuationHistory, (ss-2)->continuationHistory, nullptr, (ss-4)->continuationHistory };
Move countermove = thisThread->counterMoves[pos.piece_on(prevSq)][prevSq];
MovePicker mp(pos, ttMove, depth, &thisThread->mainHistory,
// Update the current move (this must be done after singular extension search)
ss->currentMove = move;
- ss->contHistory = thisThread->contHistory[movedPiece][to_sq(move)].get();
+ ss->continuationHistory = thisThread->continuationHistory[movedPiece][to_sq(move)].get();
// Step 15. Make the move
pos.do_move(move, st, givesCheck);
if (captureOrPromotion) // (~5 Elo)
{
- // Increase reduction by comparing opponent's stat score
- if ((ss-1)->statScore >= 0)
- r += ONE_PLY;
-
- r -= r ? ONE_PLY : DEPTH_ZERO;
+ // Decrease reduction by comparing opponent's stat score
+ if ((ss-1)->statScore < 0)
+ r -= ONE_PLY;
}
else
{
r += ONE_PLY;
// Decrease/increase reduction for moves with a good/bad history (~30 Elo)
- r = std::max(DEPTH_ZERO, (r / ONE_PLY - ss->statScore / 20000) * ONE_PLY);
+ r -= ss->statScore / 20000 * ONE_PLY;
}
- Depth d = std::max(newDepth - r, ONE_PLY);
+ Depth d = std::max(newDepth - std::max(r, DEPTH_ZERO), ONE_PLY);
value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d, true);
if (!pos.capture_or_promotion(bestMove))
update_quiet_stats(pos, ss, bestMove, quietsSearched, quietCount,
stat_bonus(depth + (bestValue > beta + PawnValueMg ? ONE_PLY : DEPTH_ZERO)));
- else
- update_capture_stats(pos, bestMove, capturesSearched, captureCount, stat_bonus(depth + ONE_PLY));
+
+ update_capture_stats(pos, bestMove, capturesSearched, captureCount, stat_bonus(depth + ONE_PLY));
// Extra penalty for a quiet TT move in previous ply when it gets refuted
if ((ss-1)->moveCount == 1 && !pos.captured_piece())
ss->pv[0] = MOVE_NONE;
}
+ Thread* thisThread = pos.this_thread();
(ss+1)->ply = ss->ply + 1;
ss->currentMove = bestMove = MOVE_NONE;
+ ss->continuationHistory = thisThread->continuationHistory[NO_PIECE][0].get();
inCheck = pos.checkers();
moveCount = 0;
&& ttHit
&& tte->depth() >= ttDepth
&& ttValue != VALUE_NONE // Only in case of TT access race
- && (ttValue >= beta ? (tte->bound() & BOUND_LOWER)
- : (tte->bound() & BOUND_UPPER)))
+ && (ttValue >= beta ? (tte->bound() & BOUND_LOWER)
+ : (tte->bound() & BOUND_UPPER)))
return ttValue;
// Evaluate the position statically
ss->staticEval = bestValue = evaluate(pos);
// Can ttValue be used as a better position evaluation?
- if ( ttValue != VALUE_NONE
+ if ( ttValue != VALUE_NONE
&& (tte->bound() & (ttValue > bestValue ? BOUND_LOWER : BOUND_UPPER)))
bestValue = ttValue;
}
futilityBase = bestValue + 128;
}
+ const PieceToHistory* contHist[] = { (ss-1)->continuationHistory, (ss-2)->continuationHistory, nullptr, (ss-4)->continuationHistory };
+
// Initialize a MovePicker object for the current position, and prepare
// to search the moves. Because the depth is <= 0 here, only captures,
// queen promotions and checks (only if depth >= DEPTH_QS_CHECKS) will
// be generated.
- MovePicker mp(pos, ttMove, depth, &pos.this_thread()->mainHistory,
- &pos.this_thread()->captureHistory,
+ MovePicker mp(pos, ttMove, depth, &thisThread->mainHistory,
+ &thisThread->captureHistory,
+ contHist,
to_sq((ss-1)->currentMove));
// Loop through the moves until no moves remain or a beta cutoff occurs
}
ss->currentMove = move;
+ ss->continuationHistory = thisThread->continuationHistory[pos.moved_piece(move)][to_sq(move)].get();
// Make and search the move
pos.do_move(move, st, givesCheck);
for (int i : {1, 2, 4})
if (is_ok((ss-i)->currentMove))
- (*(ss-i)->contHistory)[pc][to] << bonus;
+ (*(ss-i)->continuationHistory)[pc][to] << bonus;
}
CapturePieceToHistory& captureHistory = pos.this_thread()->captureHistory;
Piece moved_piece = pos.moved_piece(move);
PieceType captured = type_of(pos.piece_on(to_sq(move)));
- captureHistory[moved_piece][to_sq(move)][captured] << bonus;
+
+ if (pos.capture_or_promotion(move))
+ captureHistory[moved_piece][to_sq(move)][captured] << bonus;
// Decrease all the other played capture moves
for (int i = 0; i < captureCnt; ++i)