1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-04-29 16:23:09 +00:00

Reduce futility_margin if opponents last move was bad

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.

Passed STC:
https://tests.stockfishchess.org/tests/live_elo/65e3977bf2ef6c733362aae3
LLR: 2.94 (-2.94,2.94) <0.00,2.00>
Total: 122432 W: 31884 L: 31436 D: 59112
Ptnml(0-2): 467, 14404, 31035, 14834, 476

Passed LTC:
https://tests.stockfishchess.org/tests/live_elo/65e47f40f2ef6c733362b6d2
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 421692 W: 106572 L: 105452 D: 209668
Ptnml(0-2): 216, 47217, 114865, 48327, 221

closes https://github.com/official-stockfish/Stockfish/pull/5092

Bench: 1565939
This commit is contained in:
rn5f107s2 2024-02-15 23:01:02 +01:00 committed by Disservin
parent bd579ab5d1
commit 1db969e620

View file

@ -53,11 +53,13 @@ using namespace Search;
namespace {
// Futility margin
Value futility_margin(Depth d, bool noTtCutNode, bool improving) {
Value futility_margin(Depth d, bool noTtCutNode, bool improving, bool oppWorsening) {
Value futilityMult = 117 - 44 * noTtCutNode;
return (futilityMult * d - 3 * futilityMult / 2 * improving);
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) {
@ -533,7 +535,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, opponenWorsening;
bool capture, moveCountPruning, ttCapture;
Piece movedPiece;
int moveCount, captureCount, quietCount;
@ -742,6 +744,8 @@ Value Search::Worker::search(
? ss->staticEval > (ss - 2)->staticEval
: (ss - 4)->staticEval != VALUE_NONE && ss->staticEval > (ss - 4)->staticEval;
opponenWorsening = ss->staticEval + (ss - 1)->staticEval > 2 && (depth != 2 || !improving);
// Step 7. Razoring (~1 Elo)
// If eval is really low check with qsearch if it can exceed alpha, if it can't,
// return a fail low.
@ -756,7 +760,7 @@ Value Search::Worker::search(
// Step 8. Futility pruning: child node (~40 Elo)
// The depth condition is important for mate finding.
if (!ss->ttPv && depth < 11
&& eval - futility_margin(depth, cutNode && !ss->ttHit, improving)
&& eval - futility_margin(depth, cutNode && !ss->ttHit, improving, opponenWorsening)
- (ss - 1)->statScore / 314
>= beta
&& eval >= beta && eval < 30016 // smaller than TB wins