Move get(Key key) const {
return expectedPosKey == key? pv[2] : MOVE_NONE;
}
void update(Position& pos, const std::vector& newPv) {
assert(newPv.size() >= 3);
// Keep track of how many times in a row the 3rd ply remains stable
stableCnt = (newPv[2] == pv[2]) ? stableCnt + 1 : 0;
if (!std::equal(newPv.begin(), newPv.begin() + 3, pv))
{
std::copy(newPv.begin(), newPv.begin() + 3, pv);
StateInfo st[2];
pos.do_move(newPv[0], st[0], pos.gives_check(newPv[0], CheckInfo(pos)));
pos.do_move(newPv[1], st[1], pos.gives_check(newPv[1], CheckInfo(pos)));
expectedPosKey = pos.key();
pos.undo_move(newPv[1]);
pos.undo_move(newPv[0]);
}
}
int stableCnt;
Key expectedPosKey;
Move pv[3];
};
// Set of rows with half bits set to 1 and half to 0. It is used to allocate
// the search depths across the threads.
typedef std::vector Row;
const Row HalfDensity[] = {
{0, 1},
{1, 0},
{0, 0, 1, 1},
{0, 1, 1, 0},
{1, 1, 0, 0},
{1, 0, 0, 1},
{0, 0, 0, 1, 1, 1},
{0, 0, 1, 1, 1, 0},
{0, 1, 1, 1, 0, 0},
{1, 1, 1, 0, 0, 0},
{1, 1, 0, 0, 0, 1},
{1, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 1, 1, 1, 1},
{0, 0, 0, 1, 1, 1, 1, 0},
{0, 0, 1, 1, 1, 1, 0, 0},
{0, 1, 1, 1, 1, 0, 0, 0},
{1, 1, 1, 1, 0, 0, 0, 0},
{1, 1, 1, 0, 0, 0, 0, 1},
{1, 1, 0, 0, 0, 0, 1, 1},
{1, 0, 0, 0, 0, 1, 1, 1},
};
const size_t HalfDensitySize = std::extent::value;
EasyMoveManager EasyMove;
Value DrawValue[COLOR_NB];
CounterMoveHistoryStats CounterMoveHistory;
template
Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, bool cutNode);
template
Value qsearch(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth);
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_stats(const Position& pos, Stack* ss, Move move, Depth depth, Move* quiets, int quietsCnt);
void check_time();
} // namespace
/// Search::init() is called during startup to initialize various lookup tables
void Search::init() {
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[NonPV][imp][d][mc] = int(std::round(r)) * ONE_PLY;
Reductions[PV][imp][d][mc] = std::max(Reductions[NonPV][imp][d][mc] - ONE_PLY, DEPTH_ZERO);
// Increase reduction for non-PV nodes when eval is not improving
if (!imp && Reductions[NonPV][imp][d][mc] >= 2 * ONE_PLY)
Reductions[NonPV][imp][d][mc] += ONE_PLY;
return expectedPosKey == key? pv[2] : MOVE_NONE;
}
void update(Position& pos, const std::vector& newPv) {
assert(newPv.size() >= 3);
// Keep track of how many times in a row the 3rd ply remains stable
stableCnt = (newPv[2] == pv[2]) ? stableCnt + 1 : 0;
if (!std::equal(newPv.begin(), newPv.begin() + 3, pv))
{
std::copy(newPv.begin(), newPv.begin() + 3, pv);
StateInfo st[2];
pos.do_move(newPv[0], st[0], pos.gives_check(newPv[0], CheckInfo(pos)));
pos.do_move(newPv[1], st[1], pos.gives_check(newPv[1], CheckInfo(pos)));
expectedPosKey = pos.key();
pos.undo_move(newPv[1]);
pos.undo_move(newPv[0]);
}
}
int stableCnt;
Key expectedPosKey;
Move pv[3];
};
// Set of rows with half bits set to 1 and half to 0. It is used to allocate
// the search depths across the threads.
typedef std::vector Row;
const Row HalfDensity[] = {
{0, 1},
{1, 0},
{0, 0, 1, 1},
{0, 1, 1, 0},
{1, 1, 0, 0},
{1, 0, 0, 1},
{0, 0, 0, 1, 1, 1},
{0, 0, 1, 1, 1, 0},
{0, 1, 1, 1, 0, 0},
{1, 1, 1, 0, 0, 0},
{1, 1, 0, 0, 0, 1},
{1, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 1, 1, 1, 1},
{0, 0, 0, 1, 1, 1, 1, 0},
{0, 0, 1, 1, 1, 1, 0, 0},
{0, 1, 1, 1, 1, 0, 0, 0},
{1, 1, 1, 1, 0, 0, 0, 0},
{1, 1, 1, 0, 0, 0, 0, 1},
{1, 1, 0, 0, 0, 0, 1, 1},
{1, 0, 0, 0, 0, 1, 1, 1},
};
const size_t HalfDensitySize = std::extent::value;
EasyMoveManager EasyMove;
Value DrawValue[COLOR_NB];
CounterMoveHistoryStats CounterMoveHistory;
template
Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, bool cutNode);
template
Value qsearch(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth);
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_stats(const Position& pos, Stack* ss, Move move, Depth depth, Move* quiets, int quietsCnt);
void check_time();
} // namespace
/// Search::init() is called during startup to initialize various lookup tables
void Search::init() {
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[NonPV][imp][d][mc] = int(std::round(r)) * ONE_PLY;
Reductions[PV][imp][d][mc] = std::max(Reductions[NonPV][imp][d][mc] - ONE_PLY, DEPTH_ZERO);
// Increase reduction for non-PV nodes when eval is not improving
if (!imp && Reductions[NonPV][imp][d][mc] >= 2 * ONE_PLY)
Reductions[NonPV][imp][d][mc] += ONE_PLY;