diff --git a/bitboard/src/bitboard.rs b/bitboard/src/bitboard.rs index 7dcc164..1ef26e9 100644 --- a/bitboard/src/bitboard.rs +++ b/bitboard/src/bitboard.rs @@ -1,7 +1,8 @@ // Eryn Wells +use crate::bit_scanner::{LeadingBitScanner, TrailingBitScanner}; +use crate::direction::IterationDirection; use crate::library; -use crate::{LeadingBitScanner, TrailingBitScanner}; use chessfriend_core::{Color, Direction, File, Rank, Square}; use forward_ref::{forward_ref_binop, forward_ref_op_assign, forward_ref_unop}; use std::fmt; @@ -223,27 +224,39 @@ impl BitBoard { self.0.is_power_of_two() } - /// Return an Iterator over the occupied squares. The Iterator yields - /// squares starting from the leading (most-significant bit) end of the - /// board. + /// Return an Iterator over the occupied squares. #[must_use] - pub fn occupied_squares(&self) -> impl Iterator { - LeadingBitScanner::new(self.0).map(|idx| unsafe { Square::from_index_unchecked(idx as u8) }) + pub fn occupied_squares( + &self, + direction: IterationDirection, + ) -> Box> { + fn index_to_square(index: usize) -> Square { + unsafe { Square::from_index_unchecked(index as u8) } + } + + match direction { + IterationDirection::Leading => { + Box::new(LeadingBitScanner::new(self.0).map(index_to_square)) + } + IterationDirection::Trailing => { + Box::new(TrailingBitScanner::new(self.0).map(index_to_square)) + } + } } - /// Return an Iterator over the occupied squares. The Iterator yields - /// squares starting from the trailing (least-significant bit) end of the - /// board. - pub fn occupied_squares_trailing(&self) -> impl Iterator { - TrailingBitScanner::new(self.0) - .map(|idx| unsafe { Square::from_index_unchecked(idx as u8) }) + #[must_use] + pub fn first_occupied_square(&self, direction: IterationDirection) -> Option { + match direction { + IterationDirection::Leading => self.first_occupied_square_leading(), + IterationDirection::Trailing => self.first_occupied_square_trailing(), + } } /// If the board is not empty, returns the first occupied square on the /// board, starting at the leading (most-significant) end of the board. If /// the board is empty, returns `None`. #[must_use] - pub fn first_occupied_square(&self) -> Option { + fn first_occupied_square_leading(&self) -> Option { let leading_zeros = self.0.leading_zeros() as u8; if leading_zeros < Square::NUM as u8 { unsafe { @@ -260,7 +273,7 @@ impl BitBoard { /// board, starting at the trailing (least-significant) end of the board. /// If the board is empty, returns `None`. #[must_use] - pub fn first_occupied_square_trailing(&self) -> Option { + fn first_occupied_square_trailing(&self) -> Option { let trailing_zeros = self.0.trailing_zeros() as u8; if trailing_zeros < Square::NUM as u8 { unsafe { Some(Square::from_index_unchecked(trailing_zeros)) } @@ -458,7 +471,10 @@ mod tests { fn single_rank_occupancy() { let bb = BitBoard(0b01010100); let expected_squares = [Square::G1, Square::E1, Square::C1]; - for (a, b) in bb.occupied_squares().zip(expected_squares.iter().cloned()) { + for (a, b) in bb + .occupied_squares(IterationDirection::Leading) + .zip(expected_squares.iter().cloned()) + { assert_eq!(a, b); } } @@ -470,7 +486,10 @@ mod tests { let expected_squares = [Square::H8, Square::F6, Square::C5, Square::E2, Square::D1]; - for (a, b) in bb.occupied_squares().zip(expected_squares.iter().cloned()) { + for (a, b) in bb + .occupied_squares(IterationDirection::Leading) + .zip(expected_squares.iter().cloned()) + { assert_eq!(a, b); } } @@ -514,7 +533,7 @@ mod tests { #[test] fn first_occupied_squares() { let bb = bitboard![A8 E1]; - assert_eq!(bb.first_occupied_square(), Some(Square::A8)); + assert_eq!(bb.first_occupied_square_leading(), Some(Square::A8)); assert_eq!(bb.first_occupied_square_trailing(), Some(Square::E1)); let bb = bitboard![D6 E7 F8]; diff --git a/bitboard/src/direction.rs b/bitboard/src/direction.rs new file mode 100644 index 0000000..b1298fc --- /dev/null +++ b/bitboard/src/direction.rs @@ -0,0 +1,6 @@ +#[derive(Default)] +pub enum IterationDirection { + #[default] + Leading, + Trailing, +} diff --git a/bitboard/src/lib.rs b/bitboard/src/lib.rs index a39d3c9..983f65e 100644 --- a/bitboard/src/lib.rs +++ b/bitboard/src/lib.rs @@ -2,12 +2,12 @@ mod bit_scanner; mod bitboard; +mod direction; mod library; mod shifts; pub use bitboard::BitBoard; - -pub(crate) use bit_scanner::{LeadingBitScanner, TrailingBitScanner}; +pub use direction::IterationDirection; #[macro_export] macro_rules! bitboard {