Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: Nullmove problem

Author: Michel Langeveld

Date: 21:03:32 11/21/01

Go up one level in this thread


On November 21, 2001 at 18:32:33, Dann Corbit wrote:

>On November 21, 2001 at 18:23:08, Michel Langeveld wrote:
>
>>I build nullmove in my chessprogram and received a problem.
>>
>>The example which is on Bruce side seems not to work in certain positions.
>>Especially positions where it's possible to give mate:
>>
>>[D] rnbq1bnr/pp2k3/2p1p1B1/3pP1p1/7p/4PQ2/PPPN1PPP/R3K1NR b KQ
>>
>>After Qc7 white doesn't see Qf7 anymore.
>>
>>It seems to be that the line:
>>
>>val = -AlphaBeta(depth - 1 - R, -beta, -beta + 1);
>>
>>Must be changed into:
>>
>>val = -AlphaBeta(depth - 1 - R, -beta+1, -beta);
>>
>>
>>--------- BELOW HERE THE EXAMPLE OF BRUCE ---------------
>>
>>#define R   2
>>
>>
>>
>>int AlphaBeta(int depth, int alpha, int beta)
>>{
>>    if (depth == 0)
>>        return Evaluate();
>>    MakeNullMove();
>>    val = -AlphaBeta(depth - 1 - R, -beta, -beta + 1);
>>    UnmakeNullMove();
>>    if (val >= beta)
>>        return beta;
>>    GenerateLegalMoves();
>>    while (MovesLeft()) {
>>        MakeNextMove();
>>        val = -AlphaBeta(depth - 1, -beta, -alpha);
>>        UnmakeMove();
>>        if (val >= beta) // Delete these to get straight
>>            return beta; // min-max instead of alpha-beta.
>>        if (val > alpha)
>>            alpha = val;
>>    }
>>    return alpha;
>
>Null-move can cause you to miss tactics, up to <reduction> plies.  That is to be
>expected.  The hope is that there is an overall gain in play.  You cannot judge
>from a single position.
>
>Bruce's code looks right to me.  Here is what Beowulf does:
>
>    /* -----------====     TRY A NULL MOVE     ====------------- */
>
>    /* Perform a NULL move if; (1) We're not on the first 2 plies (2) We're
>     * not in the process of performing a NULL move right now (Note - DoNull
>     * stores whether or not we are OK to NULL move, not whether we are doing
>     * one, hence testing for TRUE not FALSE) (3) We're not in check (4)
>     * There are enough pieces left to avoid high risk of zugzwang (5) We're
>     * on skill level 6 or higher */
>    if (USE_NULL && ply > 1 && DoNull && !inchk && (nullreduction = NullOK(B,
>depth)) && Skill > 4) {
>        /* Increase the NULL reduction by one ply to account for the fact
>         * that we've passed on this move. */
>        nullreduction += ONEPLY;
>        /* Set up temporary flags to store the board position */
>        ep_carry = B->ep;
>        B->ep = -1;
>
>        /* Do the null move reduced-depth search */
>        B->side = Opponent(B->side);
>        if (depth - nullreduction < ONEPLY)
>            score = -Quiesce(B, -tbeta, -tbeta + 1, ply + 1, 0);
>        else
>            score = -Search(B, -tbeta, -tbeta + 1, depth - nullreduction, ply +
>1, 0, 0, FALSE, -1);
>
>        /* Put things back */
>        B->side = Opponent(B->side);
>
>        /* Verification Search.  Here we re-search this node at a shallower
>         * depth if the score is >= beta.  The reason we do this is simple:
>         * we want to make sure that this really is a strong node, and
>         * therefore worth chopping. This time, instead of actually making a
>         * NULL move, we play a proper move. Note that we don't bother doing
>         * this when close to the frontier nodes (this would take us into the
>         * qsearch).  We only fail high if this second search ALSO fails
>         * high. */
>        if (USE_VERIFICATION && score >= tbeta && depth - nullreduction >=
>ONEPLY)
>            score = Search(B, tbeta - 1, tbeta, depth - nullreduction, ply + 1,
>0, fifty, FALSE, LastMove);
>
>        /* Replace the En-Passant flag */
>        B->ep = ep_carry;
>
>        /* If this move returned CM then we must be careful because there is
>         * a CM threat dangerously close! Only do this on highest skill
>         * level. */
>        if (IsCM(score) == -1 && Skill == 10)
>            threat = TRUE;
>
>        /* A fail high means that the positional score here is so high that
>         * even if the opponent is given a 'free move' then he still can't
>         * improve his position enough to increase the value of alpha.  If
>         * this is the case then clearly the current position is very strong.
>         * In fact it is so strong that the opponent would never let it occur
>         * in the first place, so we should cause a cut off.  */
>        if (score >= tbeta) {
>            HashUpdate(B, score, BestMoveRet, depth + ONEPLY - nullreduction,
>HASH_LOWER, FALSE, ply);
>            return score;
>        }
>    }

You are right. I see in this code that the nullmove isn't done on the last ply
before the QSearch:

if (depth - nullreduction < ONEPLY)

In my program after nullmove my program can come immediatly in the QSearch. Is
this a problem?



This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.