Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: SEE and possible EXChess bug

Author: Dan Homan

Date: 15:19:39 04/01/01

Go up one level in this thread



I wrote this pretty quickly (and a long time ago), so I'll need to look
at it carefully to be sure, but I think that the "bestval" variable takes
care of the stand-pat option.  The algorithm keeps track of the best
achievable score and returns that rather than the score at the end of the
complete exchange.

 - Dan

P.S.  I've been very busy with work and haven't thought about computer chess in
months, so I am quite rusty -- even on my own code!

On April 01, 2001 at 10:29:42, Gian-Carlo Pascutto wrote:

>Hi all,
>
>in the process of using EXChess's source to design my SEE
>after, I ran into something which I suspect is either a bug
>in EXChess, or a misunderstanding from my part about how SEE
>works.
>
>Below is the critical section.
>
>int swap(int sq, position p, int side, int from)
>{
>  int val = value[p.sq[sq].type], lsq;
>
>  // initalize attackers arrays
>  attackers[0][0].v = 0; attcks[0] = 0;
>  attackers[1][0].v = 0; attcks[1] = 0;
>
>  // put in the first capture
>  attackers[side][0].v = value[p.sq[from].type];
>  attcks[side]++;
>  p.sq[from] = empty;
>
>  // find all the attcks on sq
>  dia_attcks(sq, 0, &p);
>  knt_attcks(sq, &p);
>  hor_attcks(sq, 0, &p);
>
>  attackers[0][attcks[0]].v = 0;
>  attackers[1][attcks[1]].v = 0;
>
>  // swap off the attacks, starting with other side
>  // and with the least value
>  int swapside = side^1;
>  int count[2] = { 0, 0 }, bestval;
>
>  if(attcks[swapside]) bestval = val - attackers[side][0].v;
>  else bestval = val;
>
>  count[side]++; // for the first capture
>
>  while(count[swapside] < attcks[swapside]) {
>    SSort(&attackers[swapside][count[swapside]],
>&attackers[swapside][attcks[swapside]-1]);
>    if(swapside == side) {
>     val += attackers[swapside^1][count[swapside^1]-1].v;
>     if(count[side^1] >= attcks[side^1] && val > bestval)
>       bestval = val;
>    } else {
>     val -= attackers[swapside^1][count[swapside^1]-1].v;
>     if(val > bestval)
>       { bestval= val; }
>    }
>    // square from which the capture came
>    lsq = attackers[swapside][count[swapside]].s;
>    // add in any revealed attacks due to this capture
>    if((FILE(lsq) == FILE(sq) || RANK(lsq) == RANK(sq)) && lsq)
>      hor_attcks(sq, lsq, &p);
>    else if(p.sq[lsq].type != KNIGHT && lsq) dia_attcks(sq, lsq, &p);
>    count[swapside]++;
>    swapside ^= 1;
>  }
>
>  return bestval;
>}
>
>If you look at this code you see the program keeps exchanging off
>attackers untill one side is exhausted. New best values are remembered
>if the side that was originally to move can stand pat either after
>a recapture by the opponent, or after a capture when we know the
>opponent has no more recaptures.
>
>I think this will cause problems when, for example, a bishop and a
>pawn are attacking a pawn defended by a queen.
>
>Correct would be:
>
>pawn takes pawn, standpat, score +100
>
>but I think the algorithm does:
>
>pawn takes pawn, queen takes pawn, bishop takes queen and standpat, score +900
>
>because it does not allow a standpat for the opponent.
>
>Am I missing something here? I added the (IMHO) corrected algorithm
>to Sjeng and the results aren't as good as I hoped they would be, even
>if using SEE to prune losing captures.
>
>My SEE function is below (note that I don't do Xray attacks yet):
>
>int see(int color, int square, int from)
>{
>  int sside;
>  int caps[2];
>  int value;
>  int origpiece;
>  int ourbestvalue;
>  int hisbestvalue;
>
>  /* reset data */
>  see_num_attackers[WHITE] = 0;
>  see_num_attackers[BLACK] = 0;
>
>  /* remove original capturer from board, exposing his first xray-er */
>  origpiece = board[from];
>  board[from] = npiece;
>
>  see_num_attackers[color]++;
>  see_attackers[color][0].piece = origpiece;
>  see_attackers[color][0].square = from;
>
>  /* calculate all attackers to square */
>  setup_attackers(square);
>
>  /* initially we gain the piece we are capturing */
>  value = abs(material[board[square]]);
>
>  /* free capture ? */
>  if (!see_num_attackers[!color])
>    {
>      board[from] = origpiece;
>      return value;
>    }
>  else
>    {
>      /* we can never get a higher SEE score than the piece we just captured */
>      /* so that is the current best value for our opponent */
>      /* we arent sure of anything yet, so -INF */
>      hisbestvalue = value;
>      ourbestvalue = -INF;
>    }
>
>  caps[color] = 1;
>  caps[!color] = 0;
>
>  /* start with recapture */
>  sside = !color;
>
>  /* continue as long as there are attackers */
>  while (caps[sside] < see_num_attackers[sside])
>    {
>      /* resort capturelist of sside to put lowest attacker in next position */
>      findlowest(sside, caps[sside]);
>
>      if (sside == color)
>	{
>	  /* capturing more */
>	  /* we capture the opponents recapturer */
>	  value += abs(material[see_attackers[!sside][caps[!sside]-1].piece]);
>
>	  /* if the opp ran out of attackers we can stand pat now! */
>	   if (see_num_attackers[!sside] <= caps[!sside] && value > ourbestvalue)
>	    ourbestvalue = value;
>
>	  /* our opponent can always stand pat now */
>	  if (value < hisbestvalue) hisbestvalue = value;
>	}
>      else
>	{
>	  /* recapture by opp */
>	  /* we lose whatever we captured with in last iteration */
>	  value -= abs(material[see_attackers[!sside][caps[!sside]-1].piece]);
>
>	  /* we can stand pat if we want to now */
>	  /* our best score goes up, opponent is unaffected */
>
>	  if (value > ourbestvalue)
>	    {
>	      ourbestvalue = value;
>	    }
>
>	  if (see_num_attackers[!sside] <= caps[!sside] && value < hisbestvalue)
>	    hisbestvalue = value;
>	}
>
>      /* keep track of capture count */
>      caps[sside]++;
>
>      /* switch sides */
>      sside ^= 1;
>
>    }
>
>  /* restore capturer */
>  board[from] = origpiece;
>
>  /* we return our best score now, keeping in mind that
>     it can never we better than the best for our opponent */
>  return (ourbestvalue > hisbestvalue) ? hisbestvalue : ourbestvalue;
>}
>
>--
>GCP



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.