X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=d87d3899a006d6794799919ce1f5fd08464aa20d;hp=55bf52b29cd28e7db664c3c47b432d9a44fd86b3;hb=5dc0df843529faacd79e5f46a3a9b015982d2381;hpb=39c08c17c5812dc947d83a07cae702029319af2f diff --git a/src/search.cpp b/src/search.cpp index 55bf52b2..d87d3899 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -51,6 +51,11 @@ using std::endl; using Eval::evaluate; using namespace Search; +// For some reason argument-dependent lookup (ADL) doesn't work for Android's +// STLPort, so explicitly qualify following functions. +using std::count; +using std::find; + namespace { // Set to true to force running with one thread. Used for debugging @@ -67,7 +72,7 @@ namespace { const Depth RazorDepth = 4 * ONE_PLY; // Dynamic razoring margin based on depth - inline Value razor_margin(Depth d) { return Value(0x200 + 0x10 * int(d)); } + inline Value razor_margin(Depth d) { return Value(512 + 16 * int(d)); } // Maximum depth for use of dynamic threat detection when null move fails low const Depth ThreatDepth = 5 * ONE_PLY; @@ -77,13 +82,13 @@ namespace { // At Non-PV nodes we do an internal iterative deepening search // when the static evaluation is bigger then beta - IIDMargin. - const Value IIDMargin = Value(0x100); + const Value IIDMargin = Value(256); // Minimum depth for use of singular extension const Depth SingularExtensionDepth[] = { 8 * ONE_PLY, 6 * ONE_PLY }; // Futility margin for quiescence search - const Value FutilityMarginQS = Value(0x80); + const Value FutilityMarginQS = Value(128); // Futility lookup tables (initialized at startup) and their access functions Value FutilityMargins[16][64]; // [depth][moveNumber] @@ -166,19 +171,15 @@ namespace { // 'dangerous' moves so that we avoid to prune it. FORCE_INLINE bool is_dangerous(const Position& pos, Move m, bool captureOrPromotion) { - // Test for a pawn pushed to 7th or a passed pawn move - if (type_of(pos.piece_moved(m)) == PAWN) - { - Color c = pos.side_to_move(); - if ( relative_rank(c, to_sq(m)) == RANK_7 - || pos.pawn_is_passed(c, to_sq(m))) - return true; - } + // Test for a passed pawn move + if ( type_of(pos.piece_moved(m)) == PAWN + && pos.pawn_is_passed(pos.side_to_move(), to_sq(m))) + return true; // Test for a capture that triggers a pawn endgame if ( captureOrPromotion && type_of(pos.piece_on(to_sq(m))) != PAWN - && !is_special(m) + && type_of(m) == NORMAL && ( pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK) - PieceValueMidgame[pos.piece_on(to_sq(m))] == VALUE_ZERO)) return true; @@ -224,7 +225,7 @@ int64_t Search::perft(Position& pos, Depth depth) { StateInfo st; int64_t cnt = 0; - MoveList ml(pos); + MoveList ml(pos); // At the last ply just return the number of moves (leaf nodes) if (depth == ONE_PLY) @@ -656,7 +657,7 @@ namespace { && (ss-1)->eval != VALUE_NONE && ss->eval != VALUE_NONE && !pos.captured_piece_type() - && !is_special(move)) + && type_of(move) == NORMAL) { Square to = to_sq(move); H.update_gain(pos.piece_on(to), to, -(ss-1)->eval - ss->eval); @@ -703,16 +704,16 @@ namespace { ss->currentMove = MOVE_NULL; // Null move dynamic reduction based on depth - int R = 3 + (depth >= 5 * ONE_PLY ? depth / 8 : 0); + Depth R = 3 * ONE_PLY + depth / 4; // Null move dynamic reduction based on value if (refinedValue - PawnValueMidgame > beta) - R++; + R += ONE_PLY; pos.do_null_move(st); (ss+1)->skipNullMove = true; - nullValue = depth-R*ONE_PLY < ONE_PLY ? -qsearch(pos, ss+1, -beta, -alpha, DEPTH_ZERO) - : - search(pos, ss+1, -beta, -alpha, depth-R*ONE_PLY); + nullValue = depth-R < ONE_PLY ? -qsearch(pos, ss+1, -beta, -alpha, DEPTH_ZERO) + : - search(pos, ss+1, -beta, -alpha, depth-R); (ss+1)->skipNullMove = false; pos.do_null_move(st); @@ -727,7 +728,7 @@ namespace { // Do verification search at high depths ss->skipNullMove = true; - Value v = search(pos, ss, alpha, beta, depth-R*ONE_PLY); + Value v = search(pos, ss, alpha, beta, depth-R); ss->skipNullMove = false; if (v >= beta) @@ -873,19 +874,18 @@ split_point_start: // At split points actual search starts from here if ( singularExtensionNode && !ext && move == ttMove - && pos.pl_move_is_legal(move, ci.pinned)) + && pos.pl_move_is_legal(move, ci.pinned) + && abs(ttValue) < VALUE_KNOWN_WIN) { - if (abs(ttValue) < VALUE_KNOWN_WIN) - { - Value rBeta = ttValue - int(depth); - ss->excludedMove = move; - ss->skipNullMove = true; - value = search(pos, ss, rBeta - 1, rBeta, depth / 2); - ss->skipNullMove = false; - ss->excludedMove = MOVE_NONE; - if (value < rBeta) - ext = ONE_PLY; - } + Value rBeta = ttValue - int(depth); + ss->excludedMove = move; + ss->skipNullMove = true; + value = search(pos, ss, rBeta - 1, rBeta, depth / 2); + ss->skipNullMove = false; + ss->excludedMove = MOVE_NONE; + + if (value < rBeta) + ext = ONE_PLY; } // Update current move (this must be done after singular extension search) @@ -897,7 +897,7 @@ split_point_start: // At split points actual search starts from here && !inCheck && !dangerous && move != ttMove - && !is_castle(move) + && type_of(move) != CASTLE && (bestValue > VALUE_MATED_IN_MAX_PLY || bestValue == -VALUE_INFINITE)) { // Move count based pruning @@ -956,7 +956,7 @@ split_point_start: // At split points actual search starts from here && !isPvMove && !captureOrPromotion && !dangerous - && !is_castle(move) + && type_of(move) != CASTLE && ss->killers[0] != move && ss->killers[1] != move) { @@ -1221,12 +1221,12 @@ split_point_start: // At split points actual search starts from here && !givesCheck && move != ttMove && enoughMaterial - && !is_promotion(move) + && type_of(move) != PROMOTION && !pos.is_passed_pawn_push(move)) { futilityValue = futilityBase + PieceValueEndgame[pos.piece_on(to_sq(move))] - + (is_enpassant(move) ? PawnValueEndgame : VALUE_ZERO); + + (type_of(move) == ENPASSANT ? PawnValueEndgame : VALUE_ZERO); if (futilityValue < beta) { @@ -1254,7 +1254,7 @@ split_point_start: // At split points actual search starts from here if ( !PvNode && (!inCheck || evasionPrunable) && move != ttMove - && !is_promotion(move) + && type_of(move) != PROMOTION && pos.see_sign(move) < 0) continue; @@ -1349,7 +1349,7 @@ split_point_start: // At split points actual search starts from here while (b) { // Note that here we generate illegal "double move"! - if (futilityBase + PieceValueEndgame[pos.piece_on(pop_1st_bit(&b))] >= beta) + if (futilityBase + PieceValueEndgame[pos.piece_on(pop_lsb(&b))] >= beta) return true; }