--- /dev/null
+\r
+// attack.c\r
+\r
+// includes\r
+\r
+#include "board.h"\r
+#include "colour.h"\r
+#include "move.h"\r
+#include "attack.h"\r
+#include "piece.h"\r
+#include "util.h"\r
+\r
+// macros\r
+\r
+#define DELTA_INC(delta) (DeltaInc[128+(delta)])\r
+#define DELTA_MASK(delta) (DeltaMask[128+(delta)])\r
+\r
+// "constants"\r
+\r
+const sint8 KnightInc[8+1] = {\r
+ -33, -31, -18, -14, +14, +18, +31, +33, 0\r
+};\r
+\r
+const sint8 BishopInc[4+1] = {\r
+ -17, -15, +15, +17, 0\r
+};\r
+\r
+const sint8 RookInc[4+1] = {\r
+ -16, -1, +1, +16, 0\r
+};\r
+\r
+const sint8 QueenInc[8+1] = {\r
+ -17, -16, -15, -1, +1, +15, +16, +17, 0\r
+};\r
+\r
+const sint8 KingInc[8+1] = {\r
+ -17, -16, -15, -1, +1, +15, +16, +17, 0\r
+};\r
+\r
+// variables\r
+\r
+static sint8 DeltaInc[256];\r
+static uint8 DeltaMask[256];\r
+\r
+// prototypes\r
+\r
+static bool delta_is_ok (int delta);\r
+static bool inc_is_ok (int inc);\r
+\r
+// functions\r
+\r
+// attack_init()\r
+\r
+void attack_init() {\r
+\r
+ int delta;\r
+ int dir, inc, dist;\r
+\r
+ for (delta = -128; delta < +128; delta++) {\r
+ DeltaInc[128+delta] = IncNone;\r
+ DeltaMask[128+delta] = 0;\r
+ }\r
+\r
+ DeltaMask[128-17] |= BlackPawnFlag;\r
+ DeltaMask[128-15] |= BlackPawnFlag;\r
+\r
+ DeltaMask[128+15] |= WhitePawnFlag;\r
+ DeltaMask[128+17] |= WhitePawnFlag;\r
+\r
+ for (dir = 0; dir < 8; dir++) {\r
+ delta = KnightInc[dir];\r
+ ASSERT(delta_is_ok(delta));\r
+ DeltaMask[128+delta] |= KnightFlag;\r
+ }\r
+\r
+ for (dir = 0; dir < 4; dir++) {\r
+ inc = BishopInc[dir];\r
+ ASSERT(inc!=IncNone);\r
+ for (dist = 1; dist < 8; dist++) {\r
+ delta = inc*dist;\r
+ ASSERT(delta_is_ok(delta));\r
+ ASSERT(DeltaInc[128+delta]==IncNone);\r
+ DeltaInc[128+delta] = inc;\r
+ DeltaMask[128+delta] |= BishopFlag;\r
+ }\r
+ }\r
+\r
+ for (dir = 0; dir < 4; dir++) {\r
+ inc = RookInc[dir];\r
+ ASSERT(inc!=IncNone);\r
+ for (dist = 1; dist < 8; dist++) {\r
+ delta = inc*dist;\r
+ ASSERT(delta_is_ok(delta));\r
+ ASSERT(DeltaInc[128+delta]==IncNone);\r
+ DeltaInc[128+delta] = inc;\r
+ DeltaMask[128+delta] |= RookFlag;\r
+ }\r
+ }\r
+\r
+ for (dir = 0; dir < 8; dir++) {\r
+ delta = KingInc[dir];\r
+ ASSERT(delta_is_ok(delta));\r
+ DeltaMask[128+delta] |= KingFlag;\r
+ }\r
+}\r
+\r
+// delta_is_ok()\r
+\r
+static bool delta_is_ok(int delta) {\r
+\r
+ if (delta < -119 || delta > +119) return FALSE;\r
+\r
+ return TRUE;\r
+}\r
+\r
+// inc_is_ok()\r
+\r
+static bool inc_is_ok(int inc) {\r
+\r
+ int dir;\r
+\r
+ for (dir = 0; dir < 8; dir++) {\r
+ if (KingInc[dir] == inc) return TRUE;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+// is_in_check()\r
+\r
+bool is_in_check(const board_t * board, int colour) {\r
+\r
+ ASSERT(board_is_ok(board));\r
+ ASSERT(colour_is_ok(colour));\r
+\r
+ return is_attacked(board,king_pos(board,colour),colour_opp(colour));\r
+}\r
+\r
+// is_attacked()\r
+\r
+bool is_attacked(const board_t * board, int to, int colour) {\r
+\r
+ const uint8 * ptr;\r
+ int from, piece;\r
+\r
+ ASSERT(board_is_ok(board));\r
+ ASSERT(square_is_ok(to));\r
+ ASSERT(colour_is_ok(colour));\r
+\r
+ for (ptr = board->list[colour]; (from=*ptr) != SquareNone; ptr++) {\r
+\r
+ piece = board->square[from];\r
+ ASSERT(colour_equal(piece,colour));\r
+\r
+ if (piece_attack(board,piece,from,to)) return TRUE;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+// piece_attack()\r
+\r
+bool piece_attack(const board_t * board, int piece, int from, int to) {\r
+\r
+ int delta;\r
+ int inc, sq;\r
+\r
+ ASSERT(board_is_ok(board));\r
+ ASSERT(piece_is_ok(piece));\r
+ ASSERT(square_is_ok(from));\r
+ ASSERT(square_is_ok(to));\r
+\r
+ delta = to - from;\r
+ ASSERT(delta_is_ok(delta));\r
+\r
+ if ((piece & DELTA_MASK(delta)) == 0) return FALSE; // no pseudo-attack\r
+\r
+ if (!piece_is_slider(piece)) return TRUE;\r
+\r
+ inc = DELTA_INC(delta);\r
+ ASSERT(inc_is_ok(inc));\r
+\r
+ for (sq = from+inc; sq != to; sq += inc) {\r
+ ASSERT(square_is_ok(sq));\r
+ if (board->square[sq] != Empty) return FALSE; // blocker\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+// is_pinned()\r
+\r
+bool is_pinned(const board_t * board, int from, int to, int colour) {\r
+\r
+ int king;\r
+ int inc;\r
+ int sq, piece;\r
+\r
+ ASSERT(board!=NULL);\r
+ ASSERT(square_is_ok(from));\r
+ ASSERT(square_is_ok(to));\r
+ ASSERT(colour_is_ok(colour));\r
+\r
+ king = king_pos(board,colour);\r
+\r
+ inc = DELTA_INC(king-from);\r
+ if (inc == IncNone) return FALSE; // not a line\r
+\r
+ sq = from;\r
+ do sq += inc; while (board->square[sq] == Empty);\r
+\r
+ if (sq != king) return FALSE; // blocker\r
+\r
+ sq = from;\r
+ do sq -= inc; while ((piece=board->square[sq]) == Empty);\r
+\r
+ return square_is_ok(sq)\r
+ && (piece & DELTA_MASK(king-sq)) != 0\r
+ && piece_colour(piece) == colour_opp(colour)\r
+ && DELTA_INC(king-to) != inc;\r
+}\r
+\r
+// end of attack.cpp\r
+\r