diff --git a/engine/src/bitboard/attacks.rs b/engine/src/bitboard/attacks.rs index a348d96..27c54e0 100644 --- a/engine/src/bitboard/attacks.rs +++ b/engine/src/bitboard/attacks.rs @@ -71,6 +71,31 @@ impl Board { pub fn get_pseudo_queen_moves(&self, sq: u32) -> u64 { return self.get_pseudo_bishop_moves(sq) | self.get_pseudo_rook_moves(sq); } + + #[inline] + pub fn is_square_attacked(&self, king_sq: u32) -> bool { + let offset: usize = 6 * self.side_to_move as usize; + + // rook-queen checks (+) + let mut threat_mask: u64 = self.get_pseudo_rook_moves(king_sq); + let mut attacker_mask: u64 = self.bitboards[10 - offset] | self.bitboards[9 - offset]; + if threat_mask & attacker_mask != 0 { return true; } + + // bishop-queen checks (x) + threat_mask = self.get_pseudo_bishop_moves(king_sq); + attacker_mask = self.bitboards[10 - offset] | self.bitboards[8 - offset]; + if threat_mask & attacker_mask != 0 { return true; } + + // knight checks (L) + threat_mask = KNIGHT_ATTACK_MAP[king_sq as usize]; + attacker_mask = self.bitboards[7 - offset]; + if threat_mask & attacker_mask != 0 { return true; } + + // pawn checks (v) + threat_mask = PAWN_ATTACK_MAP[king_sq as usize][self.side_to_move as usize]; + attacker_mask = self.bitboards[6 - offset]; + return threat_mask & attacker_mask != 0; + } } #[inline(always)] diff --git a/engine/src/bitboard/movegen/kings.rs b/engine/src/bitboard/movegen/kings.rs index 883d082..18315e4 100644 --- a/engine/src/bitboard/movegen/kings.rs +++ b/engine/src/bitboard/movegen/kings.rs @@ -51,4 +51,38 @@ impl Board { } } } + fn add_king_castles(&self, buffer: &mut MoveBuffer, move_mask: u64) { + if self.castling_rights & (0b11 << (2 - 2 * self.side_to_move)) == 0 { + return; + } + + let offset = 5 + 6 * self.side_to_move as u8; + let castle_offset = 2 - 2 * self.side_to_move as u8; + let castling_rights = self.castling_rights & 3 << castle_offset; + let occupied = self.occupancy[2]; + let king_sq = self.bitboards[offset as usize].trailing_zeros(); + + let queenside_mask = 0b111 << (king_sq - 3); + let kingside_mask = 0b11 << (king_sq + 1); + + if (castling_rights & 1 << castle_offset) != 0 + && queenside_mask & occupied == 0 + && !move_mask & 0b11 << (king_sq - 2) == 0 + && !self.is_square_attacked(king_sq - 2) { + buffer.add(BitMove::castle( + king_sq as u8, + (king_sq - 2) as u8 + )); + } + if (castling_rights & 2 << castle_offset) != 0 + && kingside_mask & occupied == 0 + && !move_mask & 0b11 << (king_sq + 1) == 0 + && !self.is_square_attacked(king_sq + 2) { + buffer.add(BitMove::castle( + king_sq as u8, + (king_sq + 2) as u8 + )); + } + + } } \ No newline at end of file