X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=dd5e921ef41bb605e543295bcd3d40ee64f14b9b;hp=bc66ebad15751eefb3b037ea9f446e455f11b4ef;hb=235df6a887967195822bc4167d199ea334256287;hpb=20a2ca366f81d61cc0043cc68f4109f6f70c2716 diff --git a/src/search.cpp b/src/search.cpp index bc66ebad..dd5e921e 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -106,6 +106,9 @@ namespace { const bool UseIIDAtPVNodes = true; const bool UseIIDAtNonPVNodes = false; + // Use null move driven internal iterative deepening? + bool UseNullDrivenIID = true; + // Internal iterative deepening margin. At Non-PV moves, when // UseIIDAtNonPVNodes is true, we do an internal iterative deepening search // when the static evaluation is at most IIDMargin below beta. @@ -188,7 +191,7 @@ namespace { // Time managment variables int SearchStartTime; int MaxNodes, MaxDepth; - int MaxSearchTime, AbsoluteMaxSearchTime, ExtraSearchTime, TimeAdvantage; + int MaxSearchTime, AbsoluteMaxSearchTime, ExtraSearchTime; Move BestRootMove, PonderMove, EasyMove; int RootMoveNumber; bool InfiniteSearch; @@ -390,6 +393,7 @@ void think(const Position &pos, bool infinite, bool ponder, int side_to_move, if (UseLogFile) LogFile.open(get_option_value_string("Search Log Filename").c_str(), std::ios::out | std::ios::app); + UseNullDrivenIID = get_option_value_bool("Null driven IID"); UseQSearchFutilityPruning = get_option_value_bool("Futility Pruning (Quiescence Search)"); UseFutilityPruning = get_option_value_bool("Futility Pruning (Main Search)"); @@ -427,8 +431,6 @@ void think(const Position &pos, bool infinite, bool ponder, int side_to_move, int myIncrement = increment[side_to_move]; int oppTime = time[1 - side_to_move]; - TimeAdvantage = myTime - oppTime; - if (!movesToGo) // Sudden death time control { if (myIncrement) @@ -680,10 +682,6 @@ namespace { ExtraSearchTime = BestMoveChangesByIteration[Iteration] * (MaxSearchTime / 2) + BestMoveChangesByIteration[Iteration-1] * (MaxSearchTime / 3); - // If we need some more and we are in time advantage take it - if (ExtraSearchTime > 0 && TimeAdvantage > 2 * MaxSearchTime) - ExtraSearchTime += MaxSearchTime / 2; - // Try to guess if the current iteration is the last one or the last two LastIterations = (current_search_time() > ((MaxSearchTime + ExtraSearchTime)*58) / 128); @@ -1130,12 +1128,13 @@ namespace { if (tte && ok_to_use_TT(tte, depth, beta, ply)) { - ss[ply].currentMove = ttMove; // can be MOVE_NONE ? + ss[ply].currentMove = ttMove; // can be MOVE_NONE return value_from_tt(tte->value(), ply); } Value approximateEval = quick_evaluate(pos); bool mateThreat = false; + bool nullDrivenIID = false; bool isCheck = pos.is_check(); // Null move search @@ -1149,7 +1148,21 @@ namespace { UndoInfo u; pos.do_null_move(u); int R = (depth > 7 ? 4 : 3); + Value nullValue = -search(pos, ss, -(beta-1), depth-R*OnePly, ply+1, false, threadID); + + // Check for a null capture artifact, if the value without the null capture + // is above beta then there is a good possibility that this is a cut-node. + // We will do an IID later to find a ttMove. + if ( UseNullDrivenIID + && nullValue < beta + && depth > 6 * OnePly + && ttMove == MOVE_NONE + && ss[ply + 1].currentMove != MOVE_NONE + && pos.move_is_capture(ss[ply + 1].currentMove) + && pos.see(ss[ply + 1].currentMove) * PawnValueMidgame + nullValue > beta - IIDMargin) + nullDrivenIID = true; + pos.undo_null_move(u); if (nullValue >= beta) @@ -1169,8 +1182,10 @@ namespace { // low score (which will cause the reduced move to fail high in the // parent node, which will trigger a re-search with full depth). if (nullValue == value_mated_in(ply + 2)) + { mateThreat = true; - + nullDrivenIID = false; + } ss[ply].threatMove = ss[ply + 1].currentMove; if ( depth < ThreatDepth && ss[ply - 1].reduction @@ -1194,6 +1209,19 @@ namespace { search(pos, ss, beta, Min(depth/2, depth-2*OnePly), ply, false, threadID); ttMove = ss[ply].pv[ply]; } + else if (nullDrivenIID) + { + // The null move failed low due to a suspicious capture. Perhaps we + // are facing a null capture artifact due to the side to move change + // and this is a cut-node. So it's a good time to search for a ttMove. + Move tm = ss[ply].threatMove; + + assert(tm != MOVE_NONE); + + search(pos, ss, beta, Min(depth/2, depth-3*OnePly), ply, false, threadID); + ttMove = ss[ply].pv[ply]; + ss[ply].threatMove = tm; + } // Initialize a MovePicker object for the current position, and prepare // to search all moves: