void Search::init() {
- const double K[][2] = {{ 0.799, 2.281 }, { 0.484, 3.023 }};
+ const bool PV=true;
- for (int pv = 0; pv <= 1; ++pv)
- for (int imp = 0; imp <= 1; ++imp)
- for (int d = 1; d < 64; ++d)
- for (int mc = 1; mc < 64; ++mc)
- {
- double r = K[pv][0] + log(d) * log(mc) / K[pv][1];
-
- if (r >= 1.5)
- Reductions[pv][imp][d][mc] = int(r) * ONE_PLY;
-
- // Increase reduction when eval is not improving
- if (!pv && !imp && Reductions[pv][imp][d][mc] >= 2 * ONE_PLY)
- Reductions[pv][imp][d][mc] += ONE_PLY;
- }
+ for (int imp = 0; imp <= 1; ++imp)
+ for (int d = 1; d < 64; ++d)
+ for (int mc = 1; mc < 64; ++mc)
+ {
+ double r = log(d) * log(mc) / 2;
+ if (r < 0.80)
+ continue;
+
+ Reductions[!PV][imp][d][mc] = int(std::round(r)) * ONE_PLY;
+ Reductions[PV][imp][d][mc] = std::max(Reductions[!PV][imp][d][mc] - ONE_PLY, DEPTH_ZERO);
+
+ // Increase reduction for non-PV nodes when eval is not improving
+ if (!imp && Reductions[!PV][imp][d][mc] >= 2 * ONE_PLY)
+ Reductions[!PV][imp][d][mc] += ONE_PLY;
+ }
for (int d = 0; d < 16; ++d)
{
moves_loop: // When in check search starts from here
Square prevSq = to_sq((ss-1)->currentMove);
+ Square ownPrevSq = to_sq((ss-2)->currentMove);
Move cm = thisThread->counterMoves[pos.piece_on(prevSq)][prevSq];
const CounterMoveStats& cmh = CounterMoveHistory[pos.piece_on(prevSq)][prevSq];
+ const CounterMoveStats& fmh = CounterMoveHistory[pos.piece_on(ownPrevSq)][ownPrevSq];
- MovePicker mp(pos, ttMove, depth, thisThread->history, cmh, cm, ss);
+ MovePicker mp(pos, ttMove, depth, thisThread->history, cmh, fmh, cm, ss);
CheckInfo ci(pos);
value = bestValue; // Workaround a bogus 'uninitialized' warning under gcc
improving = ss->staticEval >= (ss-2)->staticEval
&& !captureOrPromotion)
{
Depth r = reduction<PvNode>(improving, depth, moveCount);
+ Value hValue = thisThread->history[pos.piece_on(to_sq(move))][to_sq(move)];
+ Value cmhValue = cmh[pos.piece_on(to_sq(move))][to_sq(move)];
// Increase reduction for cut nodes and moves with a bad history
if ( (!PvNode && cutNode)
- || ( thisThread->history[pos.piece_on(to_sq(move))][to_sq(move)] < VALUE_ZERO
- && cmh[pos.piece_on(to_sq(move))][to_sq(move)] <= VALUE_ZERO))
+ || (hValue < VALUE_ZERO && cmhValue <= VALUE_ZERO))
r += ONE_PLY;
// Decrease/increase reduction for moves with a good/bad history
- int rHist = ( thisThread->history[pos.piece_on(to_sq(move))][to_sq(move)]
- + cmh[pos.piece_on(to_sq(move))][to_sq(move)]) / 14980;
+ int rHist = (hValue + cmhValue) / 14980;
r = std::max(DEPTH_ZERO, r - rHist * ONE_PLY);
// Decrease reduction for moves that escape a capture. Filter out
Value bonus = Value((depth / ONE_PLY) * (depth / ONE_PLY) + depth / ONE_PLY - 1);
Square prevSq = to_sq((ss-1)->currentMove);
+ Square ownPrevSq = to_sq((ss-2)->currentMove);
CounterMoveStats& cmh = CounterMoveHistory[pos.piece_on(prevSq)][prevSq];
+ CounterMoveStats& fmh = CounterMoveHistory[pos.piece_on(ownPrevSq)][ownPrevSq];
Thread* thisThread = pos.this_thread();
thisThread->history.update(pos.moved_piece(move), to_sq(move), bonus);
cmh.update(pos.moved_piece(move), to_sq(move), bonus);
}
+ if (is_ok((ss-2)->currentMove))
+ fmh.update(pos.moved_piece(move), to_sq(move), bonus);
+
// Decrease all the other played quiet moves
for (int i = 0; i < quietsCnt; ++i)
{
if (is_ok((ss-1)->currentMove))
cmh.update(pos.moved_piece(quiets[i]), to_sq(quiets[i]), -bonus);
+
+ if (is_ok((ss-2)->currentMove))
+ fmh.update(pos.moved_piece(quiets[i]), to_sq(quiets[i]), -bonus);
}
// Extra penalty for a quiet TT move in previous ply when it gets refuted