// Eryn Wells use crate::bitboard::BitBoard; use crate::piece::{Color, Piece, PiecePlacementError, PieceShape}; use crate::square::Square; use std::fmt; mod color { const WHITE: u8 = 0; const BLACK: u8 = 1; } mod piece { const PAWN: u8 = 0; const KNIGHT: u8 = 1; const BISHOP: u8 = 2; const ROOK: u8 = 3; const QUEEN: u8 = 4; const KING: u8 = 5; } #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct Position { /// Composite bitboards for all the pieces of a particular color. pieces_per_color: [BitBoard; 2], /// Bitboards representing positions of particular piece types per color. pieces_per_type: [[BitBoard; 6]; 2], } impl Position { fn empty() -> Position { Position { pieces_per_color: [BitBoard::empty(), BitBoard::empty()], pieces_per_type: [ [ BitBoard::empty(), BitBoard::empty(), BitBoard::empty(), BitBoard::empty(), BitBoard::empty(), BitBoard::empty(), ], [ BitBoard::empty(), BitBoard::empty(), BitBoard::empty(), BitBoard::empty(), BitBoard::empty(), BitBoard::empty(), ], ], } } /// Return a starting position. fn starting() -> Position { let white_pieces = [ BitBoard::from_bit_field(0x00FF000000000000), BitBoard::from_bit_field(0x4200000000000000), BitBoard::from_bit_field(0x2400000000000000), BitBoard::from_bit_field(0x8100000000000000), BitBoard::from_bit_field(0x1000000000000000), BitBoard::from_bit_field(0x8000000000000000), ]; let black_pieces = [ BitBoard::from_bit_field(0xFF00), BitBoard::from_bit_field(0x0042), BitBoard::from_bit_field(0x0024), BitBoard::from_bit_field(0x0081), BitBoard::from_bit_field(0x0010), BitBoard::from_bit_field(0x0080), ]; Position { pieces_per_color: [ white_pieces.iter().fold(BitBoard::empty(), |a, b| a | b), black_pieces.iter().fold(BitBoard::empty(), |a, b| a | b), ], pieces_per_type: [white_pieces, black_pieces], } } fn place_piece(&mut self, piece: &Piece, square: &Square) -> Result<(), PiecePlacementError> { let mut bitboard = self.bitboard_for_piece_mut(piece); if bitboard.has_piece_at(&square) { return Err(PiecePlacementError::PieceExistsOnSquare); } bitboard.place_piece_at(&square); Ok(()) } fn bitboard_for_piece(&self, piece: &Piece) -> &BitBoard { let color_index: usize = match piece.color { Color::White => 0, Color::Black => 1, }; let piece_index: usize = match piece.piece { PieceShape::Pawn => 0, PieceShape::Knight => 1, PieceShape::Bishop => 2, PieceShape::Rook => 3, PieceShape::Queen => 4, PieceShape::King => 5, }; &self.pieces_per_type[color_index][piece_index] } fn bitboard_for_piece_mut(&mut self, piece: &Piece) -> &mut BitBoard { let color_index: usize = match piece.color { Color::White => 0, Color::Black => 1, }; let piece_index: usize = match piece.piece { PieceShape::Pawn => 0, PieceShape::Knight => 1, PieceShape::Bishop => 2, PieceShape::Rook => 3, PieceShape::Queen => 4, PieceShape::King => 5, }; &mut self.pieces_per_type[color_index][piece_index] } } impl fmt::Display for Position { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "abcdefg") #[cfg(test)] mod tests { use super::*; #[test] fn place_piece_at() { let mut position = Position::empty(); let piece = Piece::new(Color::White, PieceShape::Queen); let square = Square::from_algebraic_string("e4").expect("Unable to get e4 square"); position .place_piece(&piece, &square) .expect("Unable to place white queen on e4"); position .place_piece(&piece, &square) .expect_err("Placed white queen on e4 a second time?!"); println!("{:?}", position); } }