[board] Replace Pieces iterator with Mailbox::iter()

Mailbox can use a standard iterator because it's just a slice. So nice!
This commit is contained in:
Eryn Wells 2024-07-13 11:51:52 -07:00
parent 51de32fa0a
commit 90e33d1202
3 changed files with 10 additions and 132 deletions

View file

@ -2,10 +2,10 @@
use crate::{
display::DiagramFormatter, piece_sets::PlacePieceError, Castle, EnPassant, Flags, PieceSet,
Pieces,
};
use chessfriend_bitboard::BitBoard;
use chessfriend_core::{Color, Piece, PlacedPiece, Shape, Square};
use std::iter::Iterator;
#[derive(Clone, Debug, Eq)]
pub struct Board {
@ -154,8 +154,15 @@ impl Board {
}
#[must_use]
pub fn pieces(&self, color: Color) -> Pieces {
Pieces::new(self, color)
pub fn iter_all_pieces(&self) -> impl Iterator<Item = PlacedPiece> + '_ {
self.pieces.iter()
}
#[must_use]
pub fn iter_pieces_of_color(&self, color: Color) -> impl Iterator<Item = PlacedPiece> + '_ {
self.pieces
.iter()
.filter(move |piece| piece.color() == color)
}
#[must_use]

View file

@ -10,7 +10,6 @@ mod display;
mod flags;
mod macros;
mod piece_sets;
mod pieces;
pub use board::Board;
pub use builder::Builder;
@ -18,5 +17,4 @@ pub use builder::Builder;
use castle::Castle;
use en_passant::EnPassant;
use flags::Flags;
use pieces::Pieces;
use piece_sets::PieceSet;

View file

@ -1,127 +0,0 @@
// Eryn Wells <eryn@erynwells.me>
use super::Board;
use chessfriend_bitboard::BitBoard;
use chessfriend_core::{Color, Piece, PlacedPiece, Shape, Square};
pub struct Pieces<'a> {
color: Color,
board: &'a Board,
current_shape: Option<Shape>,
shape_iterator: Box<dyn Iterator<Item = &'static Shape>>,
square_iterator: Option<Box<dyn Iterator<Item = Square>>>,
}
impl<'a> Pieces<'a> {
pub(crate) fn new(board: &Board, color: Color) -> Pieces {
Pieces {
color,
board,
current_shape: None,
shape_iterator: Box::new(Shape::iter()),
square_iterator: None,
}
}
}
impl<'a> Iterator for Pieces<'a> {
type Item = PlacedPiece;
fn next(&mut self) -> Option<Self::Item> {
if let Some(square_iterator) = &mut self.square_iterator {
if let (Some(square), Some(shape)) = (square_iterator.next(), self.current_shape) {
return Some(PlacedPiece::new(Piece::new(self.color, shape), square));
}
}
let mut current_shape: Option<Shape> = None;
let mut next_nonempty_bitboard: Option<&BitBoard> = None;
for shape in self.shape_iterator.by_ref() {
let piece = Piece::new(self.color, *shape);
let bitboard = self.board.bitboard_for_piece(piece);
if bitboard.is_empty() {
continue;
}
next_nonempty_bitboard = Some(bitboard);
current_shape = Some(*shape);
break;
}
if let (Some(bitboard), Some(shape)) = (next_nonempty_bitboard, current_shape) {
let mut square_iterator = bitboard.occupied_squares();
let mut next_placed_piece: Option<PlacedPiece> = None;
if let Some(square) = square_iterator.next() {
next_placed_piece = Some(PlacedPiece::new(Piece::new(self.color, shape), square));
}
self.square_iterator = Some(Box::new(square_iterator));
self.current_shape = Some(shape);
return next_placed_piece;
}
None
}
}
#[cfg(test)]
mod tests {
use crate::{test_board, Board, Builder};
use chessfriend_core::{piece, Color};
use std::collections::HashSet;
#[test]
fn empty() {
let board = Board::empty();
let mut pieces = board.pieces(Color::White);
assert_eq!(pieces.next(), None);
}
#[test]
fn one() {
let pos = Builder::new()
.place_piece(piece!(White Queen on E4))
.build();
println!("{:#?}", &pos);
let mut pieces = pos.pieces(Color::White);
assert_eq!(pieces.next(), Some(piece!(White Queen on E4)));
assert_eq!(pieces.next(), Some(piece!(White King on E1)));
assert_eq!(pieces.next(), None);
}
#[test]
fn multiple_pieces() {
let board = test_board![
White Queen on E4,
White King on A1,
White Pawn on B2,
White Pawn on C2,
];
let expected_placed_pieces = HashSet::from([
piece!(White Queen on E4),
piece!(White King on A1),
piece!(White Pawn on B2),
piece!(White Pawn on C2),
]);
let placed_pieces = HashSet::from_iter(board.pieces(Color::White));
assert_eq!(
placed_pieces,
expected_placed_pieces,
"{:#?}",
placed_pieces
.symmetric_difference(&expected_placed_pieces)
.into_iter()
.map(|pp| format!("{}", pp))
.collect::<Vec<String>>()
);
}
}