Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: Programming guru favour needed please

Author: Dann Corbit

Date: 17:53:50 06/05/03

Go up one level in this thread


On June 05, 2003 at 20:11:27, Geoff wrote:

>Hi Dan
>
>>>			/* NULL_R = 2 */
>>>                       nullScore = -search(-beta, -beta+1, depth-NULL_R-1, FALSE);
>>
>>In the above:
>>No adjustment to ply depth during null move?
>
>Not sure what you mean ? The Null move search is called with param (depth - 3)
>so reducing the search depth for the null move.
>
>>The takeback does not seem to have enough information restored to me, but I
>>don't know your data structures.
>
>Data structures are pretty much as TSCP, I think it is ok as it is because it
>vastly speeds up my search and doesnt make any obviously buggy or totally stupid
>moves with the null move code enabled. However if I play a number of games
>against earlier versions of the program prior to Null move, they older code
>quite easily wins !

Here is the code from some version of Beowulf:
    /* -----------====     PROBE TRANSPOSITION TABLE     ====------------  */

    /* See if this position is in the hash table */
    Entry = HashProbe(B);

    /* ------------====     GET INFORMATION FROM HASH TABLE ====------------- */

    /* See what we can learn from the hash table entry (if any exists) */
    if (USE_HASH && Entry) {
        /* Get the suggested best move from the hash entry (if there is one) */
        hashmove = Entry->move;
        EntryType = GetHashType(Entry->flags);
        EntryScore = (int) Entry->score;
        /* Only accept this hash entry if the level to which it was initially
         * searched was greater than or equal to the current depth. Don't
         * check at ply==0 so that we're sure we can get a return value. */
        if (ply > 0 && ((int) Entry->depth >= depth || (EntryType == HASH_EXACT
&& IsCM(EntryScore) == 1))) {
            /* This was an exact entry so return it */
            switch (EntryType) {
            case (HASH_EXACT):
                return EntryScore;
                /* This was an upper bound, but still isn't greater than
                 * alpha, so return a fail-low */
            case (HASH_UPPER):
                if (EntryScore <= talpha)
                    return EntryScore;
                /* This was an upper bound, but was greater than alpha, so
                 * adjust beta if necessary */
                if (EntryScore < tbeta)
                    tbeta = EntryScore;
                break;
                /* This was a lower bound, but was still greater than beta,
                 * so return a fail-high */
            case (HASH_LOWER):
                if (EntryScore >= tbeta)
                    return EntryScore;
                /* This was a lower bound, but was not greater than beta, so
                 * adjust alpha if necessary */
                if (EntryScore > talpha)
                    talpha = EntryScore;
                break;
                /* Check to see if we should avoid null moves */
            case (HASH_NULL):
                DoNull = FALSE;
                break;
            }
        }
    }

    /* -----------====     TRY A NULL MOVE     ====------------- */

    /* Perform a NULL move if; (1) We're not on the first 2 plies (2) We are
     * OK to NULL move at this position (from the hash table) (3) We haven't
     * done more than one NULL move consecutively (The 'Double Null Move'
     * algorithm) (4) We're not in check (5) There are enough pieces left to
     * avoid high risk of zugzwang (6) We're on skill level 5 or higher */
    if (USE_NULL && ply > 1 && DoNull && NullDepth < 2 && !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, 0);
        else
            score = -Search(B, -tbeta, -tbeta + 1, depth - nullreduction, ply +
1, 0, 0, NullDepth + 1, NO_MOVE);

        /* 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, NullDepth + 1, 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;
        }
    }

Yours might be a bit simpler since you are not hashing.

I can't really see what's wrong with your code, to tell the truth.

You might set up some board with an obvious set of really 3-4 bad moves and one
good one and trace it to see what is happening.

For instance, here:

[D]r3k3/2ppp3/Qp6/np6/8/8/8/3K4 w - -

Most of the really dumb moves should obvously be trimmed by null move.



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.