X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=31b6967c17ff008b97e6c939731a523232d92c17;hp=a4b2ef348566eb4b62d462e0e8c63b62c1343eae;hb=d7022031130ef84b801e087c1804d0cf05bc369b;hpb=76d4a80084f2ff61b0ea433ac829914370736b5e diff --git a/src/search.cpp b/src/search.cpp index a4b2ef34..31b6967c 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -547,6 +547,7 @@ namespace { // Step 1. Initialize node Thread* thisThread = pos.this_thread(); inCheck = pos.checkers(); + Color us = pos.side_to_move(); moveCount = captureCount = quietCount = ss->moveCount = 0; bestValue = -VALUE_INFINITE; maxValue = VALUE_INFINITE; @@ -577,6 +578,17 @@ namespace { beta = std::min(mate_in(ss->ply+1), beta); if (alpha >= beta) return alpha; + + // Check if there exists a move which draws by repetition, or an alternative + // earlier move to this position. + if ( pos.rule50_count() >= 3 + && alpha < VALUE_DRAW + && pos.has_game_cycle(ss->ply)) + { + alpha = VALUE_DRAW; + if (alpha >= beta) + return alpha; + } } assert(0 <= ss->ply && ss->ply < MAX_PLY); @@ -628,7 +640,7 @@ namespace { else if (!pos.capture_or_promotion(ttMove)) { int penalty = -stat_bonus(depth); - thisThread->mainHistory[pos.side_to_move()][from_to(ttMove)] << penalty; + thisThread->mainHistory[us][from_to(ttMove)] << penalty; update_continuation_histories(ss, pos.moved_piece(ttMove), to_sq(ttMove), penalty); } } @@ -737,9 +749,9 @@ namespace { && (ss-1)->statScore < 22500 && eval >= beta && ss->staticEval >= beta - 36 * depth / ONE_PLY + 225 - && !ss->excludedMove - && pos.non_pawn_material(pos.side_to_move()) - && (ss->ply >= thisThread->nmp_ply || ss->ply % 2 != thisThread->nmp_odd)) + && !excludedMove + && pos.non_pawn_material(us) + && (ss->ply > thisThread->nmp_min_ply || us != thisThread->nmp_color)) { assert(eval - beta >= 0); @@ -761,17 +773,17 @@ namespace { if (nullValue >= VALUE_MATE_IN_MAX_PLY) nullValue = beta; - if (abs(beta) < VALUE_KNOWN_WIN && (depth < 12 * ONE_PLY || thisThread->nmp_ply)) + if (abs(beta) < VALUE_KNOWN_WIN && (depth < 12 * ONE_PLY || thisThread->nmp_min_ply)) return nullValue; // Do verification search at high depths. Disable null move pruning // for side to move for the first part of the remaining search tree. - thisThread->nmp_ply = ss->ply + 3 * (depth-R) / 4; - thisThread->nmp_odd = ss->ply % 2; + thisThread->nmp_min_ply = ss->ply + 3 * (depth-R) / 4 - 1; + thisThread->nmp_color = us; Value v = search(pos, ss, beta-1, beta, depth-R, false); - thisThread->nmp_odd = thisThread->nmp_ply = 0; + thisThread->nmp_min_ply = 0; if (v >= beta) return nullValue; @@ -912,7 +924,7 @@ moves_loop: // When in check, search starts from here // Step 14. Pruning at shallow depth (~170 Elo) if ( !rootNode - && pos.non_pawn_material(pos.side_to_move()) + && pos.non_pawn_material(us) && bestValue > VALUE_MATED_IN_MAX_PLY) { if ( !captureOrPromotion @@ -1007,7 +1019,7 @@ moves_loop: // When in check, search starts from here && !pos.see_ge(make_move(to_sq(move), from_sq(move)))) r -= 2 * ONE_PLY; - ss->statScore = thisThread->mainHistory[~pos.side_to_move()][from_to(move)] + ss->statScore = thisThread->mainHistory[us][from_to(move)] + (*contHist[0])[movedPiece][to_sq(move)] + (*contHist[1])[movedPiece][to_sq(move)] + (*contHist[3])[movedPiece][to_sq(move)] @@ -1106,7 +1118,7 @@ moves_loop: // When in check, search starts from here else { assert(value >= beta); // Fail high - ss->statScore = std::max(ss->statScore, 0); + ss->statScore = 0; break; } } @@ -1153,7 +1165,7 @@ moves_loop: // When in check, search starts from here update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -stat_bonus(depth + ONE_PLY)); } // Bonus for prior countermove that caused the fail low - else if ( depth >= 3 * ONE_PLY + else if ( (depth >= 3 * ONE_PLY || PvNode) && !pos.captured_piece() && is_ok((ss-1)->currentMove)) update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, stat_bonus(depth));