X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=ee7d906e61698010afd4b7e64336c44505493b2e;hp=2a6ba30b8367e93a6d84869d31b2c7fa5ca01a4f;hb=d8268024a9663727d1f183bf88639475eabca9d4;hpb=a3477af2a172066f760c52ddf7b674394dff364f diff --git a/src/search.cpp b/src/search.cpp index 2a6ba30b..ee7d906e 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -152,6 +152,12 @@ namespace { Depth RazorDepth = 4*OnePly; Value RazorMargin = Value(0x300); + // Last seconds noise filtering (LSN) + bool UseLSNFiltering = false; + bool looseOnTime = false; + int LSNTime = 4 * 1000; // In milliseconds + Value LSNValue = Value(0x200); + // Extensions. Array index 0 is used at non-PV nodes, index 1 at PV nodes. Depth CheckExtension[2] = {OnePly, OnePly}; Depth SingleReplyExtension[2] = {OnePly / 2, OnePly / 2}; @@ -220,7 +226,7 @@ namespace { /// Functions - void id_loop(const Position &pos, Move searchMoves[]); + Value id_loop(const Position &pos, Move searchMoves[]); Value root_search(Position &pos, SearchStack ss[], RootMoveList &rml); Value search_pv(Position &pos, SearchStack ss[], Value alpha, Value beta, Depth depth, int ply, int threadID); @@ -394,6 +400,10 @@ void think(const Position &pos, bool infinite, bool ponder, int side_to_move, RazorDepth = (get_option_value_int("Maximum Razoring Depth") + 1) * OnePly; RazorMargin = value_from_centipawns(get_option_value_int("Razoring Margin")); + UseLSNFiltering = get_option_value_bool("LSN filtering"); + LSNTime = get_option_value_int("LSN Time Margin (sec)") * 1000; + LSNValue = value_from_centipawns(get_option_value_int("LSN Value Margin")); + MinimumSplitDepth = get_option_value_int("Minimum Split Depth") * OnePly; MaxThreadsPerSplitPoint = get_option_value_int("Maximum Number of Threads per Split Point"); @@ -468,7 +478,21 @@ void think(const Position &pos, bool infinite, bool ponder, int side_to_move, // We're ready to start thinking. Call the iterative deepening loop // function: - id_loop(pos, searchMoves); + if (!looseOnTime) + { + Value v = id_loop(pos, searchMoves); + looseOnTime = ( UseLSNFiltering + && myTime < LSNTime + && myIncrement == 0 + && v < -LSNValue); + } + else + { + looseOnTime = false; // reset for next match + while (SearchStartTime + myTime + 1000 > get_system_time()) + ; // wait here + id_loop(pos, searchMoves); // to fail gracefully + } if(UseLogFile) LogFile.close(); @@ -570,7 +594,7 @@ namespace { // been consumed, the user stops the search, or the maximum search depth is // reached. - void id_loop(const Position &pos, Move searchMoves[]) { + Value id_loop(const Position &pos, Move searchMoves[]) { Position p(pos); SearchStack ss[PLY_MAX_PLUS_2]; @@ -694,6 +718,7 @@ namespace { LogFile << "Ponder move: " << move_to_san(p, ss[0].pv[1]) << '\n'; LogFile << std::endl; } + return rml.get_move_score(0); } @@ -1122,7 +1147,8 @@ namespace { } } // Null move search not allowed, try razoring - else if (depth < RazorDepth && approximateEval < beta - RazorMargin) + else if ( (approximateEval < beta - RazorMargin && depth < RazorDepth) + ||(approximateEval < beta - PawnValueMidgame && depth <= OnePly)) { Value v = qsearch(pos, ss, beta-1, beta, Depth(0), ply, threadID); if (v < beta) @@ -1147,7 +1173,6 @@ namespace { Value value, bestValue = -VALUE_INFINITE; Bitboard dcCandidates = mp.discovered_check_candidates(); Value futilityValue = VALUE_NONE; - MovePicker::MovegenPhase moveType; bool isCheck = pos.is_check(); bool useFutilityPruning = UseFutilityPruning && depth < SelectiveDepth @@ -1156,14 +1181,14 @@ namespace { // Loop through all legal moves until no moves remain or a beta cutoff // occurs. while ( bestValue < beta - && (move = mp.get_next_move(&moveType)) != MOVE_NONE + && (move = mp.get_next_move()) != MOVE_NONE && !thread_should_stop(threadID)) { assert(move_is_ok(move)); bool singleReply = (isCheck && mp.number_of_moves() == 1); bool moveIsCheck = pos.move_is_check(move, dcCandidates); - bool moveIsGoodCapture = (moveType == MovePicker::PH_GOOD_CAPTURES); + bool moveIsCapture = pos.move_is_capture(move); bool moveIsPassedPawnPush = pos.move_is_passed_pawn_push(move); movesSearched[moveCount++] = ss[ply].currentMove = move; @@ -1175,7 +1200,7 @@ namespace { // Futility pruning if ( useFutilityPruning && ext == Depth(0) - && !moveIsGoodCapture + && !moveIsCapture && !moveIsPassedPawnPush && !move_promotion(move)) { @@ -1207,7 +1232,7 @@ namespace { if ( depth >= 2*OnePly && ext == Depth(0) && moveCount >= LMRNonPVMoves - && !moveIsGoodCapture + && !moveIsCapture && !move_promotion(move) && !moveIsPassedPawnPush && !move_is_castle(move) @@ -2021,6 +2046,7 @@ namespace { assert(threat == MOVE_NONE || move_is_ok(threat)); assert(!move_promotion(m)); assert(!pos.move_is_check(m)); + assert(!pos.move_is_capture(m)); assert(!pos.move_is_passed_pawn_push(m)); assert(d >= OnePly); @@ -2172,6 +2198,12 @@ namespace { { lastInfoTime = t; lock_grab(&IOLock); + if (dbg_show_mean) + dbg_print_mean(); + + if (dbg_show_hit_rate) + dbg_print_hit_rate(); + std::cout << "info nodes " << nodes_searched() << " nps " << nps() << " time " << t << " hashfull " << TT.full() << std::endl; lock_release(&IOLock);