use square::Square;
use bitboard::Bitboard;
use types::{Color, Piece, Role};
use magics;
include!(concat!(env!("OUT_DIR"), "/attacks.rs"));
#[inline]
pub fn pawn_attacks(color: Color, sq: Square) -> Bitboard {
Bitboard(match color {
Color::White => WHITE_PAWN_ATTACKS[usize::from(sq)],
Color::Black => BLACK_PAWN_ATTACKS[usize::from(sq)],
})
}
#[inline]
pub fn knight_attacks(sq: Square) -> Bitboard {
Bitboard(KNIGHT_ATTACKS[usize::from(sq)])
}
#[inline]
pub fn king_attacks(sq: Square) -> Bitboard {
Bitboard(KING_ATTACKS[usize::from(sq)])
}
#[inline]
pub fn rook_attacks(sq: Square, occupied: Bitboard) -> Bitboard {
let m = &magics::ROOK_MAGICS[usize::from(sq)];
let idx = (m.factor.wrapping_mul(occupied.0 & m.mask) >> (64 - 12)) as usize + m.offset;
debug_assert!(idx < ATTACKS.len());
Bitboard(unsafe { *ATTACKS.get_unchecked(idx) })
}
#[inline]
pub fn rook_mask(sq: Square) -> Bitboard {
Bitboard(magics::ROOK_MAGICS[usize::from(sq)].mask)
}
#[inline]
pub fn bishop_attacks(sq: Square, occupied: Bitboard) -> Bitboard {
let m = &magics::BISHOP_MAGICS[usize::from(sq)];
let idx = (m.factor.wrapping_mul(occupied.0 & m.mask) >> (64 - 9)) as usize + m.offset;
debug_assert!(idx < ATTACKS.len());
Bitboard(unsafe { *ATTACKS.get_unchecked(idx) })
}
#[inline]
pub fn bishop_mask(sq: Square) -> Bitboard {
Bitboard(magics::BISHOP_MAGICS[usize::from(sq)].mask)
}
#[inline]
pub fn queen_attacks(sq: Square, occupied: Bitboard) -> Bitboard {
rook_attacks(sq, occupied) ^ bishop_attacks(sq, occupied)
}
pub fn attacks(sq: Square, piece: Piece, occupied: Bitboard) -> Bitboard {
match piece.role {
Role::Pawn => pawn_attacks(piece.color, sq),
Role::Knight => knight_attacks(sq),
Role::Bishop => bishop_attacks(sq, occupied),
Role::Rook => rook_attacks(sq, occupied),
Role::Queen => queen_attacks(sq, occupied),
Role::King => king_attacks(sq),
}
}
#[inline]
pub fn ray(a: Square, b: Square) -> Bitboard {
Bitboard(BB_RAYS[usize::from(a)][usize::from(b)])
}
#[inline]
pub fn between(a: Square, b: Square) -> Bitboard {
Bitboard(BB_BETWEEN[usize::from(a)][usize::from(b)])
}
#[inline]
pub fn aligned(a: Square, b: Square, c: Square) -> bool {
ray(a, b).contains(c)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rook_attacks() {
assert_eq!(rook_attacks(Square::D6, Bitboard(0x3f7f28802826f5b9)),
Bitboard(0x8370808000000));
}
}