/// ordering is at the current node.
MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const HistoryStats& h,
- const CounterMoveStats& cmh, Move cm, Search::Stack* s)
- : pos(p), history(h), counterMoveHistory(&cmh), ss(s), countermove(cm), depth(d) {
+ const CounterMoveStats& cmh, const CounterMoveStats& fmh, Move cm, Search::Stack* s)
+ : pos(p), history(h), counterMoveHistory(&cmh), followupMoveHistory(&fmh), ss(s), countermove(cm), depth(d) {
assert(d > DEPTH_ZERO);
MovePicker::MovePicker(const Position& p, Move ttm, Depth d,
const HistoryStats& h, Square s)
- : pos(p), history(h), counterMoveHistory(nullptr) {
+ : pos(p), history(h), counterMoveHistory(nullptr), followupMoveHistory(nullptr) {
assert(d <= DEPTH_ZERO);
}
MovePicker::MovePicker(const Position& p, Move ttm, const HistoryStats& h, Value th)
- : pos(p), history(h), counterMoveHistory(nullptr), threshold(th) {
+ : pos(p), history(h), counterMoveHistory(nullptr), followupMoveHistory(nullptr), threshold(th) {
assert(!pos.checkers());
for (auto& m : *this)
m.value = history[pos.moved_piece(m)][to_sq(m)]
- + (*counterMoveHistory)[pos.moved_piece(m)][to_sq(m)];
+ + (*counterMoveHistory)[pos.moved_piece(m)][to_sq(m)]
+ + (*followupMoveHistory)[pos.moved_piece(m)][to_sq(m)];
}
template<>
MovePicker(const Position&, Move, Depth, const HistoryStats&, Square);
MovePicker(const Position&, Move, const HistoryStats&, Value);
- MovePicker(const Position&, Move, Depth, const HistoryStats&, const CounterMoveStats&, Move, Search::Stack*);
+ MovePicker(const Position&, Move, Depth, const HistoryStats&, const CounterMoveStats&, const CounterMoveStats&, Move, Search::Stack*);
Move next_move();
const Position& pos;
const HistoryStats& history;
const CounterMoveStats* counterMoveHistory;
+ const CounterMoveStats* followupMoveHistory;
Search::Stack* ss;
Move countermove;
Depth depth;
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
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