X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=a2138d426a04606f9d8a88a7e5d9a1f3a71f4135;hp=37a962663fd241434642d09c89c760682483a8b1;hb=eb50793cffd8ac059450a76760e2c3f8ae9cc931;hpb=adeded29fb6ce483bbbafaa0f67aa086cad968f9 diff --git a/src/search.cpp b/src/search.cpp index 37a96266..a2138d42 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -52,9 +52,6 @@ using namespace Search; namespace { - // Set to true to force running with one thread. Used for debugging - const bool FakeSplit = false; - // Different node types, used as template parameter enum NodeType { Root, PV, NonPV }; @@ -76,9 +73,6 @@ namespace { return (Depth) Reductions[PvNode][i][std::min(int(d) / ONE_PLY, 63)][std::min(mn, 63)]; } - // Tempo bonus. Must be handled by search to preserve eval symmetry. - const int Tempo = 17; - size_t MultiPV, PVIdx; TimeManager TimeMgr; double BestMoveChanges; @@ -273,7 +267,6 @@ namespace { Value bestValue, alpha, beta, delta; std::memset(ss-2, 0, 5 * sizeof(Stack)); - (ss-1)->currentMove = MOVE_NULL; // Hack to skip update gains depth = 0; BestMoveChanges = 0; @@ -473,7 +466,7 @@ namespace { bestValue = -VALUE_INFINITE; ss->currentMove = ss->ttMove = (ss+1)->excludedMove = bestMove = MOVE_NONE; ss->ply = (ss-1)->ply + 1; - (ss+1)->skipNullMove = (ss+1)->nullChild = false; (ss+1)->reduction = DEPTH_ZERO; + (ss+1)->skipNullMove = false; (ss+1)->reduction = DEPTH_ZERO; (ss+2)->killers[0] = (ss+2)->killers[1] = MOVE_NONE; // Used to send selDepth info to GUI @@ -484,7 +477,7 @@ namespace { { // Step 2. Check for aborted search and immediate draw if (Signals.stop || pos.is_draw() || ss->ply > MAX_PLY) - return ss->ply > MAX_PLY && !inCheck ? evaluate(pos) + Tempo : DrawValue[pos.side_to_move()]; + return ss->ply > MAX_PLY && !inCheck ? evaluate(pos) : DrawValue[pos.side_to_move()]; // Step 3. Mate distance pruning. Even if we mate at the next move our score // would be at best mate_in(ss->ply+1), but if alpha is already bigger because @@ -539,7 +532,7 @@ namespace { { // Never assume anything on values stored in TT if ((ss->staticEval = eval = tte->eval_value()) == VALUE_NONE) - eval = ss->staticEval = evaluate(pos) + Tempo; + eval = ss->staticEval = evaluate(pos); // Can ttValue be used as a better position evaluation? if (ttValue != VALUE_NONE) @@ -548,7 +541,9 @@ namespace { } else { - eval = ss->staticEval = ss->nullChild ? -(ss-1)->staticEval + 2 * Tempo : evaluate(pos) + Tempo; + eval = ss->staticEval = + (ss-1)->currentMove != MOVE_NULL ? evaluate(pos) : -(ss-1)->staticEval + 2 * Eval::Tempo; + TT.store(posKey, VALUE_NONE, BOUND_NONE, DEPTH_NONE, MOVE_NONE, ss->staticEval); } @@ -556,6 +551,7 @@ namespace { && ss->staticEval != VALUE_NONE && (ss-1)->staticEval != VALUE_NONE && (move = (ss-1)->currentMove) != MOVE_NULL + && move != MOVE_NONE && type_of(move) == NORMAL) { Square to = to_sq(move); @@ -567,7 +563,6 @@ namespace { && depth < 4 * ONE_PLY && eval + razor_margin(depth) <= alpha && ttMove == MOVE_NONE - && abs(beta) < VALUE_MATE_IN_MAX_PLY && !pos.pawn_on_7th(pos.side_to_move())) { if ( depth <= ONE_PLY @@ -595,7 +590,6 @@ namespace { && !ss->skipNullMove && depth >= 2 * ONE_PLY && eval >= beta - && abs(beta) < VALUE_MATE_IN_MAX_PLY && pos.non_pawn_material(pos.side_to_move())) { ss->currentMove = MOVE_NULL; @@ -605,13 +599,14 @@ namespace { // Null move dynamic reduction based on depth and value Depth R = 3 * ONE_PLY + depth / 4 - + int(eval - beta) / PawnValueMg * ONE_PLY; + + (abs(beta) < VALUE_KNOWN_WIN ? int(eval - beta) / PawnValueMg * ONE_PLY + : DEPTH_ZERO); pos.do_null_move(st); - (ss+1)->skipNullMove = (ss+1)->nullChild = true; + (ss+1)->skipNullMove = true; nullValue = depth-R < ONE_PLY ? -qsearch(pos, ss+1, -beta, -beta+1, DEPTH_ZERO) : - search(pos, ss+1, -beta, -beta+1, depth-R, !cutNode); - (ss+1)->skipNullMove = (ss+1)->nullChild = false; + (ss+1)->skipNullMove = false; pos.undo_null_move(); if (nullValue >= beta) @@ -620,7 +615,7 @@ namespace { if (nullValue >= VALUE_MATE_IN_MAX_PLY) nullValue = beta; - if (depth < 12 * ONE_PLY) + if (depth < 12 * ONE_PLY && abs(beta) < VALUE_KNOWN_WIN) return nullValue; // Do verification search at high depths @@ -700,7 +695,10 @@ moves_loop: // When in check and at SpNode search starts from here singularExtensionNode = !RootNode && !SpNode && depth >= 8 * ONE_PLY + && abs(beta) < VALUE_KNOWN_WIN && ttMove != MOVE_NONE + /* && ttValue != VALUE_NONE Already implicit in the next condition */ + && abs(ttValue) < VALUE_KNOWN_WIN && !excludedMove // Recursive singular search is not allowed && (tte->bound() & BOUND_LOWER) && tte->depth() >= depth - 3 * ONE_PLY; @@ -765,11 +763,8 @@ moves_loop: // When in check and at SpNode search starts from here if ( singularExtensionNode && move == ttMove && !ext - && pos.legal(move, ci.pinned) - && abs(ttValue) < VALUE_KNOWN_WIN) + && pos.legal(move, ci.pinned)) { - assert(ttValue != VALUE_NONE); - Value rBeta = ttValue - int(depth); ss->excludedMove = move; ss->skipNullMove = true; @@ -989,8 +984,8 @@ moves_loop: // When in check and at SpNode search starts from here { assert(bestValue > -VALUE_INFINITE && bestValue < beta); - thisThread->split(pos, ss, alpha, beta, &bestValue, &bestMove, - depth, moveCount, &mp, NT, cutNode); + thisThread->split(pos, ss, alpha, beta, &bestValue, &bestMove, + depth, moveCount, &mp, NT, cutNode); if (Signals.stop || thisThread->cutoff_occurred()) return VALUE_ZERO; @@ -1066,7 +1061,7 @@ moves_loop: // When in check and at SpNode search starts from here // Check for an instant draw or if the maximum ply has been reached if (pos.is_draw() || ss->ply > MAX_PLY) - return ss->ply > MAX_PLY && !InCheck ? evaluate(pos) + Tempo : DrawValue[pos.side_to_move()]; + return ss->ply > MAX_PLY && !InCheck ? evaluate(pos) : DrawValue[pos.side_to_move()]; // Decide whether or not to include checks: this fixes also the type of // TT entry depth that we are going to use. Note that in qsearch we use @@ -1103,7 +1098,7 @@ moves_loop: // When in check and at SpNode search starts from here { // Never assume anything on values stored in TT if ((ss->staticEval = bestValue = tte->eval_value()) == VALUE_NONE) - ss->staticEval = bestValue = evaluate(pos) + Tempo; + ss->staticEval = bestValue = evaluate(pos); // Can ttValue be used as a better position evaluation? if (ttValue != VALUE_NONE) @@ -1111,7 +1106,8 @@ moves_loop: // When in check and at SpNode search starts from here bestValue = ttValue; } else - ss->staticEval = bestValue = ss->nullChild ? -(ss-1)->staticEval + 2 * Tempo : evaluate(pos) + Tempo; + ss->staticEval = bestValue = + (ss-1)->currentMove != MOVE_NULL ? evaluate(pos) : -(ss-1)->staticEval + 2 * Eval::Tempo; // Stand pat. Return immediately if static value is at least beta if (bestValue >= beta)