[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:
parent
51de32fa0a
commit
90e33d1202
3 changed files with 10 additions and 132 deletions
|
@ -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]
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>>()
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue