/* the movement map generator - this allows you to quickly determine if a particular piece type can ever capture from one square to another. This is useful for Xray attacks in the eval fn */ #include "includes.h" #include "knightcap.h" char capture_map[2*KING+1][NUM_SQUARES][NUM_SQUARES]; char sliding_map[NUM_SQUARES][NUM_SQUARES]; char edge_square[NUM_SQUARES]; uint64 same_line_mask[NUM_SQUARES][NUM_SQUARES]; static void init_pawn_movements(Piece p) { Square from; for (from=A1;from<=H8;from++) { if (YPOS(from) == 0 || YPOS(from) == 7) continue; if (p == PAWN) { if (XPOS(from) != 0) capture_map[p+KING][from][from+NORTH_WEST] = 1; if (XPOS(from) != 7) capture_map[p+KING][from][from+NORTH_EAST] = 1; } else { if (XPOS(from) != 0) capture_map[p+KING][from][from+SOUTH_WEST] = 1; if (XPOS(from) != 7) capture_map[p+KING][from][from+SOUTH_EAST] = 1; } } } static void init_knight_movements(Piece p) { Square from, to; for (from=A1;from<=H8;from++) for (to=A1;to<=H8;to++) { int dx = abs(XPOS(from) - XPOS(to)); int dy = abs(YPOS(from) - YPOS(to)); if (from == to) continue; if ((dx == 1 && dy == 2) || (dx == 2 && dy == 1)) { capture_map[p+KING][from][to] = 1; } } } static void init_bishop_movements(Piece p) { Square from, to; for (from=A1;from<=H8;from++) for (to=A1;to<=H8;to++) { int dx = abs(XPOS(from) - XPOS(to)); int dy = abs(YPOS(from) - YPOS(to)); if (from == to) continue; if (dx == dy) { capture_map[p+KING][from][to] = 1; } } } static void init_rook_movements(Piece p) { Square from, to; for (from=A1;from<=H8;from++) for (to=A1;to<=H8;to++) { int dx = abs(XPOS(from) - XPOS(to)); int dy = abs(YPOS(from) - YPOS(to)); if (from == to) continue; if (dx == 0 || dy == 0) { capture_map[p+KING][from][to] = 1; } } } static void init_queen_movements(Piece p) { Square from, to; for (from=A1;from<=H8;from++) for (to=A1;to<=H8;to++) { int dx = abs(XPOS(from) - XPOS(to)); int dy = abs(YPOS(from) - YPOS(to)); if (from == to) continue; if ((dx == 0 || dy == 0) || (dx == dy)) { capture_map[p+KING][from][to] = 1; } } } static void init_king_movements(Piece p) { Square from, to; for (from=A1;from<=H8;from++) for (to=A1;to<=H8;to++) { int dx = abs(XPOS(from) - XPOS(to)); int dy = abs(YPOS(from) - YPOS(to)); if (from == to) continue; if (dx <= 1 && dy <= 1) { capture_map[p+KING][from][to] = 1; } } } static void init_sliding_map(void) { Square p1, p2, s1, s2; int dir, i; memset(sliding_map,0, sizeof(sliding_map)); for (i=0;i<8;i++) { dir = EAST; p1 = A1 + i*NORTH; p2 = H1 + i*NORTH; for (s1=p1;s1=p2; s1+=dir) mask |= ((uint64)1<=p2;s1+=dir) for (s2=p1;s2>=p2;s2+=dir) if (s1 != s2) { same_line_mask[s1][s2] = mask; } } for (i=1;i<8;i++) { dir = NORTH_WEST; p1 = H1 + i*NORTH; p2 = A8 + i*EAST; mask = 0; for (s1=p1; s1>=p2; s1+=dir) mask |= ((uint64)1<=p2;s1+=dir) for (s2=p1;s2>=p2;s2+=dir) if (s1 != s2) { same_line_mask[s1][s2] = mask; } } } static void init_edges(void) { Square p; memset(edge_square, 0, sizeof(edge_square)); for (p=A1;p<=H1;p+=EAST) edge_square[p] += SOUTH; for (p=A1;p<=A8;p+=NORTH) edge_square[p] += WEST; for (p=A8;p<=H8;p+=EAST) edge_square[p] += NORTH; for (p=H1;p<=H8;p+=NORTH) edge_square[p] += EAST; } void init_movements(void) { static int initialised; if (initialised) return; initialised = 1; init_pawn_movements(PAWN); init_knight_movements(KNIGHT); init_bishop_movements(BISHOP); init_rook_movements(ROOK); init_queen_movements(QUEEN); init_king_movements(KING); init_pawn_movements(-PAWN); init_knight_movements(-KNIGHT); init_bishop_movements(-BISHOP); init_rook_movements(-ROOK); init_queen_movements(-QUEEN); init_king_movements(-KING); init_sliding_map(); init_same_line_mask(); init_edges(); }