Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: 0x88 offset table

Author: Tord Romstad

Date: 01:49:56 10/10/04

Go up one level in this thread


Hi David,

I'm not sure exactly what you are trying to achieve, but here is some code from
Glaurung
which you may find useful.  This is what I use to test whether a square is
attacked, and
to find pinned pieces and pieces which can deliver discovered checks.  I use the
same
data structures and similar code in my generate_checks() and
generate_check_evasions()
functions.

int Directions[16][16] = {
  {0},
  {15, 17, 0},  /* WP */
  {33, 31, 18, 14, -14, -18, -31, -33, 0},  /* WN */
  {17, 15, -15, -17, 0},  /* WB */
  {16, 1, -1, -16, 0},  /* WR */
  {17, 16, 15, 1, -1, -15, -16, -17, 0},  /* WQ */
  {17, 16, 15, 1, -1, -15, -16, -17, 0},  /* WK */
  {0},
  {0},
  {-15, -17, 0},  /* BP */
  {-33, -31, -18, -14, 14, 18, 31, 33, 0},  /* BN */
  {-17, -15, 15, 17, 0},  /* BB */
  {-16, -1, 1, 16, 0},  /* BR */
  {-17, -16, -15, -1, 1, 15, 16, 17, 0},  /* BQ */
  {-17, -16, -15, -1, 1, 15, 16, 17, 0},  /* BK */
  {0}
};

int PieceMask[OUTSIDE+1] = {0,WP_MASK,N_MASK,B_MASK,R_MASK,Q_MASK,K_MASK,0,
			    0,BP_MASK,N_MASK,B_MASK,R_MASK,Q_MASK,K_MASK,0,
			    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
typedef struct {
  uint8 may_attack;
  int8 step;
} attack_data_t;

attack_data_t AttackData_[256];
attack_data_t *AttackData = AttackData_ + 128;

void init_attack_data() {
  int sq, piece, tosq;
  int *ptr;

  for(sq=0; sq<256; sq++)
    AttackData_[sq].may_attack = AttackData_[sq].step = 0;
  for(sq=A1; sq<=H8; sq++)
    for(piece=WP; piece<=BK; piece++)
      for(ptr = Directions[piece]; *ptr; ptr++)
	if(SLIDER(piece))
	  for(tosq=sq+(*ptr); Board[tosq]!=OUTSIDE; tosq+=(*ptr)) {
	    AttackData[sq-tosq].step = *ptr;
	    AttackData[sq-tosq].may_attack |= PieceMask[piece];
	  }
	else {
	  tosq = sq+(*ptr);
	  if(Board[tosq]!=OUTSIDE) {
	    AttackData[sq-tosq].step = *ptr;
	    AttackData[sq-tosq].may_attack |= PieceMask[piece];
	  }
	}
}

int is_attacked(int square, int side) {
  int sq, tosq, piece, step;
  attack_data_t *a = AttackData-square;

  for(sq=KSQ(side); sq!=PL_END; sq=PL_NEXT(sq)) {
    if(sq>H8) continue;
    piece = Board[sq];
    if(PieceMask[piece]&a[sq].may_attack) {
      if(!SLIDER(piece)) return 1;
      step = a[sq].step;
      for(tosq=sq+step; Board[tosq]==EMPTY&&tosq!=square; tosq+=step);
      if(tosq==square) return 1;
    }
  }
  return 0;
}


/*
   pinned() tests whether a piece is pinned on the king.  The return value,
   if nonzero, indicates the direction in which it is pinned.
*/
int pinned(int square) {
  int side = COLOUR(Board[square]), ksq = KSQ(side), p1, p2, step, sq;
  attack_data_t *a = AttackData-ksq+square;

  if(!(a->may_attack&Q_MASK)) return 0;

  if(AttackData[square-ksq].may_attack&R_MASK) p1 = ((side^1)<<3)|ROOK;
  else p1 = ((side^1)<<3)|BISHOP;
  p2 = ((side^1)<<3)|QUEEN;

  step = a->step;
  for(sq=square+step; Board[sq]==EMPTY; sq+=step);
  if(sq==ksq) {
    for(sq=square-step; Board[sq]==EMPTY; sq-=step);
    if(Board[sq]==p1 || Board[sq]==p2) return step;
  }
  return 0;
}

/*
   disc_check_candidate() tests whether a piece is a candidate to deliver
   a discovered check.  The return value, if nonzero, indicates the direction
   in which the piece *cannot* move in order to give a discovered check.
*/
int disc_check_candidate(int square) {
  int side = COLOUR(Board[square]), ksq=KSQ(side^1), p1, p2, step, sq;

  attack_data_t *a = AttackData-ksq+square;

  if(!(a->may_attack&Q_MASK)) return 0;

  if(AttackData[square-ksq].may_attack&R_MASK) p1 = (side<<3)|ROOK;
  else p1 = (side<<3)|BISHOP;
  p2 = (side<<3)|QUEEN;

  step = a->step;
  for(sq=square+step; Board[sq]==EMPTY; sq+=step);
  if(sq==ksq) {
    for(sq=square-step; Board[sq]==EMPTY; sq-=step);
    if(Board[sq]==p1 || Board[sq]==p2) return step;
  }
  return 0;
}


Tord



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.