diff options
| -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); | 
