- // All legal moves have been searched. A special case: If there were
- // no legal moves, it must be mate or stalemate.
- if (moveCount == 0)
- return (isCheck ? value_mated_in(ply) : VALUE_DRAW);
-
- // If the search is not aborted, update the transposition table,
- // history counters, and killer moves.
- if (AbortSearch || thread_should_stop(threadID))
- return bestValue;
-
- if (bestValue <= oldAlpha)
- TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_UPPER, depth, MOVE_NONE);
-
- else if (bestValue >= beta)
- {
- BetaCounter.add(pos.side_to_move(), depth, threadID);
- move = ss[ply].pv[ply];
- if (!pos.move_is_capture_or_promotion(move))
- {
- update_history(pos, move, depth, movesSearched, moveCount);
- update_killers(move, ss[ply]);
- }
- TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, depth, move);
- }
- else
- TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_EXACT, depth, ss[ply].pv[ply]);
-
- return bestValue;
- }
-
-
- // search() is the search function for zero-width nodes.
-
- Value search(Position& pos, SearchStack ss[], Value beta, Depth depth,
- int ply, bool allowNullmove, int threadID) {
-
- assert(beta >= -VALUE_INFINITE && beta <= VALUE_INFINITE);
- assert(ply >= 0 && ply < PLY_MAX);
- assert(threadID >= 0 && threadID < ActiveThreads);
-
- Move movesSearched[256];
- EvalInfo ei;
- StateInfo st;
- const TTEntry* tte;
- Move ttMove, move;
- Depth ext, newDepth;
- Value approximateEval, nullValue, value, futilityValue;
- bool isCheck, useFutilityPruning, singleReply, moveIsCheck, captureOrPromotion, dangerous;
- bool mateThreat = false;
- int moveCount = 0;
- Value bestValue = -VALUE_INFINITE;
-
- if (depth < OnePly)
- return qsearch(pos, ss, beta-1, beta, Depth(0), ply, threadID);
-
- // Initialize, and make an early exit in case of an aborted search,
- // an instant draw, maximum ply reached, etc.
- init_node(ss, ply, threadID);
-
- // After init_node() that calls poll()
- if (AbortSearch || thread_should_stop(threadID))
- return Value(0);
-
- if (pos.is_draw())
- return VALUE_DRAW;
-
- if (ply >= PLY_MAX - 1)
- return pos.is_check() ? quick_evaluate(pos) : evaluate(pos, ei, threadID);
-
- // Mate distance pruning
- if (value_mated_in(ply) >= beta)
- return beta;
-
- if (value_mate_in(ply + 1) < beta)
- return beta - 1;
-
- // Transposition table lookup
- tte = TT.retrieve(pos.get_key());
- ttMove = (tte ? tte->move() : MOVE_NONE);
-
- if (tte && ok_to_use_TT(tte, depth, beta, ply))