Futility Pruning

Discussion of chess software programming and technical issues.

Moderator: Ras

theturk1234
Posts: 52
Joined: Tue Jul 12, 2016 5:28 am

Re: Futility Pruning

Post by theturk1234 »

Kevin:
You're basically saying to inversely relate material gain margin and current move capture value(The more valuable of a piece this move captures, decrease the futility margin)?

Folkert: What is isCatchMove?
flok

Re: Futility Pruning

Post by flok »

kbhearn wrote:Your formula for material gain is wrong. It doesn't add in the evaluation value of your victim in the case of a capture.
Yes but that is because it doesn't apply it if it is capture move. On the chess programming wiki I read that you should not fut.prun. if it is a capture move (which I called catchMove in my source).
flok

Re: Futility Pruning

Post by flok »

isCatchMove is a flag in the move-object which says that the move captures an opponent piece.
kbhearn
Posts: 411
Joined: Thu Dec 30, 2010 4:48 am

Re: Futility Pruning

Post by kbhearn »

It seems correct (albeit possibly overly restrictive) to my eyes then assuming all variables are from the parent node not the child that's about to be pruned - I'm not sure how it's costing you 100 elo (but i could understand if it's not gaining you anything or losing a little as you're only saving 1 recursive call and 1 static eval when it's correct - the child should be in qsearch and fail high anyways). I don't see how material gain from promotion should make a move more eligible for pruning than material gain from captures though.

SF's implementation of futility pruning is done in the child node (line 740 of search.cpp for the pruning, line 69 for the margin) and at remaining depths up to 6 which would increase the potential for effort saving substantially.
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Futility Pruning

Post by Sven »

flok wrote:

Code: Select all

if (!isCatchMove) {
        int materialGain = promoteTo != NONE ? materialGain = ChessPiece::evalVal[promoteTo] - ChessPiece::evalVal[PAWN] : 0;
        constexpr int margin = 200; // maximum non-mate eval minus max material gain

        if (depthLeft == 1 && staticEval + materialGain + margin <= alpha && !sd -> s -> isKingUnderAttack(co) && abs(alpha) < value_checkmate_min) {
                sd -> s -> undoMove();

                continue; // skip move
        }
}
That code is confusing me.

Code: Select all

int materialGain = promoteTo != NONE ? materialGain = ChessPiece::evalVal[promoteTo] - ChessPiece::evalVal[PAWN] : 0;
means what? Why an assignment to materialGain within an assignment to materialGain?

Code: Select all

 && abs(alpha) < value_checkmate_min
Why this condition? Why not like this, based on the CPW recommendation:

Code: Select all

 && !(abs(alpha) >= value_checkmate_min || abs(beta) >= value_checkmate_min)
?
Last edited by Sven on Wed Oct 12, 2016 11:55 pm, edited 1 time in total.
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Futility Pruning

Post by Sven »

Sven Schüle wrote:
flok wrote:

Code: Select all

if (!isCatchMove) {
        int materialGain = promoteTo != NONE ? materialGain = ChessPiece::evalVal[promoteTo] - ChessPiece::evalVal[PAWN] : 0;
        constexpr int margin = 200; // maximum non-mate eval minus max material gain

        if (depthLeft == 1 && staticEval + materialGain + margin <= alpha && !sd -> s -> isKingUnderAttack(co) && abs(alpha) < value_checkmate_min) {
                sd -> s -> undoMove();

                continue; // skip move
        }
}
That code is confusing me.

Code: Select all

int materialGain = promoteTo != NONE ? materialGain = ChessPiece::evalVal[promoteTo] - ChessPiece::evalVal[PAWN] : 0;
means what? Why an assignment to materialGain within an assignment to materialGain?
It might even work but nobody should write it like that ...
Sven Schüle wrote:

Code: Select all

 && abs(alpha) < value_checkmate_min
Why this condition? Why not like this, based on the CPW recommendation:

Code: Select all

 && !(abs(alpha) >= value_checkmate_min || abs(beta) >= value_checkmate_min)
?
I think that is already the explanation for your -100 Elo, since your condition skips almost all non-capture moves at depth == 1 which is wrong in general.

Note that I edited the previous post and added a missing "!" in my proposal.
theturk1234
Posts: 52
Joined: Tue Jul 12, 2016 5:28 am

Re: Futility Pruning

Post by theturk1234 »

What I'm trying now is trying delta pruning(in quiescence search) which is pretty much the same as futility pruning. I seem to be getting a small but noticeable improvement, but really no luck on futility pruning.
flok

Re: Futility Pruning

Post by flok »

Sven Schüle wrote:
flok wrote:

Code: Select all

if (!isCatchMove) {
        int materialGain = promoteTo != NONE ? materialGain = ChessPiece::evalVal[promoteTo] - ChessPiece::evalVal[PAWN] : 0;
        constexpr int margin = 200; // maximum non-mate eval minus max material gain

        if (depthLeft == 1 && staticEval + materialGain + margin <= alpha && !sd -> s -> isKingUnderAttack(co) && abs(alpha) < value_checkmate_min) {
                sd -> s -> undoMove();

                continue; // skip move
        }
}
That code is confusing me.

Code: Select all

int materialGain = promoteTo != NONE ? materialGain = ChessPiece::evalVal[promoteTo] - ChessPiece::evalVal[PAWN] : 0;
means what? Why an assignment to materialGain within an assignment to materialGain?

That's a mistake while editing the code before publishing it. Sorry for the confusion.
I often edit things a bit before publishing because of long variable names like newCause.causingMove.isCatchMove that may only confuse people.

Code: Select all

 && abs(alpha) < value_checkmate_min
Why this condition? Why not like this, based on the CPW recommendation:

Code: Select all

 && !(abs(alpha) >= value_checkmate_min || abs(beta) >= value_checkmate_min)
?
Regarding the omission of the beta-check: I misread the text :-(
I've added it now and started a test-run.