}
// Add a small random component to draw evaluations to avoid 3fold-blindness
- Value value_draw(Depth depth, Thread* thisThread) {
- return depth < 4 * ONE_PLY ? VALUE_DRAW
- : VALUE_DRAW + Value(2 * (thisThread->nodes & 1) - 1);
+ Value value_draw(Thread* thisThread) {
+ return VALUE_DRAW + Value(2 * (thisThread->nodes & 1) - 1);
}
// Skill structure is used to implement strength limit
++failedHighCnt;
}
else
+ {
+ ++rootMoves[pvIdx].bestMoveCount;
break;
+ }
delta += delta / 4 + 5;
&& !rootNode
&& pos.has_game_cycle(ss->ply))
{
- alpha = value_draw(depth, pos.this_thread());
+ alpha = value_draw(pos.this_thread());
if (alpha >= beta)
return alpha;
}
|| pos.is_draw(ss->ply)
|| ss->ply >= MAX_PLY)
return (ss->ply >= MAX_PLY && !inCheck) ? evaluate(pos)
- : value_draw(depth, pos.this_thread());
+ : value_draw(pos.this_thread());
// Step 3. Mate distance pruning. Even if we mate at the next move our score
// would be at best mate_in(ss->ply+1), but if alpha is already bigger because
if (eval == VALUE_NONE)
ss->staticEval = eval = evaluate(pos);
+ if (eval == VALUE_DRAW)
+ eval = value_draw(thisThread);
+
// Can ttValue be used as a better position evaluation?
if ( ttValue != VALUE_NONE
&& (tte->bound() & (ttValue > eval ? BOUND_LOWER : BOUND_UPPER)))
&& (pos.is_discovery_check_on_king(~us, move) || pos.see_ge(move)))
extension = ONE_PLY;
- // Castling extension
- else if (type_of(move) == CASTLING)
- extension = ONE_PLY;
-
// Shuffle extension
else if ( PvNode
&& pos.rule50_count() > 18
&& pos.advanced_pawn_push(move)
&& pos.pawn_passed(us, to_sq(move)))
extension = ONE_PLY;
+
+ // Castling extension
+ if (type_of(move) == CASTLING)
+ extension = ONE_PLY;
// Calculate new depth for this move
newDepth = depth - ONE_PLY + extension;
if (!pos.see_ge(move, Value(-(31 - std::min(lmrDepth, 18)) * lmrDepth * lmrDepth)))
continue;
}
- else if ( (!givesCheck || !extension)
+ else if ( !(givesCheck && extension)
&& !pos.see_ge(move, Value(-199) * (depth / ONE_PLY))) // (~20 Elo)
continue;
}
// Step 16. Reduced depth search (LMR). If the move fails high it will be
// re-searched at full depth.
if ( depth >= 3 * ONE_PLY
- && moveCount > 1 + 3 * rootNode
+ && moveCount > 1 + 2 * rootNode
+ && (!rootNode || thisThread->best_move_count(move) == 0)
&& ( !captureOrPromotion
|| moveCountPruning
|| ss->staticEval + PieceValue[EG][pos.captured_piece()] <= alpha
if ((ss-1)->moveCount > 15)
r -= ONE_PLY;
- // Decrease reduction if move has been singularly extended
+ // Decrease reduction if ttMove has been singularly extended
r -= singularLMR * ONE_PLY;
if (!captureOrPromotion)
// castling moves, because they are coded as "king captures rook" and
// hence break make_move(). (~5 Elo)
else if ( type_of(move) == NORMAL
- && !pos.see_ge(make_move(to_sq(move), from_sq(move))))
+ && !pos.see_ge(reverse_move(move)))
r -= 2 * ONE_PLY;
ss->statScore = thisThread->mainHistory[us][from_to(move)]
thisThread->mainHistory[us][from_to(move)] << bonus;
update_continuation_histories(ss, pos.moved_piece(move), to_sq(move), bonus);
+ if (type_of(pos.moved_piece(move)) != PAWN)
+ thisThread->mainHistory[us][from_to(reverse_move(move))] << -bonus;
+
if (is_ok((ss-1)->currentMove))
{
Square prevSq = to_sq((ss-1)->currentMove);