From a0fcf3285cbfdcfbeab3eee20da45f6c8ec971ed Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Fri, 15 Jul 2022 21:53:08 +0200 Subject: [PATCH] Add bitboard iteration Introduce 'BitboardIterator', use it to implement 'IntoIterator' for 'Bitboard'. --- src/board/bitboard/iterator.rs | 17 ++++++++++++++ src/board/bitboard/mod.rs | 43 ++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 src/board/bitboard/iterator.rs diff --git a/src/board/bitboard/iterator.rs b/src/board/bitboard/iterator.rs new file mode 100644 index 0000000..06db283 --- /dev/null +++ b/src/board/bitboard/iterator.rs @@ -0,0 +1,17 @@ +/// An [Iterator](std::iter::Iterator) of [Square](crate::board::Square) contained in a +/// [Bitboard](crate::board::Bitboard). +pub struct BitboardIterator(pub(crate) u64); + +impl Iterator for BitboardIterator { + type Item = crate::board::Square; + + fn next(&mut self) -> Option { + if self.0 == 0 { + None + } else { + let lsb = self.0.trailing_zeros() as usize; + self.0 ^= 1 << lsb; + Some(crate::board::Square::from_index(lsb)) + } + } +} diff --git a/src/board/bitboard/mod.rs b/src/board/bitboard/mod.rs index 50298d9..edb1015 100644 --- a/src/board/bitboard/mod.rs +++ b/src/board/bitboard/mod.rs @@ -1,4 +1,6 @@ use super::Square; +mod iterator; +use iterator::*; /// Use a 64-bit number to represent a chessboard. Each bit is mapped from to a specific square, so /// that index 0 -> A1, 1 -> A2, ..., 63 -> H8. @@ -40,6 +42,16 @@ impl Default for Bitboard { } } +/// Iterate over the [Square](crate::board::Square) values included in the board. +impl IntoIterator for Bitboard { + type IntoIter = BitboardIterator; + type Item = Square; + + fn into_iter(self) -> Self::IntoIter { + BitboardIterator(self.0) + } +} + /// Treat bitboard as a set of squares, shift each square's index left by the amount given. impl std::ops::Shl for Bitboard { type Output = Bitboard; @@ -155,6 +167,37 @@ mod test { use super::*; use crate::board::square::*; + #[test] + fn iter() { + assert_eq!(Bitboard::EMPTY.into_iter().collect::>(), Vec::new()); + assert_eq!( + Bitboard::RANKS[0].into_iter().collect::>(), + vec![ + Square::A1, + Square::B1, + Square::C1, + Square::D1, + Square::E1, + Square::F1, + Square::G1, + Square::H1, + ] + ); + assert_eq!( + Bitboard::FILES[0].into_iter().collect::>(), + vec![ + Square::A1, + Square::A2, + Square::A3, + Square::A4, + Square::A5, + Square::A6, + Square::A7, + Square::A8, + ] + ); + } + #[test] fn left_shift() { assert_eq!(Bitboard::RANKS[0] << 1, Bitboard::RANKS[1]);