X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=df4c854030d9ba82b74dece6f469b4ba7057793b;hp=079fbf2bc504ffb8b6e480acb9933941fc1798a8;hb=c1558dde12620fdf1995c08d3a09cb4c18b4539a;hpb=6096ca7a95f2f3bc1049b4fe240b21b7fbc389f9 diff --git a/src/search.cpp b/src/search.cpp index 079fbf2b..df4c8540 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -188,12 +188,6 @@ namespace { // Dynamic razoring margin based on depth inline Value razor_margin(Depth d) { return Value(0x200 + 0x10 * int(d)); } - // Step 8. Null move search with verification search - - // Null move margin. A null move search will not be done if the static - // evaluation of the position is more than NullMoveMargin below beta. - const Value NullMoveMargin = Value(0x200); - // Maximum depth for use of dynamic threat detection when null move fails low const Depth ThreatDepth = 5 * ONE_PLY; @@ -226,10 +220,10 @@ namespace { const Value FutilityMarginQS = Value(0x80); // Futility lookup tables (initialized at startup) and their getter functions - int32_t FutilityMarginsMatrix[16][64]; // [depth][moveNumber] + Value FutilityMarginsMatrix[16][64]; // [depth][moveNumber] int FutilityMoveCountArray[32]; // [depth] - inline Value futility_margin(Depth d, int mn) { return Value(d < 7 * ONE_PLY ? FutilityMarginsMatrix[Max(d, 1)][Min(mn, 63)] : 2 * VALUE_INFINITE); } + inline Value futility_margin(Depth d, int mn) { return d < 7 * ONE_PLY ? FutilityMarginsMatrix[Max(d, 1)][Min(mn, 63)] : 2 * VALUE_INFINITE; } inline int futility_move_count(Depth d) { return d < 16 * ONE_PLY ? FutilityMoveCountArray[d] : 512; } // Step 14. Reduced search @@ -368,7 +362,7 @@ void init_search() { // Init futility margins array for (d = 1; d < 16; d++) for (mc = 0; mc < 64; mc++) - FutilityMarginsMatrix[d][mc] = 112 * int(log(double(d * d) / 2) / log(2.0) + 1.001) - 8 * mc + 45; + FutilityMarginsMatrix[d][mc] = Value(112 * int(log(double(d * d) / 2) / log(2.0) + 1.001) - 8 * mc + 45); // Init futility move count array for (d = 0; d < 32; d++) @@ -716,13 +710,12 @@ namespace { Value root_search(Position& pos, SearchStack* ss, Move* pv, RootMoveList& rml, Value* alphaPtr, Value* betaPtr) { - Value margins[2]; StateInfo st; CheckInfo ci(pos); int64_t nodes; Move move; Depth depth, ext, newDepth; - Value value, alpha, beta; + Value value, evalMargin, alpha, beta; bool isCheck, moveIsCheck, captureOrPromotion, dangerous; int researchCountFH, researchCountFL; @@ -741,7 +734,7 @@ namespace { // Step 5. Evaluate the position statically // At root we do this only to get reference value for child nodes - ss->eval = isCheck ? VALUE_NONE : evaluate(pos, margins); + ss->eval = isCheck ? VALUE_NONE : evaluate(pos, evalMargin); // Step 6. Razoring (omitted at root) // Step 7. Static null move pruning (omitted at root) @@ -977,13 +970,12 @@ namespace { assert(pos.thread() >= 0 && pos.thread() < ThreadsMgr.active_threads()); Move movesSearched[MOVES_MAX]; - Value margins[2]; StateInfo st; const TTEntry *tte; Key posKey; Move ttMove, move, excludedMove, threatMove; Depth ext, newDepth; - Value bestValue, value, oldAlpha; + Value bestValue, value, evalMargin, oldAlpha; Value refinedValue, nullValue, futilityBase, futilityValueScaled; // Non-PV specific bool isCheck, singleEvasion, singularExtensionNode, moveIsCheck, captureOrPromotion, dangerous; bool mateThreat = false; @@ -1047,19 +1039,19 @@ namespace { // update gain statistics of parent move. isCheck = pos.is_check(); if (isCheck) - ss->eval = VALUE_NONE; + ss->eval = evalMargin = VALUE_NONE; else if (tte) { assert(tte->static_value() != VALUE_NONE); ss->eval = tte->static_value(); - margins[pos.side_to_move()] = tte->static_value_margin(); + evalMargin = tte->static_value_margin(); refinedValue = refine_eval(tte, ss->eval, ply); } else { - refinedValue = ss->eval = evaluate(pos, margins); - TT.store(posKey, VALUE_NONE, VALUE_TYPE_NONE, DEPTH_NONE, MOVE_NONE, ss->eval, margins[pos.side_to_move()]); + refinedValue = ss->eval = evaluate(pos, evalMargin); + TT.store(posKey, VALUE_NONE, VALUE_TYPE_NONE, DEPTH_NONE, MOVE_NONE, ss->eval, evalMargin); } // Save gain for the parent non-capture move @@ -1096,14 +1088,11 @@ namespace { return refinedValue - futility_margin(depth, 0); // Step 8. Null move search with verification search (is omitted in PV nodes) - // When we jump directly to qsearch() we do a null move only if static value is - // at least beta. Otherwise we do a null move if static value is not more than - // NullMoveMargin under beta. if ( !PvNode && !ss->skipNullMove && depth > ONE_PLY && !isCheck - && refinedValue >= beta - (depth >= 4 * ONE_PLY ? NullMoveMargin : 0) + && refinedValue >= beta && !value_is_mate(beta) && pos.non_pawn_material(pos.side_to_move())) { @@ -1184,7 +1173,7 @@ namespace { CheckInfo ci(pos); ss->bestMove = MOVE_NONE; singleEvasion = isCheck && mp.number_of_evasions() == 1; - futilityBase = ss->eval + margins[pos.side_to_move()]; + futilityBase = ss->eval + evalMargin; singularExtensionNode = depth >= SingularExtensionDepth[PvNode] && tte && tte->move() @@ -1374,7 +1363,7 @@ namespace { ValueType vt = (bestValue <= oldAlpha ? VALUE_TYPE_UPPER : bestValue >= beta ? VALUE_TYPE_LOWER : VALUE_TYPE_EXACT); move = (bestValue <= oldAlpha ? MOVE_NONE : ss->bestMove); - TT.store(posKey, value_to_tt(bestValue, ply), vt, depth, move, ss->eval, margins[pos.side_to_move()]); + TT.store(posKey, value_to_tt(bestValue, ply), vt, depth, move, ss->eval, evalMargin); // Update killers and history only for non capture moves that fails high if ( bestValue >= beta @@ -1404,10 +1393,9 @@ namespace { assert(ply > 0 && ply < PLY_MAX); assert(pos.thread() >= 0 && pos.thread() < ThreadsMgr.active_threads()); - Value margins[2]; StateInfo st; Move ttMove, move; - Value bestValue, value, futilityValue, futilityBase; + Value bestValue, value, evalMargin, futilityValue, futilityBase; bool isCheck, deepChecks, enoughMaterial, moveIsCheck, evasionPrunable; const TTEntry* tte; Value oldAlpha = alpha; @@ -1436,7 +1424,7 @@ namespace { if (isCheck) { bestValue = futilityBase = -VALUE_INFINITE; - ss->eval = VALUE_NONE; + ss->eval = evalMargin = VALUE_NONE; deepChecks = enoughMaterial = false; } else @@ -1445,11 +1433,11 @@ namespace { { assert(tte->static_value() != VALUE_NONE); - margins[pos.side_to_move()] = tte->static_value_margin(); + evalMargin = tte->static_value_margin(); bestValue = tte->static_value(); } else - bestValue = evaluate(pos, margins); + bestValue = evaluate(pos, evalMargin); ss->eval = bestValue; update_gains(pos, (ss-1)->currentMove, (ss-1)->eval, ss->eval); @@ -1458,7 +1446,7 @@ namespace { if (bestValue >= beta) { if (!tte) - TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, DEPTH_NONE, MOVE_NONE, ss->eval, margins[pos.side_to_move()]); + TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, DEPTH_NONE, MOVE_NONE, ss->eval, evalMargin); return bestValue; } @@ -1470,7 +1458,7 @@ namespace { deepChecks = (depth == -ONE_PLY && bestValue >= beta - PawnValueMidgame / 8); // Futility pruning parameters, not needed when in check - futilityBase = bestValue + FutilityMarginQS + margins[pos.side_to_move()]; + futilityBase = bestValue + FutilityMarginQS + evalMargin; enoughMaterial = pos.non_pawn_material(pos.side_to_move()) > RookValueMidgame; } @@ -1514,7 +1502,6 @@ namespace { evasionPrunable = isCheck && bestValue > value_mated_in(PLY_MAX) && !pos.move_is_capture(move) - && pos.type_of_piece_on(move_from(move)) != KING && !pos.can_castle(pos.side_to_move()); // Don't search moves with negative SEE values @@ -1555,12 +1542,7 @@ namespace { // Update transposition table Depth d = (depth == DEPTH_ZERO ? DEPTH_ZERO : DEPTH_ZERO - ONE_PLY); ValueType vt = (bestValue <= oldAlpha ? VALUE_TYPE_UPPER : bestValue >= beta ? VALUE_TYPE_LOWER : VALUE_TYPE_EXACT); - TT.store(pos.get_key(), value_to_tt(bestValue, ply), vt, d, ss->bestMove, ss->eval, margins[pos.side_to_move()]); - - // Update killers only for checking moves that fails high - if ( bestValue >= beta - && !pos.move_is_capture_or_promotion(ss->bestMove)) - update_killers(ss->bestMove, ss); + TT.store(pos.get_key(), value_to_tt(bestValue, ply), vt, d, ss->bestMove, ss->eval, evalMargin); assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE); @@ -2245,16 +2227,15 @@ namespace { StateInfo st; TTEntry* tte; Position p(pos, pos.thread()); - Value margins[2]; - Value v; + Value v, m = VALUE_NONE; for (int i = 0; pv[i] != MOVE_NONE; i++) { tte = TT.retrieve(p.get_key()); if (!tte || tte->move() != pv[i]) { - v = (p.is_check() ? VALUE_NONE : evaluate(p, margins)); - TT.store(p.get_key(), VALUE_NONE, VALUE_TYPE_NONE, DEPTH_NONE, pv[i], v, margins[pos.side_to_move()]); + v = (p.is_check() ? VALUE_NONE : evaluate(p, m)); + TT.store(p.get_key(), VALUE_NONE, VALUE_TYPE_NONE, DEPTH_NONE, pv[i], v, m); } p.do_move(pv[i], st); }