Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: Question about static exchange evaluation

Author: jonathan Baxter

Date: 13:25:19 11/12/98

Go up one level in this thread


On November 12, 1998 at 14:34:16, Robert Hyatt wrote:

>On November 12, 1998 at 12:13:26, Larry Coon wrote:
>
>>(Long question follows -- sorry.)
>>
>>I know I saw SEE talked about recently, but I couldn't
>>locate the discussion here, on rgcc or anybody's web
>>page (I don't remember where I saw it).  Can somebody
>>tell me if I'm thinking about this the right way?
>

SEE is nothing more than negamax (or minimax) where at each node in the tree
you have two options: make the next capture or sit (with an eval equal to the
current material balance). I found that once I thought of it that way, the code
was easy to write. Note that the resulting tree looks like:

+
| \
|  \
+   +
| \
|  \
+   +
| \
|  \
+   +

with a depth equal to the number of captures in the exchange.

Here's my "swap.c" (note that "topieces" for each square is a 32 bit mask
indicating which pieces are attacking that square. It is ordered so that
the next bit is always the next highest value piece. "ff_one" finds the first
set bit in its argument, fl_one finds the last set bit).


/* swap routines. */

#include "includes.h"
#include "tdchess.h"

static int debug = 0;
extern struct state *state;

/* does a crude static search to determine the material gain of
   move. It is mainly used for move ordering. */
etype swap(Position *b, Move *m)
{
        etype swap_score[32], next, gain;
        int pi, tomove, i;
        uint32 topieces, discovered, used;
        uint32 mask;
        Square from=m->from, to=m->to;

        gain = mat_value(ABS(b->board[to]));

        /* start with the piece on the "to" sqaure */
        swap_score[0] = gain;

        /* the first capture is from the "from" square. */
        next = -mat_value(ABS(b->board[from]));
        used = 1<<b->pboard[from];
        topieces = b->topieces[to] & ~used;
        if (debug)
                lprintf(0, "from: %s gain: %d\n", posstr(from), gain);

        /* moving this piece might expose a new capture possibility by
           another sliding piece. */
        discovered = b->topieces[from] & b->sliding_mask & ~used;
        while (discovered) {
                pi = ff_one(discovered);
                discovered &= ~(1<<pi);
                if (same_line(b->pieces[pi].pos, from, to)) {
                        topieces |= (1<<pi);
                        if (debug)
                                lprintf(0, "discovered: %s\n",
                                        posstr(b->pieces[pi].pos));
                        break;
                }
        }

        /* now we go through and work out the rest of the scores. */
        tomove = 1;
        mask = ~player_mask(b);
        i = 1;
        while (topieces & mask) {
                gain += next;
                swap_score[i++] = gain;
                pi = fl_one(topieces & mask);
                from = b->pieces[pi].pos;
                if (debug)
                        lprintf(0, "from: %s gain: %d\n", posstr(from), gain);
                topieces &= ~(1<<pi);
                used |= (1<<pi);
                discovered = b->topieces[from] & b->sliding_mask & ~used;
                while (discovered) {
                        pi = ff_one(discovered);
                        discovered &= ~(1<<pi);
                        if (same_line(b->pieces[pi].pos, from, to)) {
                                topieces |= (1<<pi);
                                if (debug)
                                        lprintf(0, "discovered: %s\n",
                                         posstr(b->pieces[pi].pos));
                                break;
                        }
                }
                next = tomove*mat_value(ABS(b->board[from]));
                tomove = -tomove;
                mask = ~mask;
        }

        /* now "minimax" the swap scores to determine the optimal
           point to stop. */
        --i;
        while (i) {
                if (tomove < 0) {
                        if (swap_score[i] < swap_score[i-1])
                                swap_score[i-1] = swap_score[i];
                } else {
                        if (swap_score[i] > swap_score[i-1])
                                swap_score[i-1] = swap_score[i];
                }
                --i;
                tomove = -tomove;
        }

        return swap_score[0];
}







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.