X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=c7798c873d6286980983440f9ddfb3142f83c327;hp=fc94f4f79347dfc14dc6fe5e186c90ca3a1d0fac;hb=366f6b0dabd392f7d0e4079b355615c726241596;hpb=b88bc7b7667fc6ddbfc7412fb2c0bfc13e3bf11c diff --git a/src/search.cpp b/src/search.cpp index fc94f4f7..c7798c87 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -153,7 +153,7 @@ void Search::init() { /// Search::perft() is our utility to verify move generation. All the leaf nodes /// up to the given depth are generated and counted and the sum returned. -size_t Search::perft(Position& pos, Depth depth) { +static size_t perft(Position& pos, Depth depth) { StateInfo st; size_t cnt = 0; @@ -163,12 +163,15 @@ size_t Search::perft(Position& pos, Depth depth) { for (MoveList it(pos); *it; ++it) { pos.do_move(*it, st, ci, pos.move_gives_check(*it, ci)); - cnt += leaf ? MoveList(pos).size() : perft(pos, depth - ONE_PLY); + cnt += leaf ? MoveList(pos).size() : ::perft(pos, depth - ONE_PLY); pos.undo_move(*it); } return cnt; } +size_t Search::perft(Position& pos, Depth depth) { + return depth > ONE_PLY ? ::perft(pos, depth) : MoveList(pos).size(); +} /// Search::think() is the external interface to Stockfish's search, and is /// called by the main thread when the program receives the UCI 'go' command. It @@ -364,8 +367,6 @@ namespace { if (Signals.stop) return; - delta += delta / 2; - // In case of failing low/high increase aspiration window and // research, otherwise exit the loop. if (bestValue <= alpha) @@ -381,6 +382,8 @@ namespace { else break; + delta += delta / 2; + assert(alpha >= -VALUE_INFINITE && beta <= VALUE_INFINITE); // Give some update (without cluttering the UI) before to research @@ -512,7 +515,7 @@ namespace { assert(splitPoint->bestValue > -VALUE_INFINITE && splitPoint->moveCount > 0); - goto split_point_start; + goto moves_loop; } bestValue = -VALUE_INFINITE; @@ -581,7 +584,10 @@ namespace { // Step 5. Evaluate the position statically and update parent's gain statistics if (inCheck) + { ss->staticEval = ss->evalMargin = eval = VALUE_NONE; + goto moves_loop; + } else if (tte) { @@ -618,7 +624,6 @@ namespace { // Step 6. Razoring (is omitted in PV nodes) if ( !PvNode && depth < 4 * ONE_PLY - && !inCheck && eval + razor_margin(depth) < beta && ttMove == MOVE_NONE && abs(beta) < VALUE_MATE_IN_MAX_PLY @@ -638,7 +643,6 @@ namespace { if ( !PvNode && !ss->skipNullMove && depth < 4 * ONE_PLY - && !inCheck && eval - futility_margin(depth, (ss-1)->futilityMoveCount) >= beta && abs(beta) < VALUE_MATE_IN_MAX_PLY && abs(eval) < VALUE_KNOWN_WIN @@ -649,7 +653,6 @@ namespace { if ( !PvNode && !ss->skipNullMove && depth > ONE_PLY - && !inCheck && eval >= beta && abs(beta) < VALUE_MATE_IN_MAX_PLY && pos.non_pawn_material(pos.side_to_move())) @@ -711,7 +714,6 @@ namespace { // prune the previous move. if ( !PvNode && depth >= 5 * ONE_PLY - && !inCheck && !ss->skipNullMove && abs(beta) < VALUE_MATE_IN_MAX_PLY) { @@ -740,7 +742,7 @@ namespace { // Step 10. Internal iterative deepening if ( depth >= (PvNode ? 5 * ONE_PLY : 8 * ONE_PLY) && ttMove == MOVE_NONE - && (PvNode || (!inCheck && ss->staticEval + Value(256) >= beta))) + && (PvNode || ss->staticEval + Value(256) >= beta)) { Depth d = depth - 2 * ONE_PLY - (PvNode ? DEPTH_ZERO : depth / 4); @@ -752,7 +754,7 @@ namespace { ttMove = tte ? tte->move() : MOVE_NONE; } -split_point_start: // At split points actual search starts from here +moves_loop: // When in check and at SpNode search starts from here Square prevMoveSq = to_sq((ss-1)->currentMove); Move countermoves[] = { Countermoves[pos.piece_on(prevMoveSq)][prevMoveSq].first, @@ -811,12 +813,7 @@ split_point_start: // At split points actual search starts from here givesCheck = pos.move_gives_check(move, ci); dangerous = givesCheck || pos.is_passed_pawn_push(move) - || type_of(move) == CASTLE - || ( captureOrPromotion // Entering a pawn endgame? - && type_of(pos.piece_on(to_sq(move))) != PAWN - && type_of(move) == NORMAL - && ( pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK) - - PieceValue[MG][pos.piece_on(to_sq(move))] == VALUE_ZERO)); + || type_of(move) == CASTLE; // Step 12. Extend checks and, in PV nodes, also dangerous moves if (PvNode && dangerous)