Skip to content

Commit

Permalink
Reduce futility_margin if opponents last move was bad
Browse files Browse the repository at this point in the history
This reduces the futiltiy_margin if our opponents last move was bad by
around ~1/3 when not improving and ~1/2.7 when improving, the idea being
to retroactively futility prune moves that were played, but turned out
to be bad.  A bad move is being defined as their staticEval before their
move being lower as our staticEval now is. If the depth is 2 and we are
improving the opponent worsening flag is not set, in order to not risk
having a too low futility_margin, due to the fact that when these
conditions are met the futility_margin already drops quite low.
  • Loading branch information
PikaCat-OuO committed Mar 8, 2024
1 parent d91a00f commit 8a4b3f0
Showing 1 changed file with 10 additions and 5 deletions.
15 changes: 10 additions & 5 deletions src/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,12 @@ using namespace Search;
namespace {

// Futility margin
Value futility_margin(Depth d, bool noTtCutNode, bool improving) {
Value futilityMult = 138 - 28 * noTtCutNode;
return (futilityMult * d - 3 * futilityMult / 2 * improving);
Value futility_margin(Depth d, bool noTtCutNode, bool improving, bool oppWorsening) {
Value futilityMult = 138 - 28 * noTtCutNode;
Value improvingDeduction = 3 * improving * futilityMult / 2;
Value worseningDeduction = (331 + 45 * improving) * oppWorsening * futilityMult / 1024;

return futilityMult * d - improvingDeduction - worseningDeduction;
}

constexpr int futility_move_count(bool improving, Depth depth) {
Expand Down Expand Up @@ -472,7 +475,7 @@ Value Search::Worker::search(
Move ttMove, move, excludedMove, bestMove;
Depth extension, newDepth;
Value bestValue, value, ttValue, eval, maxValue, probCutBeta;
bool givesCheck, improving, priorCapture;
bool givesCheck, improving, priorCapture, opponentWorsening;
bool capture, moveCountPruning, ttCapture;
Piece movedPiece;
int moveCount, captureCount, quietCount;
Expand Down Expand Up @@ -644,6 +647,8 @@ Value Search::Worker::search(
? ss->staticEval > (ss - 2)->staticEval
: (ss - 4)->staticEval != VALUE_NONE && ss->staticEval > (ss - 4)->staticEval;

opponentWorsening = ss->staticEval + (ss - 1)->staticEval > 2 && (depth != 2 || !improving);

// Step 6. Razoring (~1 Elo)
// If eval is really low check with qsearch if it can exceed alpha, if it can't,
// return a fail low.
Expand All @@ -657,7 +662,7 @@ Value Search::Worker::search(
// Step 7. Futility pruning: child node (~40 Elo)
// The depth condition is important for mate finding.
if (!ss->ttPv && depth < 8
&& eval - futility_margin(depth, cutNode && !ss->ttHit, improving)
&& eval - futility_margin(depth, cutNode && !ss->ttHit, improving, opponentWorsening)
- (ss - 1)->statScore / 253
>= beta
&& eval >= beta && eval < 19543 // smaller than wins.
Expand Down

0 comments on commit 8a4b3f0

Please sign in to comment.