[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::{
|
use crate::{
|
||||||
display::DiagramFormatter, piece_sets::PlacePieceError, Castle, EnPassant, Flags, PieceSet,
|
display::DiagramFormatter, piece_sets::PlacePieceError, Castle, EnPassant, Flags, PieceSet,
|
||||||
Pieces,
|
|
||||||
};
|
};
|
||||||
use chessfriend_bitboard::BitBoard;
|
use chessfriend_bitboard::BitBoard;
|
||||||
use chessfriend_core::{Color, Piece, PlacedPiece, Shape, Square};
|
use chessfriend_core::{Color, Piece, PlacedPiece, Shape, Square};
|
||||||
|
use std::iter::Iterator;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq)]
|
#[derive(Clone, Debug, Eq)]
|
||||||
pub struct Board {
|
pub struct Board {
|
||||||
|
@ -154,8 +154,15 @@ impl Board {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn pieces(&self, color: Color) -> Pieces {
|
pub fn iter_all_pieces(&self) -> impl Iterator<Item = PlacedPiece> + '_ {
|
||||||
Pieces::new(self, color)
|
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]
|
#[must_use]
|
||||||
|
|
|
@ -10,7 +10,6 @@ mod display;
|
||||||
mod flags;
|
mod flags;
|
||||||
mod macros;
|
mod macros;
|
||||||
mod piece_sets;
|
mod piece_sets;
|
||||||
mod pieces;
|
|
||||||
|
|
||||||
pub use board::Board;
|
pub use board::Board;
|
||||||
pub use builder::Builder;
|
pub use builder::Builder;
|
||||||
|
@ -18,5 +17,4 @@ pub use builder::Builder;
|
||||||
use castle::Castle;
|
use castle::Castle;
|
||||||
use en_passant::EnPassant;
|
use en_passant::EnPassant;
|
||||||
use flags::Flags;
|
use flags::Flags;
|
||||||
use pieces::Pieces;
|
|
||||||
use piece_sets::PieceSet;
|
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