Noob's TT question

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
maksimKorzh
Posts: 771
Joined: Sat Sep 08, 2018 5:37 pm
Location: Ukraine
Full name: Maksim Korzh

Noob's TT question

Post by maksimKorzh »

Hi guys

I'm researching this code by Bruce Moreland:

Code: Select all

int AlphaBeta(int depth, int alpha, int beta)
{
    int hashf = hashfALPHA;

    if ((val = ProbeHash(depth, alpha, beta)) != valUNKNOWN)
        return val;
    if (depth == 0) {
        val = Evaluate();
        RecordHash(depth, val, hashfEXACT);
        return val;
    }
    GenerateLegalMoves();
    while (MovesLeft()) {
        MakeNextMove();
        val = -AlphaBeta(depth - 1, -beta, -alpha);
        UnmakeMove();
        if (val >= beta) {

            RecordHash(depth, beta, hashfBETA);
            return beta;

        }
        if (val > alpha) {

            hashf = hashfEXACT;
            alpha = val;

        }
    }

    RecordHash(depth, alpha, hashf);
    return alpha;
}
What confuses me is WHY to store hash entry within:

Code: Select all

if (depth == 0) {
        val = Evaluate();
        RecordHash(depth, val, hashfEXACT);
        return val;
    }
Neither Gebril by Bruce Moreland nor VICE do that - they only store hash entry on fail high, fail low and exact if score > alpha and also take care of mating scores but NOT where search returns static eval(quiescence).

I tried this schema and if NOT storing hash entry the performance grows dramatically and PV line remains the same while if I store hash entry with exact value returned from quiescence search I'm getting my search at least twice slower and it's giving a completely different PV, not that bad but worth compared to "normal" PV.

Can someone please explain me WHY Bruce stores hash entry when static eval returned (no matter directly or from quiescence)?
User avatar
hgm
Posts: 27795
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Noob's TT question

Post by hgm »

This seems very wrong. At d=0 one should do QS, not evaluation. So unless Evaluate() here means a Quiescence Search, the search itself seems broken (i.e. without QS). And I don't see how it can mean QS, as alpha and beta are not passed. Unless the window is always completely opened in QS, in which case the returned score would indeed be exact.
User avatar
maksimKorzh
Posts: 771
Joined: Sat Sep 08, 2018 5:37 pm
Location: Ukraine
Full name: Maksim Korzh

Re: Noob's TT question

Post by maksimKorzh »

hgm wrote: Fri Sep 18, 2020 2:32 pm This seems very wrong. At d=0 one should do QS, not evaluation. So unless Evaluate() here means a Quiescence Search, the search itself seems broken (i.e. without QS). And I don't see how it can mean QS, as alpha and beta are not passed. Unless the window is always completely opened in QS, in which case the returned score would indeed be exact.
Mr. Muller

Let's assume that instead of Evaluate() there would be a call to quiescence search. I don't know what Bruce actually meant, here's a link to original post:
https://web.archive.org/web/20071031100 ... ashing.htm

so if we have:

Code: Select all

if (depth == 0)
{
    int score = quiescence(alpha, beta);
    // should we store hash entry here???
    // e.g. ResordHash(depth, score, HFEXACT);
    return score;
}
I just can't understand WHY is he doing that?
User avatar
hgm
Posts: 27795
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Noob's TT question

Post by hgm »

Normally the QS routine would store the hash entry itself. And the result would not be exact if it is outside the interval (alpha, beta). Of course what the static eval returns is exact. But it is not necessarily the score of the node; a capture could be better. Only if all captures fail low, but stand pat not, you would have an exact score. (Even when it is above beta.)

It seems to me the example at the link is just for a fixed-depth search without QS. If you leave out the blue lines, you are still left with a routine that unconditionally returns the evaluation at d=0, even if that is below alpha and it can grab a Queen. So the problem isn't really TT related.