X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=e02529327435b46f49f4780d591877b201042cbf;hp=23066d8f5d7186aa5391dca08822787624c53e0d;hb=314faa905a60962595d610c26727c4b603c6ed62;hpb=0fdc75c0bdf1b273f080724d03fd706ebb8c17cb diff --git a/src/search.cpp b/src/search.cpp index 23066d8f..e0252932 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -310,7 +310,7 @@ namespace { Value *alpha, Value *beta, Value *bestValue, const Value futilityValue, const Value approximateValue, Depth depth, int *moves, - MovePicker *mp, Bitboard dcCandidates, int master, bool pvNode); + MovePicker *mp, int master, bool pvNode); void wake_sleeping_threads(); #if !defined(_MSC_VER) @@ -333,25 +333,25 @@ namespace { 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; + MovePicker mp = MovePicker(pos, MOVE_NONE, depth, H); // If we are at the last ply we don't need to do and undo // the moves, just to count them. if (depth <= OnePly) // Replace with '<' to test also qsearch { - while ((move = mp.get_next_move()) != MOVE_NONE) sum++; + while (mp.get_next_move()) sum++; return sum; } // Loop through all legal moves + CheckInfo ci(pos); while ((move = mp.get_next_move()) != MOVE_NONE) { - StateInfo st; - pos.do_move(move, st, dcCandidates); - sum += perft(pos, depth - OnePly); - pos.undo_move(move); + StateInfo st; + pos.do_move(move, st, ci, pos.move_is_check(move, ci)); + sum += perft(pos, depth - OnePly); + pos.undo_move(move); } return sum; } @@ -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++) @@ -898,13 +898,14 @@ namespace { << " currmovenumber " << i + 1 << std::endl; // Decide search depth for this move + bool moveIsCheck = pos.move_is_check(move); bool captureOrPromotion = pos.move_is_capture_or_promotion(move); bool dangerous; - ext = extension(pos, move, true, captureOrPromotion, pos.move_is_check(move), false, false, &dangerous); + ext = extension(pos, move, true, captureOrPromotion, moveIsCheck, 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, moveIsCheck); if (i < MultiPV) { @@ -1065,7 +1066,6 @@ namespace { Move movesSearched[256]; EvalInfo ei; StateInfo st; - Bitboard dcCandidates; const TTEntry* tte; Move ttMove, move; Depth ext, newDepth; @@ -1103,11 +1103,8 @@ namespace { tte = TT.retrieve(pos.get_key()); ttMove = (tte ? tte->move() : MOVE_NONE); - // Go with internal iterative deepening if we don't have a TT move or - // if search depth is more then 4*OnePly higher then TT move depth. - if ( UseIIDAtPVNodes - && depth >= 5*OnePly - &&(!ttMove || depth > tte->depth() + 4*OnePly)) + // Go with internal iterative deepening if we don't have a TT move + if (UseIIDAtPVNodes && ttMove == MOVE_NONE && depth >= 5*OnePly) { search_pv(pos, ss, alpha, beta, depth-2*OnePly, ply, threadID); ttMove = ss[ply].pv[ply]; @@ -1117,7 +1114,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 @@ -1129,7 +1126,7 @@ 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; @@ -1139,7 +1136,7 @@ namespace { newDepth = depth - OnePly + ext; // Make and search the move - pos.do_move(move, st, dcCandidates); + pos.do_move(move, st, ci, moveIsCheck); if (moveCount == 1) // The first move in list is the PV value = -search_pv(pos, ss, -beta, -alpha, newDepth, ply+1, threadID); @@ -1212,8 +1209,8 @@ namespace { && idle_thread_exists(threadID) && !AbortSearch && !thread_should_stop(threadID) - && split(pos, ss, ply, &alpha, &beta, &bestValue, VALUE_NONE, VALUE_NONE, depth, - &moveCount, &mp, dcCandidates, threadID, true)) + && split(pos, ss, ply, &alpha, &beta, &bestValue, VALUE_NONE, VALUE_NONE, + depth, &moveCount, &mp, threadID, true)) break; } @@ -1260,7 +1257,6 @@ namespace { Move movesSearched[256]; EvalInfo ei; StateInfo st; - Bitboard dcCandidates; const TTEntry* tte; Move ttMove, move; Depth ext, newDepth; @@ -1318,7 +1314,13 @@ namespace { ss[ply].currentMove = MOVE_NULL; pos.do_null_move(st); - int R = (depth >= 5 * OnePly ? 4 : 3); // Null move dynamic reduction + + // Null move dynamic reduction based on depth + int R = (depth >= 5 * OnePly ? 4 : 3); + + // Null move dynamic reduction based on value + if (approximateEval - beta > PawnValueMidgame) + R++; nullValue = -search(pos, ss, -(beta-1), depth-R*OnePly, ply+1, false, threadID); @@ -1374,7 +1376,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; @@ -1391,7 +1393,7 @@ 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; @@ -1403,7 +1405,8 @@ namespace { // Futility pruning if ( useFutilityPruning && !dangerous - && !captureOrPromotion) + && !captureOrPromotion + && move != ttMove) { // History pruning. See ok_to_prune() definition if ( moveCount >= 2 + int(depth) @@ -1428,7 +1431,7 @@ namespace { } // Make and search the move - pos.do_move(move, st, dcCandidates); + pos.do_move(move, st, ci, 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. @@ -1473,8 +1476,8 @@ namespace { && idle_thread_exists(threadID) && !AbortSearch && !thread_should_stop(threadID) - && split(pos, ss, ply, &beta, &beta, &bestValue, futilityValue, approximateEval, depth, &moveCount, - &mp, dcCandidates, threadID, false)) + && split(pos, ss, ply, &beta, &beta, &bestValue, futilityValue, approximateEval, + depth, &moveCount, &mp, threadID, false)) break; } @@ -1523,10 +1526,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); @@ -1595,7 +1597,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 @@ -1608,12 +1610,15 @@ namespace { moveCount++; ss[ply].currentMove = move; + moveIsCheck = pos.move_is_check(move, ci); + // Futility pruning if ( enoughMaterial && !isCheck && !pvNode + && !moveIsCheck + && move != ttMove && !move_is_promotion(move) - && !pos.move_is_check(move, dcCandidates) && !pos.move_is_passed_pawn_push(move)) { futilityValue = staticValue @@ -1639,7 +1644,7 @@ namespace { continue; // Make and search the move - pos.do_move(move, st, dcCandidates); + pos.do_move(move, st, ci, moveIsCheck); value = -qsearch(pos, ss, -beta, -alpha, depth-OnePly, ply+1, threadID); pos.undo_move(move); @@ -1701,6 +1706,7 @@ namespace { assert(ActiveThreads > 1); Position pos = Position(sp->pos); + CheckInfo ci(pos); SearchStack* ss = sp->sstack[threadID]; Value value; Move move; @@ -1714,7 +1720,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)); @@ -1765,7 +1771,7 @@ namespace { // Make and search the move. StateInfo st; - pos.do_move(move, st, sp->dcCandidates); + pos.do_move(move, st, ci, 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. @@ -1844,6 +1850,7 @@ namespace { assert(ActiveThreads > 1); Position pos = Position(sp->pos); + CheckInfo ci(pos); SearchStack* ss = sp->sstack[threadID]; Value value; Move move; @@ -1852,7 +1859,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)); @@ -1870,7 +1877,7 @@ namespace { // Make and search the move. StateInfo st; - pos.do_move(move, st, sp->dcCandidates); + pos.do_move(move, st, ci, 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. @@ -2814,7 +2821,7 @@ namespace { bool split(const Position& p, SearchStack* sstck, int ply, Value* alpha, Value* beta, Value* bestValue, const Value futilityValue, const Value approximateEval, Depth depth, int* moves, - MovePicker* mp, Bitboard dcCandidates, int master, bool pvNode) { + MovePicker* mp, int master, bool pvNode) { assert(p.is_ok()); assert(sstck != NULL); @@ -2851,7 +2858,6 @@ namespace { splitPoint->alpha = pvNode? *alpha : (*beta - 1); splitPoint->beta = *beta; splitPoint->pvNode = pvNode; - splitPoint->dcCandidates = dcCandidates; splitPoint->bestValue = *bestValue; splitPoint->futilityValue = futilityValue; splitPoint->approximateEval = approximateEval;