[board] Replace Builder's BTreeMap with a Mailbox

More efficient and easier to work with. :)
This commit is contained in:
Eryn Wells 2024-07-13 08:08:12 -07:00
parent 7c65232c35
commit 3a2ead2668
2 changed files with 25 additions and 20 deletions

View file

@ -1,14 +1,13 @@
// Eryn Wells <eryn@erynwells.me>
use crate::{Board, Castle, EnPassant, Flags, PieceBitBoards};
use chessfriend_core::{piece, Color, Piece, PlacedPiece, Rank, Shape, Square};
use std::collections::BTreeMap;
use crate::{piece_sets::Mailbox, Board, Castle, EnPassant, Flags, PieceSet};
use chessfriend_core::{piece, Color, PlacedPiece, Rank, Shape, Square};
#[derive(Clone)]
pub struct Builder {
player_to_move: Color,
flags: Flags,
pieces: BTreeMap<Square, Piece>,
pieces: Mailbox,
kings: [Option<Square>; 2],
en_passant: Option<EnPassant>,
ply_counter: u16,
@ -23,11 +22,7 @@ impl Builder {
#[must_use]
pub fn from_board(board: &Board) -> Self {
let pieces = board
.pieces(Color::White)
.chain(board.pieces(Color::Black))
.map(|placed_piece| (placed_piece.square(), *placed_piece.piece()))
.collect::<BTreeMap<_, _>>();
let pieces = board.iter_all_pieces().collect::<Mailbox>();
let white_king = board.king_square(Color::White);
let black_king = board.king_square(Color::Black);
@ -72,12 +67,12 @@ impl Builder {
let color_index: usize = color as usize;
if let Some(king_square) = self.kings[color_index] {
self.pieces.remove(&king_square);
self.pieces.remove(king_square);
}
self.kings[color_index] = Some(square);
}
self.pieces.insert(square, *piece.piece());
self.pieces.set(piece.piece(), square);
self
}
@ -108,7 +103,7 @@ impl Builder {
let parameters = castle.parameters(color);
let has_rook_on_starting_square = self
.pieces
.get(&parameters.rook_origin_square())
.get(parameters.rook_origin_square())
.is_some_and(|piece| piece.shape() == Shape::Rook);
let king_is_on_starting_square =
self.kings[color as usize] == Some(parameters.king_origin_square());
@ -148,7 +143,7 @@ impl Default for Builder {
let white_king_square = Square::E1;
let black_king_square = Square::E8;
let pieces = BTreeMap::from_iter([
let pieces = Mailbox::from_iter([
(white_king_square, piece!(White King)),
(black_king_square, piece!(Black King)),
]);

View file

@ -4,24 +4,34 @@ use chessfriend_core::{Piece, PlacedPiece, Square};
use std::iter::FromIterator;
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub(super) struct Mailbox([Option<Piece>; Square::NUM]);
pub(crate) struct Mailbox([Option<Piece>; Square::NUM]);
impl Mailbox {
pub(super) fn new() -> Self {
pub(crate) fn new() -> Self {
Self::default()
}
pub(super) fn get(&self, square: Square) -> Option<Piece> {
pub(crate) fn get(&self, square: Square) -> Option<Piece> {
self.0[square as usize]
}
pub(super) fn set(&mut self, square: Square, piece: Piece) {
pub(crate) fn set(&mut self, piece: Piece, square: Square) {
self.0[square as usize] = Some(piece);
}
pub(super) fn clear(&mut self, square: Square) {
pub(crate) fn remove(&mut self, square: Square) {
self.0[square as usize] = None;
}
pub(crate) fn iter(&self) -> impl Iterator<Item = PlacedPiece> {
self.0
.into_iter()
.flatten() // Remove the Nones
.zip(0u8..) // Enumerate with u8 instead of usize
.map(|(piece, index)| {
PlacedPiece::new(piece, unsafe { Square::from_index_unchecked(index) })
})
}
}
impl Default for Mailbox {
@ -40,7 +50,7 @@ impl FromIterator<PlacedPiece> for Mailbox {
fn from_iter<T: IntoIterator<Item = PlacedPiece>>(iter: T) -> Self {
let mut mailbox = Self::new();
for placed_piece in iter {
mailbox.set(placed_piece.square(), placed_piece.piece());
mailbox.set(placed_piece.piece(), placed_piece.square());
}
mailbox
@ -51,7 +61,7 @@ impl FromIterator<(Square, Piece)> for Mailbox {
fn from_iter<T: IntoIterator<Item = (Square, Piece)>>(iter: T) -> Self {
let mut mailbox = Self::new();
for (square, piece) in iter {
mailbox.set(square, piece);
mailbox.set(piece, square);
}
mailbox