int FutilityMoveCounts[2][16]; // [improving][depth]
int Reductions[2][2][64][64]; // [pv][improving][depth][moveNumber]
int FutilityMoveCounts[2][16]; // [improving][depth]
int Reductions[2][2][64][64]; // [pv][improving][depth][moveNumber]
template <bool PvNode> Depth reduction(bool i, Depth d, int mn) {
return Reductions[PvNode][i][std::min(d / ONE_PLY, 63)][std::min(mn, 63)] * ONE_PLY;
}
// History and stats update bonus, based on depth
template <bool PvNode> Depth reduction(bool i, Depth d, int mn) {
return Reductions[PvNode][i][std::min(d / ONE_PLY, 63)][std::min(mn, 63)] * ONE_PLY;
}
// History and stats update bonus, based on depth
- // EasyMoveManager structure is used to detect an 'easy move'. When the PV is
- // stable across multiple search iterations, we can quickly return the best move.
+ // EasyMoveManager structure is used to detect an 'easy move'. When the PV is stable
+ // across multiple search iterations, we can quickly return the best move.
Value value_to_tt(Value v, int ply);
Value value_from_tt(Value v, int ply);
void update_pv(Move* pv, Move move, Move* childPv);
Value value_to_tt(Value v, int ply);
Value value_from_tt(Value v, int ply);
void update_pv(Move* pv, Move move, Move* childPv);
- void update_cm_stats(Stack* ss, Piece pc, Square s, Value bonus);
- void update_stats(const Position& pos, Stack* ss, Move move, Move* quiets, int quietsCnt, Value bonus);
+ void update_cm_stats(Stack* ss, Piece pc, Square s, int bonus);
+ void update_stats(const Position& pos, Stack* ss, Move move, Move* quiets, int quietsCnt, int bonus);
Reductions[NonPV][imp][d][mc] = int(std::round(r));
Reductions[PV][imp][d][mc] = std::max(Reductions[NonPV][imp][d][mc] - 1, 0);
Reductions[NonPV][imp][d][mc] = int(std::round(r));
Reductions[PV][imp][d][mc] = std::max(Reductions[NonPV][imp][d][mc] - 1, 0);
- FutilityMoveCounts[0][d] = int(2.4 + 0.773 * pow(d + 0.00, 1.8));
- FutilityMoveCounts[1][d] = int(2.9 + 1.045 * pow(d + 0.49, 1.8));
+ FutilityMoveCounts[0][d] = int(2.4 + 0.74 * pow(d, 1.78));
+ FutilityMoveCounts[1][d] = int(5.0 + 1.00 * pow(d, 2.00));
Depth extension, newDepth;
Value bestValue, value, ttValue, eval;
bool ttHit, inCheck, givesCheck, singularExtensionNode, improving;
Depth extension, newDepth;
Value bestValue, value, ttValue, eval;
bool ttHit, inCheck, givesCheck, singularExtensionNode, improving;
- bool captureOrPromotion, doFullDepthSearch, moveCountPruning;
+ bool captureOrPromotion, doFullDepthSearch, moveCountPruning, skipQuiets;
Thread* thisThread = pos.this_thread();
inCheck = pos.checkers();
moveCount = quietCount = ss->moveCount = 0;
Thread* thisThread = pos.this_thread();
inCheck = pos.checkers();
moveCount = quietCount = ss->moveCount = 0;
thisThread->history.update(pos.side_to_move(), ttMove, penalty);
update_cm_stats(ss, pos.moved_piece(ttMove), to_sq(ttMove), penalty);
}
thisThread->history.update(pos.side_to_move(), ttMove, penalty);
update_cm_stats(ss, pos.moved_piece(ttMove), to_sq(ttMove), penalty);
}
const CounterMoveStats& cmh = *(ss-1)->counterMoves;
const CounterMoveStats& fmh = *(ss-2)->counterMoves;
const CounterMoveStats& fm2 = *(ss-4)->counterMoves;
const CounterMoveStats& cmh = *(ss-1)->counterMoves;
const CounterMoveStats& fmh = *(ss-2)->counterMoves;
const CounterMoveStats& fm2 = *(ss-4)->counterMoves;
MovePicker mp(pos, ttMove, depth, ss);
value = bestValue; // Workaround a bogus 'uninitialized' warning under gcc
MovePicker mp(pos, ttMove, depth, ss);
value = bestValue; // Workaround a bogus 'uninitialized' warning under gcc
&& !excludedMove // Recursive singular search is not allowed
&& (tte->bound() & BOUND_LOWER)
&& tte->depth() >= depth - 3 * ONE_PLY;
&& !excludedMove // Recursive singular search is not allowed
&& (tte->bound() & BOUND_LOWER)
&& tte->depth() >= depth - 3 * ONE_PLY;
// Step 11. Loop through moves
// Loop through all pseudo-legal moves until no moves remain or a beta cutoff occurs
// Step 11. Loop through moves
// Loop through all pseudo-legal moves until no moves remain or a beta cutoff occurs
moveCountPruning = depth < 16 * ONE_PLY
&& moveCount >= FutilityMoveCounts[improving][depth / ONE_PLY];
moveCountPruning = depth < 16 * ONE_PLY
&& moveCount >= FutilityMoveCounts[improving][depth / ONE_PLY];
// Singular extension search. If all moves but one fail low on a search of
// (alpha-s, beta-s), and just one fails high on (alpha, beta), then that move
// Singular extension search. If all moves but one fail low on a search of
// (alpha-s, beta-s), and just one fails high on (alpha, beta), then that move
// Calculate new depth for this move
newDepth = depth - ONE_PLY + extension;
// Step 13. Pruning at shallow depth
if ( !rootNode
// Calculate new depth for this move
newDepth = depth - ONE_PLY + extension;
// Step 13. Pruning at shallow depth
if ( !rootNode
// Reduced depth of the next LMR search
int lmrDepth = std::max(newDepth - reduction<PvNode>(improving, depth, moveCount), DEPTH_ZERO) / ONE_PLY;
// Countermoves based pruning
if ( lmrDepth < 3
// Reduced depth of the next LMR search
int lmrDepth = std::max(newDepth - reduction<PvNode>(improving, depth, moveCount), DEPTH_ZERO) / ONE_PLY;
// Countermoves based pruning
if ( lmrDepth < 3
- && ((cmh[moved_piece][to_sq(move)] < VALUE_ZERO) || !cm_ok)
- && ((fmh[moved_piece][to_sq(move)] < VALUE_ZERO) || !fm_ok)
- && ((fm2[moved_piece][to_sq(move)] < VALUE_ZERO) || !f2_ok || (cm_ok && fm_ok)))
+ && (cmh[moved_piece][to_sq(move)] < CounterMovePruneThreshold)
+ && (fmh[moved_piece][to_sq(move)] < CounterMovePruneThreshold))
update_cm_stats(ss-1, pos.piece_on(prevSq), prevSq, stat_bonus(depth));
update_cm_stats(ss-1, pos.piece_on(prevSq), prevSq, stat_bonus(depth));
- tte->save(posKey, value_to_tt(bestValue, ss->ply),
- bestValue >= beta ? BOUND_LOWER :
- PvNode && bestMove ? BOUND_EXACT : BOUND_UPPER,
- depth, bestMove, ss->staticEval, TT.generation());
+ if(!excludedMove)
+ tte->save(posKey, value_to_tt(bestValue, ss->ply),
+ bestValue >= beta ? BOUND_LOWER :
+ PvNode && bestMove ? BOUND_EXACT : BOUND_UPPER,
+ depth, bestMove, ss->staticEval, TT.generation());
- void update_cm_stats(Stack* ss, Piece pc, Square s, Value bonus) {
+ void update_cm_stats(Stack* ss, Piece pc, Square s, int bonus) {
// update_stats() updates move sorting heuristics when a new quiet best move is found
void update_stats(const Position& pos, Stack* ss, Move move,
// update_stats() updates move sorting heuristics when a new quiet best move is found
void update_stats(const Position& pos, Stack* ss, Move move,