diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/board.rs | 104 |
1 files changed, 45 insertions, 59 deletions
diff --git a/src/board.rs b/src/board.rs index 18896bf..2047483 100644 --- a/src/board.rs +++ b/src/board.rs @@ -11,7 +11,10 @@ pub struct Board { } -pub enum PieceTypes { +#[derive(Debug, num_enum::FromPrimitive)] +#[repr(usize)] +pub enum PieceType { + #[default] Pawn, Knight, Bishop, @@ -26,27 +29,6 @@ pub enum PieceTypes { KingBlack, } -impl PieceTypes { - fn from_u32(value: u32) -> PieceTypes { - match value { - 0 => PieceTypes::Pawn, - 1 => PieceTypes::Knight, - 2 => PieceTypes::Bishop, - 3 => PieceTypes::Rook, - 4 => PieceTypes::Queen, - 5 => PieceTypes::King, - 6 => PieceTypes::Pawn, - 7 => PieceTypes::Knight, - 8 => PieceTypes::Bishop, - 9 => PieceTypes::Rook, - 10 => PieceTypes::Queen, - 11 => PieceTypes::King, - _ => todo!(), - } - } -} - - const PIECE_CHARS: [&str; 12] = [ "♟︎", "♞", "♝", "♜", "♛", "♚", "♙", "♘", "♗", "♖", "♕", "♔", @@ -76,18 +58,18 @@ impl Board { } } else { match character { - 'P' => pieces[PieceTypes::Pawn as usize] |= position, - 'N' => pieces[PieceTypes::Knight as usize] |= position, - 'B' => pieces[PieceTypes::Bishop as usize] |= position, - 'R' => pieces[PieceTypes::Rook as usize] |= position, - 'Q' => pieces[PieceTypes::Queen as usize] |= position, - 'K' => pieces[PieceTypes::King as usize] |= position, - 'p' => pieces[PieceTypes::PawnBlack as usize] |= position, - 'n' => pieces[PieceTypes::KnightBlack as usize] |= position, - 'b' => pieces[PieceTypes::BishopBlack as usize] |= position, - 'r' => pieces[PieceTypes::RookBlack as usize] |= position, - 'q' => pieces[PieceTypes::QueenBlack as usize] |= position, - 'k' => pieces[PieceTypes::KingBlack as usize] |= position, + 'P' => pieces[PieceType::Pawn as usize] |= position, + 'N' => pieces[PieceType::Knight as usize] |= position, + 'B' => pieces[PieceType::Bishop as usize] |= position, + 'R' => pieces[PieceType::Rook as usize] |= position, + 'Q' => pieces[PieceType::Queen as usize] |= position, + 'K' => pieces[PieceType::King as usize] |= position, + 'p' => pieces[PieceType::PawnBlack as usize] |= position, + 'n' => pieces[PieceType::KnightBlack as usize] |= position, + 'b' => pieces[PieceType::BishopBlack as usize] |= position, + 'r' => pieces[PieceType::RookBlack as usize] |= position, + 'q' => pieces[PieceType::QueenBlack as usize] |= position, + 'k' => pieces[PieceType::KingBlack as usize] |= position, '/' => { rank -= 1; file = -1; // So it becomes 0 @@ -159,45 +141,45 @@ impl Board { pub fn generate_moves(&self, color: Color) -> Vec<Move> { let mut moves = Vec::with_capacity(1024); - let available_targets = self.color_occupancy(if color == Color::White { Color::Black } else { Color::White }) | self.empty(); + let available_targets = self.color_occupancy(Color::from(1 - color as u8)) | self.empty(); for (piece_type, piece) in self.pieces_by_color(color).iter().enumerate() { - match PieceTypes::from_u32(piece_type as u32) { - PieceTypes::Pawn => { + match PieceType::from(piece_type) { + PieceType::Pawn => { for from in serialize_bitboard(*piece) { for to in serialize_bitboard(self.attacks.pawn_pushes[color as usize][from as usize] & available_targets) { moves.push(Move { from, to }); }; } } - PieceTypes::King => { + PieceType::King => { for from in serialize_bitboard(*piece) { for to in serialize_bitboard(self.attacks.king[from as usize] & available_targets) { moves.push(Move { from, to }); }; } } - PieceTypes::Knight => { + PieceType::Knight => { for from in serialize_bitboard(*piece) { for to in serialize_bitboard(self.attacks.knight[from as usize] & available_targets) { moves.push(Move { from, to }); }; } } - PieceTypes::Bishop => { + PieceType::Bishop => { for from in serialize_bitboard(*piece) { for to in serialize_bitboard(self.attacks.bishop(self.occupancy, from) & available_targets) { moves.push(Move { from, to }); }; } } - PieceTypes::Rook => { + PieceType::Rook => { for from in serialize_bitboard(*piece) { for to in serialize_bitboard(self.attacks.rook(self.occupancy, from) & available_targets) { moves.push(Move { from, to }); }; } } - PieceTypes::Queen => { + PieceType::Queen => { for from in serialize_bitboard(*piece) { for to in serialize_bitboard(self.attacks.queen(self.occupancy, from) & available_targets) { moves.push(Move { from, to }); @@ -212,8 +194,10 @@ impl Board { } -#[derive(Clone, Copy, PartialEq)] +#[derive(Clone, Copy, PartialEq, num_enum::FromPrimitive)] +#[repr(u8)] pub enum Color { + #[default] White, Black, } @@ -237,6 +221,8 @@ mod tests { use super::*; use crate::bitboard::{pop_count, bitscan, print}; + const DEFAULT_FEN: &str = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"; + #[test] fn test_square_enum() { assert_eq!(Square::A1 as u8, 0); @@ -246,28 +232,28 @@ mod tests { #[test] fn test_from_fen() { - let fen = String::from("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + let fen = String::from(DEFAULT_FEN); let board = Board::from_FEN(fen); board.print(); print(board.empty(), "Empty squares"); - assert_eq!(pop_count(board.pieces[PieceTypes::Pawn as usize]), 8); - assert_eq!(pop_count(board.pieces[PieceTypes::Knight as usize]), 2); - assert_eq!(pop_count(board.pieces[PieceTypes::Bishop as usize]), 2); - assert_eq!(pop_count(board.pieces[PieceTypes::Rook as usize]), 2); - assert_eq!(pop_count(board.pieces[PieceTypes::Queen as usize]), 1); - assert_eq!(pop_count(board.pieces[PieceTypes::King as usize]), 1); + assert_eq!(pop_count(board.pieces[PieceType::Pawn as usize]), 8); + assert_eq!(pop_count(board.pieces[PieceType::Knight as usize]), 2); + assert_eq!(pop_count(board.pieces[PieceType::Bishop as usize]), 2); + assert_eq!(pop_count(board.pieces[PieceType::Rook as usize]), 2); + assert_eq!(pop_count(board.pieces[PieceType::Queen as usize]), 1); + assert_eq!(pop_count(board.pieces[PieceType::King as usize]), 1); - assert_eq!(pop_count(board.pieces[PieceTypes::PawnBlack as usize]), 8); - assert_eq!(pop_count(board.pieces[PieceTypes::KnightBlack as usize]), 2); - assert_eq!(pop_count(board.pieces[PieceTypes::BishopBlack as usize]), 2); - assert_eq!(pop_count(board.pieces[PieceTypes::RookBlack as usize]), 2); - assert_eq!(pop_count(board.pieces[PieceTypes::QueenBlack as usize]), 1); - assert_eq!(pop_count(board.pieces[PieceTypes::KingBlack as usize]), 1); + assert_eq!(pop_count(board.pieces[PieceType::PawnBlack as usize]), 8); + assert_eq!(pop_count(board.pieces[PieceType::KnightBlack as usize]), 2); + assert_eq!(pop_count(board.pieces[PieceType::BishopBlack as usize]), 2); + assert_eq!(pop_count(board.pieces[PieceType::RookBlack as usize]), 2); + assert_eq!(pop_count(board.pieces[PieceType::QueenBlack as usize]), 1); + assert_eq!(pop_count(board.pieces[PieceType::KingBlack as usize]), 1); - assert_eq!(bitscan(board.pieces[PieceTypes::King as usize]), Square::E1 as u8); - assert_eq!(bitscan(board.pieces[PieceTypes::QueenBlack as usize]), Square::D8 as u8); + assert_eq!(bitscan(board.pieces[PieceType::King as usize]), Square::E1 as u8); + assert_eq!(bitscan(board.pieces[PieceType::QueenBlack as usize]), Square::D8 as u8); assert_eq!(pop_count(board.occupancy), 32); assert_eq!(pop_count(board.empty()), 32); @@ -277,7 +263,7 @@ mod tests { #[test] fn test_generate_moves_starting_position() { - let fen = String::from("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + let fen = String::from(DEFAULT_FEN); let board = Board::from_FEN(fen); let moves = board.generate_moves(Color::White); let black_moves = board.generate_moves(Color::Black); |