diff --git a/board/src/bitboard.rs b/board/src/bitboard.rs index e5e126c..83f1154 100644 --- a/board/src/bitboard.rs +++ b/board/src/bitboard.rs @@ -1,9 +1,10 @@ // Eryn Wells use crate::square::Square; +use std::fmt; use std::ops::{BitAnd, BitOr, Not}; -#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +#[derive(Clone, Copy, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct BitBoard(u64); impl BitBoard { @@ -46,6 +47,58 @@ impl BitBoard { } } +impl BitBoard { + const NOT_A_FILE: u64 = 0xfefefefefefefefe; + const NOT_H_FILE: u64 = 0x7f7f7f7f7f7f7f7f; + + #[inline] + pub fn shift_north_one(&self) -> BitBoard { + BitBoard(self.0 << 8) + } + + #[inline] + pub fn shift_north_east_one(&self) -> BitBoard { + BitBoard(self.0 << 9 & BitBoard::NOT_A_FILE) + } + + #[inline] + pub fn shift_east_one(&self) -> BitBoard { + BitBoard(self.0 << 1 & BitBoard::NOT_A_FILE) + } + + #[inline] + pub fn shift_south_east_one(&self) -> BitBoard { + BitBoard(self.0 >> 7 & BitBoard::NOT_A_FILE) + } + + #[inline] + pub fn shift_south_one(&self) -> BitBoard { + BitBoard(self.0 >> 8) + } + + #[inline] + pub fn shift_south_west_one(&self) -> BitBoard { + BitBoard(self.0 >> 9 & BitBoard::NOT_H_FILE) + } + + #[inline] + pub fn shift_west_one(&self) -> BitBoard { + BitBoard(self.0 >> 1 & BitBoard::NOT_H_FILE) + } + + #[inline] + pub fn shift_north_west_one(&self) -> BitBoard { + BitBoard(self.0 << 7 & BitBoard::NOT_H_FILE) + } +} + +impl fmt::Debug for BitBoard { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + let bits = self.0; + write!(f, "BitBoard({bits:064b})") + } +} + impl BitAnd for BitBoard { type Output = BitBoard; @@ -139,6 +192,43 @@ mod tests { assert!(!bb.has_piece_at(&sq)); } + #[test] + fn cardinal_direction_shifts() { + let bb = BitBoard(0x1000_0000); // e4 + + assert_eq!(bb.shift_north_one(), BitBoard(0x0010_0000_0000), "North"); + assert_eq!(bb.shift_east_one(), BitBoard(0x2000_0000), "East"); + assert_eq!(bb.shift_south_one(), BitBoard(0x0010_0000), "South"); + assert_eq!(bb.shift_west_one(), BitBoard(0x0800_0000), "West"); + } + + #[test] + fn intercardinal_direction_shifts() { + let bb = BitBoard(0x1000_0000); // e4 + println!(" bb: {:?}", bb); + + assert_eq!( + bb.shift_north_east_one(), + BitBoard(0x0020_0000_0000), + "North East" + ); + assert_eq!( + bb.shift_south_east_one(), + BitBoard(0x0020_0000), + "South East" + ); + assert_eq!( + bb.shift_south_west_one(), + BitBoard(0x0008_0000), + "South West" + ); + assert_eq!( + bb.shift_north_west_one(), + BitBoard(0x0008_0000_0000), + "North West" + ); + } + #[cfg(target_arch = "arm")] #[test] fn arm_count_leading_zeros() {