X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fsearch.cpp;h=44c29ec878209a882c27f5880878443ac32a0081;hb=dd5a3ae4a6c7cc4adcbb4b72378694b0889139d7;hp=15609966438313776e47204d947c46e585a68b67;hpb=5e112f16daeec7f03a322cbd292bdbabf3246a48;p=stockfish diff --git a/src/search.cpp b/src/search.cpp index 15609966..44c29ec8 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -284,7 +284,7 @@ namespace { bool connected_moves(const Position& pos, Move m1, Move m2); bool value_is_mate(Value value); bool move_is_killer(Move m, const SearchStack& ss); - Depth extension(const Position& pos, Move m, Depth depth, bool pvNode, bool capture, bool check, bool singleReply, bool mateThreat, bool* dangerous); + Depth extension(const Position& pos, Move m, bool pvNode, bool capture, bool check, bool singleReply, bool mateThreat, bool* dangerous); bool ok_to_do_nullmove(const Position& pos); bool ok_to_prune(const Position& pos, Move m, Move threat, Depth d); bool ok_to_use_TT(const TTEntry* tte, Depth depth, Value beta, int ply); @@ -334,7 +334,6 @@ int perft(Position& pos, Depth depth) { Move move; MovePicker mp = MovePicker(pos, MOVE_NONE, depth, H); - Bitboard dcCandidates = pos.discovered_check_candidates(pos.side_to_move()); int sum = 0; // If we are at the last ply we don't need to do and undo @@ -346,10 +345,11 @@ int perft(Position& pos, Depth depth) } // Loop through all legal moves + CheckInfo ci(pos); while ((move = mp.get_next_move()) != MOVE_NONE) { StateInfo st; - pos.do_move(move, st, dcCandidates); + pos.do_move(move, st, ci.dcCandidates, pos.move_is_check(move, ci)); sum += perft(pos, depth - OnePly); pos.undo_move(move); } @@ -862,7 +862,7 @@ namespace { Value oldAlpha = alpha; Value value; - Bitboard dcCandidates = pos.discovered_check_candidates(pos.side_to_move()); + CheckInfo ci(pos); // Loop through all the moves in the root move list for (int i = 0; i < rml.move_count() && !AbortSearch; i++) @@ -900,11 +900,11 @@ namespace { // Decide search depth for this move bool captureOrPromotion = pos.move_is_capture_or_promotion(move); bool dangerous; - ext = extension(pos, move, Depth(100), true, captureOrPromotion, pos.move_is_check(move), false, false, &dangerous); + ext = extension(pos, move, true, captureOrPromotion, pos.move_is_check(move), false, false, &dangerous); newDepth = (Iteration - 2) * OnePly + ext + InitialDepth; // Make the move, and search it - pos.do_move(move, st, dcCandidates); + pos.do_move(move, st, ci.dcCandidates); if (i < MultiPV) { @@ -1065,7 +1065,6 @@ namespace { Move movesSearched[256]; EvalInfo ei; StateInfo st; - Bitboard dcCandidates; const TTEntry* tte; Move ttMove, move; Depth ext, newDepth; @@ -1114,7 +1113,7 @@ namespace { // to search all moves isCheck = pos.is_check(); mateThreat = pos.has_mate_threat(opposite_color(pos.side_to_move())); - dcCandidates = pos.discovered_check_candidates(pos.side_to_move()); + CheckInfo ci(pos); MovePicker mp = MovePicker(pos, ttMove, depth, H, &ss[ply]); // Loop through all legal moves until no moves remain or a beta cutoff @@ -1126,17 +1125,17 @@ namespace { assert(move_is_ok(move)); singleReply = (isCheck && mp.number_of_evasions() == 1); - moveIsCheck = pos.move_is_check(move, dcCandidates); + moveIsCheck = pos.move_is_check(move, ci); captureOrPromotion = pos.move_is_capture_or_promotion(move); movesSearched[moveCount++] = ss[ply].currentMove = move; // Decide the new search depth - ext = extension(pos, move, depth, true, captureOrPromotion, moveIsCheck, singleReply, mateThreat, &dangerous); + ext = extension(pos, move, true, captureOrPromotion, moveIsCheck, singleReply, mateThreat, &dangerous); newDepth = depth - OnePly + ext; // Make and search the move - pos.do_move(move, st, dcCandidates); + pos.do_move(move, st, ci.dcCandidates, moveIsCheck); if (moveCount == 1) // The first move in list is the PV value = -search_pv(pos, ss, -beta, -alpha, newDepth, ply+1, threadID); @@ -1210,7 +1209,7 @@ namespace { && !AbortSearch && !thread_should_stop(threadID) && split(pos, ss, ply, &alpha, &beta, &bestValue, VALUE_NONE, VALUE_NONE, depth, - &moveCount, &mp, dcCandidates, threadID, true)) + &moveCount, &mp, ci.dcCandidates, threadID, true)) break; } @@ -1257,7 +1256,6 @@ namespace { Move movesSearched[256]; EvalInfo ei; StateInfo st; - Bitboard dcCandidates; const TTEntry* tte; Move ttMove, move; Depth ext, newDepth; @@ -1371,7 +1369,7 @@ namespace { // Initialize a MovePicker object for the current position, and prepare // to search all moves. MovePicker mp = MovePicker(pos, ttMove, depth, H, &ss[ply]); - dcCandidates = pos.discovered_check_candidates(pos.side_to_move()); + CheckInfo ci(pos); futilityValue = VALUE_NONE; useFutilityPruning = depth < SelectiveDepth && !isCheck; @@ -1388,13 +1386,13 @@ namespace { assert(move_is_ok(move)); singleReply = (isCheck && mp.number_of_evasions() == 1); - moveIsCheck = pos.move_is_check(move, dcCandidates); + moveIsCheck = pos.move_is_check(move, ci); captureOrPromotion = pos.move_is_capture_or_promotion(move); movesSearched[moveCount++] = ss[ply].currentMove = move; // Decide the new search depth - ext = extension(pos, move, depth, false, captureOrPromotion, moveIsCheck, singleReply, mateThreat, &dangerous); + ext = extension(pos, move, false, captureOrPromotion, moveIsCheck, singleReply, mateThreat, &dangerous); newDepth = depth - OnePly + ext; // Futility pruning @@ -1425,7 +1423,7 @@ namespace { } // Make and search the move - pos.do_move(move, st, dcCandidates); + pos.do_move(move, st, ci.dcCandidates, moveIsCheck); // Try to reduce non-pv search depth by one ply if move seems not problematic, // if the move fails high will be re-searched at full depth. @@ -1471,7 +1469,7 @@ namespace { && !AbortSearch && !thread_should_stop(threadID) && split(pos, ss, ply, &beta, &beta, &bestValue, futilityValue, approximateEval, depth, &moveCount, - &mp, dcCandidates, threadID, false)) + &mp, ci.dcCandidates, threadID, false)) break; } @@ -1520,10 +1518,9 @@ namespace { EvalInfo ei; StateInfo st; - Bitboard dcCandidates; Move ttMove, move; Value staticValue, bestValue, value, futilityValue; - bool isCheck, enoughMaterial; + bool isCheck, enoughMaterial, moveIsCheck; const TTEntry* tte = NULL; int moveCount = 0; bool pvNode = (beta - alpha != 1); @@ -1592,7 +1589,7 @@ namespace { // to search the moves. Because the depth is <= 0 here, only captures, // queen promotions and checks (only if depth == 0) will be generated. MovePicker mp = MovePicker(pos, ttMove, depth, H); - dcCandidates = pos.discovered_check_candidates(pos.side_to_move()); + CheckInfo ci(pos); enoughMaterial = pos.non_pawn_material(pos.side_to_move()) > RookValueMidgame; // Loop through the moves until no moves remain or a beta cutoff @@ -1605,12 +1602,14 @@ namespace { moveCount++; ss[ply].currentMove = move; + moveIsCheck = pos.move_is_check(move, ci); + // Futility pruning if ( enoughMaterial && !isCheck && !pvNode + && !moveIsCheck && !move_is_promotion(move) - && !pos.move_is_check(move, dcCandidates) && !pos.move_is_passed_pawn_push(move)) { futilityValue = staticValue @@ -1636,7 +1635,7 @@ namespace { continue; // Make and search the move - pos.do_move(move, st, dcCandidates); + pos.do_move(move, st, ci.dcCandidates, moveIsCheck); value = -qsearch(pos, ss, -beta, -alpha, depth-OnePly, ply+1, threadID); pos.undo_move(move); @@ -1698,6 +1697,7 @@ namespace { assert(ActiveThreads > 1); Position pos = Position(sp->pos); + CheckInfo ci(pos); SearchStack* ss = sp->sstack[threadID]; Value value; Move move; @@ -1711,7 +1711,7 @@ namespace { { assert(move_is_ok(move)); - bool moveIsCheck = pos.move_is_check(move, sp->dcCandidates); + bool moveIsCheck = pos.move_is_check(move, ci); bool captureOrPromotion = pos.move_is_capture_or_promotion(move); lock_grab(&(sp->lock)); @@ -1722,7 +1722,7 @@ namespace { // Decide the new search depth. bool dangerous; - Depth ext = extension(pos, move, sp->depth, false, captureOrPromotion, moveIsCheck, false, false, &dangerous); + Depth ext = extension(pos, move, false, captureOrPromotion, moveIsCheck, false, false, &dangerous); Depth newDepth = sp->depth - OnePly + ext; // Prune? @@ -1762,7 +1762,7 @@ namespace { // Make and search the move. StateInfo st; - pos.do_move(move, st, sp->dcCandidates); + pos.do_move(move, st, sp->dcCandidates, moveIsCheck); // Try to reduce non-pv search depth by one ply if move seems not problematic, // if the move fails high will be re-searched at full depth. @@ -1841,6 +1841,7 @@ namespace { assert(ActiveThreads > 1); Position pos = Position(sp->pos); + CheckInfo ci(pos); SearchStack* ss = sp->sstack[threadID]; Value value; Move move; @@ -1849,7 +1850,7 @@ namespace { && !thread_should_stop(threadID) && (move = sp->mp->get_next_move(sp->lock)) != MOVE_NONE) { - bool moveIsCheck = pos.move_is_check(move, sp->dcCandidates); + bool moveIsCheck = pos.move_is_check(move, ci); bool captureOrPromotion = pos.move_is_capture_or_promotion(move); assert(move_is_ok(move)); @@ -1862,12 +1863,12 @@ namespace { // Decide the new search depth. bool dangerous; - Depth ext = extension(pos, move, sp->depth, true, captureOrPromotion, moveIsCheck, false, false, &dangerous); + Depth ext = extension(pos, move, true, captureOrPromotion, moveIsCheck, false, false, &dangerous); Depth newDepth = sp->depth - OnePly + ext; // Make and search the move. StateInfo st; - pos.do_move(move, st, sp->dcCandidates); + pos.do_move(move, st, sp->dcCandidates, moveIsCheck); // Try to reduce non-pv search depth by one ply if move seems not problematic, // if the move fails high will be re-searched at full depth. @@ -2298,7 +2299,7 @@ namespace { // extended, as example because the corresponding UCI option is set to zero, // the move is marked as 'dangerous' so, at least, we avoid to prune it. - Depth extension(const Position& pos, Move m, Depth depth, bool pvNode, bool captureOrPromotion, + Depth extension(const Position& pos, Move m, bool pvNode, bool captureOrPromotion, bool check, bool singleReply, bool mateThreat, bool* dangerous) { assert(m != MOVE_NONE); @@ -2318,19 +2319,6 @@ namespace { result += MateThreatExtension[pvNode]; } - if ( pvNode - && captureOrPromotion - && pos.type_of_piece_on(move_to(m)) != PAWN - && pos.see_sign(m) >= 0) - { - result += OnePly/2; - *dangerous = true; - } - - // Do not extend at low depths - if (!pvNode && depth < 4*OnePly) - return Min(result, OnePly); // Further test with Min(result, OnePly / 2) - if (pos.type_of_piece_on(move_from(m)) == PAWN) { Color c = pos.side_to_move(); @@ -2357,6 +2345,15 @@ namespace { *dangerous = true; } + if ( pvNode + && captureOrPromotion + && pos.type_of_piece_on(move_to(m)) != PAWN + && pos.see_sign(m) >= 0) + { + result += OnePly/2; + *dangerous = true; + } + return Min(result, OnePly); }