aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/board.rs104
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);