/// ordering is at the current node.
/// MovePicker constructor for the main search
-MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const ButterflyHistory* mh, const LowPlyHistory* lp,
- const CapturePieceToHistory* cph, const PieceToHistory** ch, Move cm, const Move* killers, int pl)
- : pos(p), mainHistory(mh), lowPlyHistory(lp), captureHistory(cph), continuationHistory(ch),
- ttMove(ttm), refutations{{killers[0], 0}, {killers[1], 0}, {cm, 0}}, depth(d), ply(pl) {
-
+MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const ButterflyHistory* mh,
+ const CapturePieceToHistory* cph,
+ const PieceToHistory** ch,
+ Move cm,
+ const Move* killers)
+ : pos(p), mainHistory(mh), captureHistory(cph), continuationHistory(ch),
+ ttMove(ttm), refutations{{killers[0], 0}, {killers[1], 0}, {cm, 0}}, depth(d)
+{
assert(d > 0);
stage = (pos.checkers() ? EVASION_TT : MAIN_TT) +
/// MovePicker constructor for quiescence search
MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const ButterflyHistory* mh,
- const CapturePieceToHistory* cph, const PieceToHistory** ch, Square rs)
- : pos(p), mainHistory(mh), captureHistory(cph), continuationHistory(ch), ttMove(ttm), recaptureSquare(rs), depth(d) {
-
+ const CapturePieceToHistory* cph,
+ const PieceToHistory** ch,
+ Square rs)
+ : pos(p), mainHistory(mh), captureHistory(cph), continuationHistory(ch), ttMove(ttm), recaptureSquare(rs), depth(d)
+{
assert(d <= 0);
stage = (pos.checkers() ? EVASION_TT : QSEARCH_TT) +
/// MovePicker constructor for ProbCut: we generate captures with SEE greater
/// than or equal to the given threshold.
MovePicker::MovePicker(const Position& p, Move ttm, Value th, const CapturePieceToHistory* cph)
- : pos(p), captureHistory(cph), ttMove(ttm), threshold(th) {
-
+ : pos(p), captureHistory(cph), ttMove(ttm), threshold(th)
+{
assert(!pos.checkers());
stage = PROBCUT_TT + !(ttm && pos.capture(ttm)
+ 2 * (*continuationHistory[0])[pos.moved_piece(m)][to_sq(m)]
+ (*continuationHistory[1])[pos.moved_piece(m)][to_sq(m)]
+ (*continuationHistory[3])[pos.moved_piece(m)][to_sq(m)]
- + (*continuationHistory[5])[pos.moved_piece(m)][to_sq(m)]
- + (ply < MAX_LPH ? 6 * (*lowPlyHistory)[ply][from_to(m)] : 0);
+ + (*continuationHistory[5])[pos.moved_piece(m)][to_sq(m)];
else // Type == EVASIONS
{
/// the move's from and to squares, see www.chessprogramming.org/Butterfly_Boards
typedef Stats<int16_t, 14365, COLOR_NB, int(SQUARE_NB) * int(SQUARE_NB)> ButterflyHistory;
-/// At higher depths LowPlyHistory records successful quiet moves near the root
-/// and quiet moves which are/were in the PV (ttPv). LowPlyHistory is populated during
-/// iterative deepening and at each new search the data is shifted down by 2 plies
-constexpr int MAX_LPH = 4;
-typedef Stats<int16_t, 10692, MAX_LPH, int(SQUARE_NB) * int(SQUARE_NB)> LowPlyHistory;
-
/// CounterMoveHistory stores counter moves indexed by [piece][to] of the previous
/// move, see www.chessprogramming.org/Countermove_Heuristic
typedef Stats<Move, NOT_USED, PIECE_NB, SQUARE_NB> CounterMoveHistory;
public:
MovePicker(const MovePicker&) = delete;
MovePicker& operator=(const MovePicker&) = delete;
- MovePicker(const Position&, Move, Value, const CapturePieceToHistory*);
MovePicker(const Position&, Move, Depth, const ButterflyHistory*,
const CapturePieceToHistory*,
const PieceToHistory**,
- Square);
+ Move,
+ const Move*);
MovePicker(const Position&, Move, Depth, const ButterflyHistory*,
- const LowPlyHistory*,
const CapturePieceToHistory*,
const PieceToHistory**,
- Move,
- const Move*,
- int);
+ Square);
+ MovePicker(const Position&, Move, Value, const CapturePieceToHistory*);
Move next_move(bool skipQuiets = false);
private:
const Position& pos;
const ButterflyHistory* mainHistory;
- const LowPlyHistory* lowPlyHistory;
const CapturePieceToHistory* captureHistory;
const PieceToHistory** continuationHistory;
Move ttMove;
Square recaptureSquare;
Value threshold;
Depth depth;
- int ply;
ExtMove moves[MAX_MOVES];
};
Value value_from_tt(Value v, int ply, int r50c);
void update_pv(Move* pv, Move move, Move* childPv);
void update_continuation_histories(Stack* ss, Piece pc, Square to, int bonus);
- void update_quiet_stats(const Position& pos, Stack* ss, Move move, int bonus, int depth);
+ void update_quiet_stats(const Position& pos, Stack* ss, Move move, int bonus);
void update_all_stats(const Position& pos, Stack* ss, Move bestMove, Value bestValue, Value beta, Square prevSq,
Move* quietsSearched, int quietCount, Move* capturesSearched, int captureCount, Depth depth);
mainThread->iterValue[i] = mainThread->bestPreviousScore;
}
- std::copy(&lowPlyHistory[2][0], &lowPlyHistory.back().back() + 1, &lowPlyHistory[0][0]);
- std::fill(&lowPlyHistory[MAX_LPH - 2][0], &lowPlyHistory.back().back() + 1, 0);
-
size_t multiPV = size_t(Options["MultiPV"]);
Skill skill(Options["Skill Level"], Options["UCI_LimitStrength"] ? int(Options["UCI_Elo"]) : 0);
if (!excludedMove)
ss->ttPv = PvNode || (ss->ttHit && tte->is_pv());
- // Update low ply history for previous move if we are near root and position is or has been in PV
- if ( ss->ttPv
- && depth > 12
- && ss->ply - 1 < MAX_LPH
- && !priorCapture
- && is_ok((ss-1)->currentMove))
- thisThread->lowPlyHistory[ss->ply - 1][from_to((ss-1)->currentMove)] << stat_bonus(depth - 5);
-
// At non-PV nodes we check for an early TT cutoff
if ( !PvNode
&& ss->ttHit
{
// Bonus for a quiet ttMove that fails high
if (!ttCapture)
- update_quiet_stats(pos, ss, ttMove, stat_bonus(depth), depth);
+ update_quiet_stats(pos, ss, ttMove, stat_bonus(depth));
// Extra penalty for early quiet moves of the previous ply
if ((ss-1)->moveCount <= 2 && !priorCapture)
Move countermove = thisThread->counterMoves[pos.piece_on(prevSq)][prevSq];
MovePicker mp(pos, ttMove, depth, &thisThread->mainHistory,
- &thisThread->lowPlyHistory,
&captureHistory,
contHist,
countermove,
- ss->killers,
- ss->ply);
+ ss->killers);
value = bestValue;
moveCountPruning = false;
if (!pos.capture_or_promotion(bestMove))
{
// Increase stats for the best move in case it was a quiet move
- update_quiet_stats(pos, ss, bestMove, bonus2, depth);
+ update_quiet_stats(pos, ss, bestMove, bonus2);
// Decrease stats for all non-best quiet moves
for (int i = 0; i < quietCount; ++i)
// update_quiet_stats() updates move sorting heuristics
- void update_quiet_stats(const Position& pos, Stack* ss, Move move, int bonus, int depth) {
+ void update_quiet_stats(const Position& pos, Stack* ss, Move move, int bonus) {
// Update killers
if (ss->killers[0] != move)
Square prevSq = to_sq((ss-1)->currentMove);
thisThread->counterMoves[pos.piece_on(prevSq)][prevSq] = move;
}
-
- // Update low ply history
- if (depth > 11 && ss->ply < MAX_LPH)
- thisThread->lowPlyHistory[ss->ply][from_to(move)] << stat_bonus(depth - 7);
}
// When playing with strength handicap, choose best move among a set of RootMoves
counterMoves.fill(MOVE_NONE);
mainHistory.fill(0);
- lowPlyHistory.fill(0);
captureHistory.fill(0);
for (bool inCheck : { false, true })
Value rootDelta;
CounterMoveHistory counterMoves;
ButterflyHistory mainHistory;
- LowPlyHistory lowPlyHistory;
CapturePieceToHistory captureHistory;
ContinuationHistory continuationHistory[2][2];
Score trend;