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.