[board] Replace Builder's BTreeMap with a Mailbox
More efficient and easier to work with. :)
This commit is contained in:
		
							parent
							
								
									7c65232c35
								
							
						
					
					
						commit
						3a2ead2668
					
				
					 2 changed files with 25 additions and 20 deletions
				
			
		| 
						 | 
					@ -1,14 +1,13 @@
 | 
				
			||||||
// Eryn Wells <eryn@erynwells.me>
 | 
					// Eryn Wells <eryn@erynwells.me>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::{Board, Castle, EnPassant, Flags, PieceBitBoards};
 | 
					use crate::{piece_sets::Mailbox, Board, Castle, EnPassant, Flags, PieceSet};
 | 
				
			||||||
use chessfriend_core::{piece, Color, Piece, PlacedPiece, Rank, Shape, Square};
 | 
					use chessfriend_core::{piece, Color, PlacedPiece, Rank, Shape, Square};
 | 
				
			||||||
use std::collections::BTreeMap;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Clone)]
 | 
					#[derive(Clone)]
 | 
				
			||||||
pub struct Builder {
 | 
					pub struct Builder {
 | 
				
			||||||
    player_to_move: Color,
 | 
					    player_to_move: Color,
 | 
				
			||||||
    flags: Flags,
 | 
					    flags: Flags,
 | 
				
			||||||
    pieces: BTreeMap<Square, Piece>,
 | 
					    pieces: Mailbox,
 | 
				
			||||||
    kings: [Option<Square>; 2],
 | 
					    kings: [Option<Square>; 2],
 | 
				
			||||||
    en_passant: Option<EnPassant>,
 | 
					    en_passant: Option<EnPassant>,
 | 
				
			||||||
    ply_counter: u16,
 | 
					    ply_counter: u16,
 | 
				
			||||||
| 
						 | 
					@ -23,11 +22,7 @@ impl Builder {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[must_use]
 | 
					    #[must_use]
 | 
				
			||||||
    pub fn from_board(board: &Board) -> Self {
 | 
					    pub fn from_board(board: &Board) -> Self {
 | 
				
			||||||
        let pieces = board
 | 
					        let pieces = board.iter_all_pieces().collect::<Mailbox>();
 | 
				
			||||||
            .pieces(Color::White)
 | 
					 | 
				
			||||||
            .chain(board.pieces(Color::Black))
 | 
					 | 
				
			||||||
            .map(|placed_piece| (placed_piece.square(), *placed_piece.piece()))
 | 
					 | 
				
			||||||
            .collect::<BTreeMap<_, _>>();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let white_king = board.king_square(Color::White);
 | 
					        let white_king = board.king_square(Color::White);
 | 
				
			||||||
        let black_king = board.king_square(Color::Black);
 | 
					        let black_king = board.king_square(Color::Black);
 | 
				
			||||||
| 
						 | 
					@ -72,12 +67,12 @@ impl Builder {
 | 
				
			||||||
            let color_index: usize = color as usize;
 | 
					            let color_index: usize = color as usize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if let Some(king_square) = self.kings[color_index] {
 | 
					            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.kings[color_index] = Some(square);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.pieces.insert(square, *piece.piece());
 | 
					        self.pieces.set(piece.piece(), square);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self
 | 
					        self
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -108,7 +103,7 @@ impl Builder {
 | 
				
			||||||
                let parameters = castle.parameters(color);
 | 
					                let parameters = castle.parameters(color);
 | 
				
			||||||
                let has_rook_on_starting_square = self
 | 
					                let has_rook_on_starting_square = self
 | 
				
			||||||
                    .pieces
 | 
					                    .pieces
 | 
				
			||||||
                    .get(¶meters.rook_origin_square())
 | 
					                    .get(parameters.rook_origin_square())
 | 
				
			||||||
                    .is_some_and(|piece| piece.shape() == Shape::Rook);
 | 
					                    .is_some_and(|piece| piece.shape() == Shape::Rook);
 | 
				
			||||||
                let king_is_on_starting_square =
 | 
					                let king_is_on_starting_square =
 | 
				
			||||||
                    self.kings[color as usize] == Some(parameters.king_origin_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 white_king_square = Square::E1;
 | 
				
			||||||
        let black_king_square = Square::E8;
 | 
					        let black_king_square = Square::E8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let pieces = BTreeMap::from_iter([
 | 
					        let pieces = Mailbox::from_iter([
 | 
				
			||||||
            (white_king_square, piece!(White King)),
 | 
					            (white_king_square, piece!(White King)),
 | 
				
			||||||
            (black_king_square, piece!(Black King)),
 | 
					            (black_king_square, piece!(Black King)),
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,24 +4,34 @@ use chessfriend_core::{Piece, PlacedPiece, Square};
 | 
				
			||||||
use std::iter::FromIterator;
 | 
					use std::iter::FromIterator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
 | 
					#[derive(Clone, Debug, Eq, Hash, PartialEq)]
 | 
				
			||||||
pub(super) struct Mailbox([Option<Piece>; Square::NUM]);
 | 
					pub(crate) struct Mailbox([Option<Piece>; Square::NUM]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Mailbox {
 | 
					impl Mailbox {
 | 
				
			||||||
    pub(super) fn new() -> Self {
 | 
					    pub(crate) fn new() -> Self {
 | 
				
			||||||
        Self::default()
 | 
					        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]
 | 
					        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);
 | 
					        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;
 | 
					        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 {
 | 
					impl Default for Mailbox {
 | 
				
			||||||
| 
						 | 
					@ -40,7 +50,7 @@ impl FromIterator<PlacedPiece> for Mailbox {
 | 
				
			||||||
    fn from_iter<T: IntoIterator<Item = PlacedPiece>>(iter: T) -> Self {
 | 
					    fn from_iter<T: IntoIterator<Item = PlacedPiece>>(iter: T) -> Self {
 | 
				
			||||||
        let mut mailbox = Self::new();
 | 
					        let mut mailbox = Self::new();
 | 
				
			||||||
        for placed_piece in iter {
 | 
					        for placed_piece in iter {
 | 
				
			||||||
            mailbox.set(placed_piece.square(), placed_piece.piece());
 | 
					            mailbox.set(placed_piece.piece(), placed_piece.square());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mailbox
 | 
					        mailbox
 | 
				
			||||||
| 
						 | 
					@ -51,7 +61,7 @@ impl FromIterator<(Square, Piece)> for Mailbox {
 | 
				
			||||||
    fn from_iter<T: IntoIterator<Item = (Square, Piece)>>(iter: T) -> Self {
 | 
					    fn from_iter<T: IntoIterator<Item = (Square, Piece)>>(iter: T) -> Self {
 | 
				
			||||||
        let mut mailbox = Self::new();
 | 
					        let mut mailbox = Self::new();
 | 
				
			||||||
        for (square, piece) in iter {
 | 
					        for (square, piece) in iter {
 | 
				
			||||||
            mailbox.set(square, piece);
 | 
					            mailbox.set(piece, square);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mailbox
 | 
					        mailbox
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue