summaryrefslogtreecommitdiff
path: root/src/engine/moves/attack.c
diff options
context:
space:
mode:
authorAargh Rai <aargh.rai+git@gmail.com>2026-07-16 14:08:24 +0530
committerAargh Rai <aargh.rai+git@gmail.com>2026-07-16 14:08:24 +0530
commit1a52152852ff29c727673fc80e8bf8eca5ed6365 (patch)
treee719771aa1b23f0b8774814ee907057f86f1dda1 /src/engine/moves/attack.c
parent6ac448727e1e26c78055eaaa361217f64393d808 (diff)
starting pos, move count, test pass
Diffstat (limited to 'src/engine/moves/attack.c')
-rw-r--r--src/engine/moves/attack.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/src/engine/moves/attack.c b/src/engine/moves/attack.c
new file mode 100644
index 0000000..e4923ea
--- /dev/null
+++ b/src/engine/moves/attack.c
@@ -0,0 +1,154 @@
+#define MOVES_INTERNAL
+#include "engine/moves.h"
+
+static bool pawn_attacks_square(position_t position, square_t square, u8 by_color) {
+ bitboard_t enemy_pawns;
+ if (by_color == WHITE_TURN) {
+ enemy_pawns = position.bitboards[WHITE_PAWN];
+ if (square < 8) return false;
+ bitboard_t nw = (square % 8 == 7) ? 0 : (enemy_pawns >> (square - 7));
+ bitboard_t ne = (square % 8 == 0) ? 0 : (enemy_pawns >> (square - 9));
+ return (nw | ne) & 1;
+ } else {
+ enemy_pawns = position.bitboards[BLACK_PAWN];
+ if (square > 54) return false;
+ bitboard_t se = (square % 8 == 0) ? 0 : (enemy_pawns >> (square + 7));
+ bitboard_t sw = (square % 8 == 7) ? 0 : (enemy_pawns >> (square + 9));
+ return (se | sw) & 1;
+ }
+}
+
+static bool knight_attacks_square(position_t position, square_t square, u8 by_color) {
+ bitboard_t enemy_knights = (by_color == WHITE_TURN)
+ ? position.bitboards[WHITE_KNIGHT]
+ : position.bitboards[BLACK_KNIGHT];
+ return knight_moves[square] & enemy_knights;
+}
+
+static bool king_attacks_square(position_t position, square_t square, u8 by_color) {
+ bitboard_t enemy_king = (by_color == WHITE_TURN)
+ ? position.bitboards[WHITE_KING]
+ : position.bitboards[BLACK_KING];
+ bitboard_t movement;
+ if (square >= 10) {
+ movement = 920078ULL << (square - 10);
+ } else {
+ movement = 920078ULL >> -(square - 10);
+ }
+ if ((bitboard_t)1 << square & BITMASK_FILE_A) {
+ movement &= BITMASK_FILE_A | BITMASK_FILE_B;
+ } else if ((bitboard_t)1 << square & BITMASK_FILE_H) {
+ movement &= BITMASK_FILE_G | BITMASK_FILE_H;
+ }
+ return movement & enemy_king;
+}
+
+static bool sliding_attacks_square(
+ position_t position,
+ square_t square,
+ u8 by_color,
+ bool check_rook,
+ bool check_bishop
+) {
+ bitboard_t all_occupied = whites(position) | blacks(position);
+ int rank = square / 8;
+ int file = square % 8;
+
+ bitboard_t enemy_rooks = (by_color == WHITE_TURN) ? position.bitboards[WHITE_ROOK] : position.bitboards[BLACK_ROOK];
+ bitboard_t enemy_bishops = (by_color == WHITE_TURN) ? position.bitboards[WHITE_BISHOP] : position.bitboards[BLACK_BISHOP];
+ bitboard_t enemy_queens = (by_color == WHITE_TURN) ? position.bitboards[WHITE_QUEEN] : position.bitboards[BLACK_QUEEN];
+
+ if (check_rook) {
+ bitboard_t rook_like = enemy_rooks | enemy_queens;
+
+ int r, idx;
+ r = rank + 1;
+ while (r < 8) {
+ idx = r * 8 + file;
+ if ((all_occupied >> idx) & 1) {
+ if ((rook_like >> idx) & 1) return true;
+ break;
+ }
+ r++;
+ }
+ r = rank - 1;
+ while (r >= 0) {
+ idx = r * 8 + file;
+ if ((all_occupied >> idx) & 1) {
+ if ((rook_like >> idx) & 1) return true;
+ break;
+ }
+ r--;
+ }
+ int f = file + 1;
+ while (f < 8) {
+ idx = rank * 8 + f;
+ if ((all_occupied >> idx) & 1) {
+ if ((rook_like >> idx) & 1) return true;
+ break;
+ }
+ f++;
+ }
+ f = file - 1;
+ while (f >= 0) {
+ idx = rank * 8 + f;
+ if ((all_occupied >> idx) & 1) {
+ if ((rook_like >> idx) & 1) return true;
+ break;
+ }
+ f--;
+ }
+ }
+
+ if (check_bishop) {
+ bitboard_t bishop_like = enemy_bishops | enemy_queens;
+
+ int r, f, idx;
+ r = rank + 1; f = file + 1;
+ while (r < 8 && f < 8) {
+ idx = r * 8 + f;
+ if ((all_occupied >> idx) & 1) {
+ if ((bishop_like >> idx) & 1) return true;
+ break;
+ }
+ r++; f++;
+ }
+ r = rank - 1; f = file - 1;
+ while (r >= 0 && f >= 0) {
+ idx = r * 8 + f;
+ if ((all_occupied >> idx) & 1) {
+ if ((bishop_like >> idx) & 1) return true;
+ break;
+ }
+ r--; f--;
+ }
+ r = rank - 1; f = file + 1;
+ while (r >= 0 && f < 8) {
+ idx = r * 8 + f;
+ if ((all_occupied >> idx) & 1) {
+ if ((bishop_like >> idx) & 1) return true;
+ break;
+ }
+ r--; f++;
+ }
+ r = rank + 1; f = file - 1;
+ while (r < 8 && f >= 0) {
+ idx = r * 8 + f;
+ if ((all_occupied >> idx) & 1) {
+ if ((bishop_like >> idx) & 1) return true;
+ break;
+ }
+ r++; f--;
+ }
+ }
+
+ return false;
+}
+
+bool square_attacked(position_t position, square_t square, u8 by_color) {
+ if (pawn_attacks_square(position, square, by_color)) return true;
+ if (knight_attacks_square(position, square, by_color)) return true;
+ if (king_attacks_square(position, square, by_color)) return true;
+ if (sliding_attacks_square(position, square, by_color, true, true)) return true;
+ return false;
+}