- /// The BetaCounterType class
-
- BetaCounterType::BetaCounterType() { clear(); }
-
- void BetaCounterType::clear() {
-
- for (int i = 0; i < THREAD_MAX; i++)
- Threads[i].betaCutOffs[WHITE] = Threads[i].betaCutOffs[BLACK] = 0ULL;
- }
-
- void BetaCounterType::add(Color us, Depth d, int threadID) {
-
- // Weighted count based on depth
- Threads[threadID].betaCutOffs[us] += unsigned(d);
- }
-
- void BetaCounterType::read(Color us, int64_t& our, int64_t& their) {
-
- our = their = 0UL;
- for (int i = 0; i < THREAD_MAX; i++)
- {
- our += Threads[i].betaCutOffs[us];
- their += Threads[i].betaCutOffs[opposite_color(us)];
- }
- }
-
-
- /// The RootMove class
-
- // Constructor
-
- RootMove::RootMove() {
- nodes = cumulativeNodes = ourBeta = theirBeta = 0ULL;
- }
-
- // RootMove::operator<() is the comparison function used when
- // sorting the moves. A move m1 is considered to be better
- // than a move m2 if it has a higher score, or if the moves
- // have equal score but m1 has the higher node count.
-
- bool RootMove::operator<(const RootMove& m) const {
-
- if (score != m.score)
- return (score < m.score);
-
- return theirBeta <= m.theirBeta;
- }
-
- /// The RootMoveList class
-
- // Constructor
-
- RootMoveList::RootMoveList(Position& pos, Move searchMoves[]) : count(0) {
-
- MoveStack mlist[MaxRootMoves];
- bool includeAllMoves = (searchMoves[0] == MOVE_NONE);
-
- // Generate all legal moves
- MoveStack* last = generate_moves(pos, mlist);
-
- // Add each move to the moves[] array
- for (MoveStack* cur = mlist; cur != last; cur++)
- {
- bool includeMove = includeAllMoves;
-
- for (int k = 0; !includeMove && searchMoves[k] != MOVE_NONE; k++)
- includeMove = (searchMoves[k] == cur->move);
-
- if (!includeMove)
- continue;
-
- // Find a quick score for the move
- StateInfo st;
- SearchStack ss[PLY_MAX_PLUS_2];
- init_ss_array(ss);
-
- moves[count].move = cur->move;
- pos.do_move(moves[count].move, st);
- moves[count].score = -qsearch(pos, ss, -VALUE_INFINITE, VALUE_INFINITE, Depth(0), 1, 0);
- pos.undo_move(moves[count].move);
- moves[count].pv[0] = moves[count].move;
- moves[count].pv[1] = MOVE_NONE;
- count++;
- }
- sort();
- }
-
-
- // Simple accessor methods for the RootMoveList class
-
- inline Move RootMoveList::get_move(int moveNum) const {
- return moves[moveNum].move;
- }
-
- inline Value RootMoveList::get_move_score(int moveNum) const {
- return moves[moveNum].score;
- }
-
- inline void RootMoveList::set_move_score(int moveNum, Value score) {
- moves[moveNum].score = score;
- }
-
- inline void RootMoveList::set_move_nodes(int moveNum, int64_t nodes) {
- moves[moveNum].nodes = nodes;
- moves[moveNum].cumulativeNodes += nodes;
- }
-
- inline void RootMoveList::set_beta_counters(int moveNum, int64_t our, int64_t their) {
- moves[moveNum].ourBeta = our;
- moves[moveNum].theirBeta = their;
- }
-
- void RootMoveList::set_move_pv(int moveNum, const Move pv[]) {
- int j;
- for(j = 0; pv[j] != MOVE_NONE; j++)
- moves[moveNum].pv[j] = pv[j];
- moves[moveNum].pv[j] = MOVE_NONE;
- }
-
- inline Move RootMoveList::get_move_pv(int moveNum, int i) const {
- return moves[moveNum].pv[i];
- }
-
- inline int64_t RootMoveList::get_move_cumulative_nodes(int moveNum) const {
- return moves[moveNum].cumulativeNodes;
- }
-
- inline int RootMoveList::move_count() const {
- return count;
- }
-
-
- // RootMoveList::sort() sorts the root move list at the beginning of a new
- // iteration.
-
- inline void RootMoveList::sort() {
-
- sort_multipv(count - 1); // all items
- }
-
-
- // RootMoveList::sort_multipv() sorts the first few moves in the root move
- // list by their scores and depths. It is used to order the different PVs
- // correctly in MultiPV mode.
-
- void RootMoveList::sort_multipv(int n) {
-
- for (int i = 1; i <= n; i++)
- {
- RootMove rm = moves[i];
- int j;
- for (j = i; j > 0 && moves[j-1] < rm; j--)
- moves[j] = moves[j-1];
- moves[j] = rm;
- }
- }
-
-
- // init_node() is called at the beginning of all the search functions
- // (search(), search_pv(), qsearch(), and so on) and initializes the search
- // stack object corresponding to the current node. Once every
- // NodesBetweenPolls nodes, init_node() also calls poll(), which polls
- // for user input and checks whether it is time to stop the search.
-
- void init_node(SearchStack ss[], int ply, int threadID) {
-
- assert(ply >= 0 && ply < PLY_MAX);
- assert(threadID >= 0 && threadID < ActiveThreads);
-
- Threads[threadID].nodes++;
-
- if (threadID == 0)
- {
- NodesSincePoll++;
- if (NodesSincePoll >= NodesBetweenPolls)
- {
- poll();
- NodesSincePoll = 0;
- }
- }
- ss[ply].init(ply);
- ss[ply+2].initKillers();
-
- if (Threads[threadID].printCurrentLine)
- print_current_line(ss, ply, threadID);
- }
-
-
- // update_pv() is called whenever a search returns a value > alpha. It
- // updates the PV in the SearchStack object corresponding to the current
- // node.
-
- void update_pv(SearchStack ss[], int ply) {
- assert(ply >= 0 && ply < PLY_MAX);
-
- ss[ply].pv[ply] = ss[ply].currentMove;
- int p;
- for(p = ply + 1; ss[ply+1].pv[p] != MOVE_NONE; p++)
- ss[ply].pv[p] = ss[ply+1].pv[p];
- ss[ply].pv[p] = MOVE_NONE;
- }
-
-
- // sp_update_pv() is a variant of update_pv for use at split points. The
- // difference between the two functions is that sp_update_pv also updates
- // the PV at the parent node.
-
- void sp_update_pv(SearchStack* pss, SearchStack ss[], int ply) {
- assert(ply >= 0 && ply < PLY_MAX);
-
- ss[ply].pv[ply] = pss[ply].pv[ply] = ss[ply].currentMove;
- int p;
- for(p = ply + 1; ss[ply+1].pv[p] != MOVE_NONE; p++)
- ss[ply].pv[p] = pss[ply].pv[p] = ss[ply+1].pv[p];
- ss[ply].pv[p] = pss[ply].pv[p] = MOVE_NONE;
- }
-