15 #define DELTA_INC(delta) (DeltaInc[128+(delta)])
\r
16 #define DELTA_MASK(delta) (DeltaMask[128+(delta)])
\r
20 const sint8 KnightInc[8+1] = {
\r
21 -33, -31, -18, -14, +14, +18, +31, +33, 0
\r
24 const sint8 BishopInc[4+1] = {
\r
25 -17, -15, +15, +17, 0
\r
28 const sint8 RookInc[4+1] = {
\r
32 const sint8 QueenInc[8+1] = {
\r
33 -17, -16, -15, -1, +1, +15, +16, +17, 0
\r
36 const sint8 KingInc[8+1] = {
\r
37 -17, -16, -15, -1, +1, +15, +16, +17, 0
\r
42 static sint8 DeltaInc[256];
\r
43 static uint8 DeltaMask[256];
\r
47 static bool delta_is_ok (int delta);
\r
48 static bool inc_is_ok (int inc);
\r
54 void attack_init() {
\r
59 for (delta = -128; delta < +128; delta++) {
\r
60 DeltaInc[128+delta] = IncNone;
\r
61 DeltaMask[128+delta] = 0;
\r
64 DeltaMask[128-17] |= BlackPawnFlag;
\r
65 DeltaMask[128-15] |= BlackPawnFlag;
\r
67 DeltaMask[128+15] |= WhitePawnFlag;
\r
68 DeltaMask[128+17] |= WhitePawnFlag;
\r
70 for (dir = 0; dir < 8; dir++) {
\r
71 delta = KnightInc[dir];
\r
72 ASSERT(delta_is_ok(delta));
\r
73 DeltaMask[128+delta] |= KnightFlag;
\r
76 for (dir = 0; dir < 4; dir++) {
\r
77 inc = BishopInc[dir];
\r
78 ASSERT(inc!=IncNone);
\r
79 for (dist = 1; dist < 8; dist++) {
\r
81 ASSERT(delta_is_ok(delta));
\r
82 ASSERT(DeltaInc[128+delta]==IncNone);
\r
83 DeltaInc[128+delta] = inc;
\r
84 DeltaMask[128+delta] |= BishopFlag;
\r
88 for (dir = 0; dir < 4; dir++) {
\r
90 ASSERT(inc!=IncNone);
\r
91 for (dist = 1; dist < 8; dist++) {
\r
93 ASSERT(delta_is_ok(delta));
\r
94 ASSERT(DeltaInc[128+delta]==IncNone);
\r
95 DeltaInc[128+delta] = inc;
\r
96 DeltaMask[128+delta] |= RookFlag;
\r
100 for (dir = 0; dir < 8; dir++) {
\r
101 delta = KingInc[dir];
\r
102 ASSERT(delta_is_ok(delta));
\r
103 DeltaMask[128+delta] |= KingFlag;
\r
109 static bool delta_is_ok(int delta) {
\r
111 if (delta < -119 || delta > +119) return FALSE;
\r
118 static bool inc_is_ok(int inc) {
\r
122 for (dir = 0; dir < 8; dir++) {
\r
123 if (KingInc[dir] == inc) return TRUE;
\r
131 bool is_in_check(const board_t * board, int colour) {
\r
133 ASSERT(board_is_ok(board));
\r
134 ASSERT(colour_is_ok(colour));
\r
136 return is_attacked(board,king_pos(board,colour),colour_opp(colour));
\r
141 bool is_attacked(const board_t * board, int to, int colour) {
\r
146 ASSERT(board_is_ok(board));
\r
147 ASSERT(square_is_ok(to));
\r
148 ASSERT(colour_is_ok(colour));
\r
150 for (ptr = board->list[colour]; (from=*ptr) != SquareNone; ptr++) {
\r
152 piece = board->square[from];
\r
153 ASSERT(colour_equal(piece,colour));
\r
155 if (piece_attack(board,piece,from,to)) return TRUE;
\r
163 bool piece_attack(const board_t * board, int piece, int from, int to) {
\r
168 ASSERT(board_is_ok(board));
\r
169 ASSERT(piece_is_ok(piece));
\r
170 ASSERT(square_is_ok(from));
\r
171 ASSERT(square_is_ok(to));
\r
174 ASSERT(delta_is_ok(delta));
\r
176 if ((piece & DELTA_MASK(delta)) == 0) return FALSE; // no pseudo-attack
\r
178 if (!piece_is_slider(piece)) return TRUE;
\r
180 inc = DELTA_INC(delta);
\r
181 ASSERT(inc_is_ok(inc));
\r
183 for (sq = from+inc; sq != to; sq += inc) {
\r
184 ASSERT(square_is_ok(sq));
\r
185 if (board->square[sq] != Empty) return FALSE; // blocker
\r
193 bool is_pinned(const board_t * board, int from, int to, int colour) {
\r
199 ASSERT(board!=NULL);
\r
200 ASSERT(square_is_ok(from));
\r
201 ASSERT(square_is_ok(to));
\r
202 ASSERT(colour_is_ok(colour));
\r
204 king = king_pos(board,colour);
\r
206 inc = DELTA_INC(king-from);
\r
207 if (inc == IncNone) return FALSE; // not a line
\r
210 do sq += inc; while (board->square[sq] == Empty);
\r
212 if (sq != king) return FALSE; // blocker
\r
215 do sq -= inc; while ((piece=board->square[sq]) == Empty);
\r
217 return square_is_ok(sq)
\r
218 && (piece & DELTA_MASK(king-sq)) != 0
\r
219 && piece_colour(piece) == colour_opp(colour)
\r
220 && DELTA_INC(king-to) != inc;
\r
223 // end of attack.cpp
\r