- // Make and search the move.
- StateInfo st;
- pos.do_move(move, st, sp->dcCandidates);
-
- // Try to reduce non-pv search depth by one ply if move seems not problematic,
- // if the move fails high will be re-searched at full depth.
- if ( !dangerous
- && moveCount >= LMRPVMoves
- && !captureOrPromotion
- && !move_is_castle(move)
- && !move_is_killer(move, ss[sp->ply]))
- {
- ss[sp->ply].reduction = OnePly;
- value = -search(pos, ss, -sp->alpha, newDepth - OnePly, sp->ply+1, true, threadID);
- }
- else
- value = sp->alpha + 1; // Just to trigger next condition
-
- if (value > sp->alpha) // Go with full depth non-pv search
- {
- ss[sp->ply].reduction = Depth(0);
- value = -search(pos, ss, -sp->alpha, newDepth, sp->ply+1, true, threadID);
-
- if (value > sp->alpha && value < sp->beta)
- {
- // When the search fails high at ply 1 while searching the first
- // move at the root, set the flag failHighPly1. This is used for
- // time managment: We don't want to stop the search early in
- // such cases, because resolving the fail high at ply 1 could
- // result in a big drop in score at the root.
- if (sp->ply == 1 && RootMoveNumber == 1)
- Threads[threadID].failHighPly1 = true;
-
- value = -search_pv(pos, ss, -sp->beta, -sp->alpha, newDepth, sp->ply+1, threadID);
- Threads[threadID].failHighPly1 = false;
- }
- }
- pos.undo_move(move);
-
- assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);
-
- if (thread_should_stop(threadID))
- break;
-
- // New best move?
- lock_grab(&(sp->lock));
- if (value > sp->bestValue && !thread_should_stop(threadID))
- {
- sp->bestValue = value;
- if (value > sp->alpha)
- {
- sp->alpha = value;
- sp_update_pv(sp->parentSstack, ss, sp->ply);
- if (value == value_mate_in(sp->ply + 1))
- ss[sp->ply].mateKiller = move;
-
- if (value >= sp->beta)
- {
- for (int i = 0; i < ActiveThreads; i++)
- if (i != threadID && (i == sp->master || sp->slaves[i]))
- Threads[i].stop = true;
-
- sp->finished = true;
- }
- }
- // If we are at ply 1, and we are searching the first root move at
- // ply 0, set the 'Problem' variable if the score has dropped a lot
- // (from the computer's point of view) since the previous iteration.
- if ( sp->ply == 1
- && Iteration >= 2
- && -value <= IterationInfo[Iteration-1].value - ProblemMargin)
- Problem = true;
- }
- lock_release(&(sp->lock));
- }
-
- lock_grab(&(sp->lock));
-
- // If this is the master thread and we have been asked to stop because of
- // a beta cutoff higher up in the tree, stop all slave threads.
- if (sp->master == threadID && thread_should_stop(threadID))
- for (int i = 0; i < ActiveThreads; i++)
- if (sp->slaves[i])
- Threads[i].stop = true;
-
- sp->cpus--;
- sp->slaves[threadID] = 0;
-
- lock_release(&(sp->lock));
- }
-
- /// 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) {
-
- 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);