52 lines
1.5 KiB
Rust
52 lines
1.5 KiB
Rust
use super::Bitboard;
|
|
|
|
/// Iterator over a [Bitboard] mask, which yields all potential subsets of the given board.
|
|
/// In other words, for each square that belongs to the mask, this will yield all sets that do
|
|
/// contain the square, and all sets that do not.
|
|
pub struct BitboardPowerSetIterator {
|
|
/// The mask.
|
|
mask: Bitboard,
|
|
/// The "index" of the next blocker set that should be generated.
|
|
current: usize,
|
|
/// The number of blocker sets that should be generated by [BlockerIterator], i.e: 2^n with n
|
|
/// the number of squares belonging to `mask`.
|
|
total: usize,
|
|
}
|
|
|
|
impl BitboardPowerSetIterator {
|
|
pub fn new(mask: Bitboard) -> Self {
|
|
Self {
|
|
mask,
|
|
current: 0,
|
|
total: 1 << mask.count(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Iterator for BitboardPowerSetIterator {
|
|
type Item = Bitboard;
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
if self.current >= self.total {
|
|
None
|
|
} else {
|
|
let blockers = (0..)
|
|
.into_iter()
|
|
.zip(self.mask.into_iter())
|
|
.filter(|(index, _)| self.current & (1 << index) != 0)
|
|
.map(|(_, board)| board)
|
|
.fold(Bitboard::EMPTY, |lhs, rhs| lhs | rhs);
|
|
self.current += 1;
|
|
Some(blockers)
|
|
}
|
|
}
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
(self.total, Some(self.total))
|
|
}
|
|
}
|
|
|
|
impl ExactSizeIterator for BitboardPowerSetIterator {}
|
|
|
|
impl std::iter::FusedIterator for BitboardPowerSetIterator {}
|