diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/board.rs | 124 |
1 files changed, 104 insertions, 20 deletions
diff --git a/src/board.rs b/src/board.rs index a078fff..18896bf 100644 --- a/src/board.rs +++ b/src/board.rs @@ -1,4 +1,4 @@ -use crate::bitboard::Bitboard; +use crate::{bitboard::{Bitboard, serialize_bitboard}, moves::Move, attacks::Attacks}; #[derive(Debug)] pub struct Board { @@ -6,32 +6,50 @@ pub struct Board { pub occupancy: Bitboard, pub ply: u16, + + attacks: Attacks, } pub enum PieceTypes { Pawn, - PawnBlack, Knight, - KnightBlack, Bishop, - BishopBlack, Rook, - RookBlack, Queen, - QueenBlack, King, + PawnBlack, + KnightBlack, + BishopBlack, + RookBlack, + QueenBlack, 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] = [ - "♟︎", "♙", - "♞", "♘", - "♝", "♗", - "♜", "♖", - "♛", "♕", - "♚", "♔", + "♟︎", "♞", "♝", "♜", "♛", "♚", + "♙", "♘", "♗", "♖", "♕", "♔", ]; @@ -83,7 +101,7 @@ impl Board { } } - let mut board = Self { pieces, occupancy: 0, ply: 0 }; + let mut board = Self { pieces, occupancy: 0, ply: 0, attacks: Attacks::new() }; board.update_occupancy(); board } @@ -102,10 +120,8 @@ impl Board { fn pieces_by_color(&self, color: Color) -> [Bitboard; 6] { let mut pieces = [0; 6]; - for (piece_type, piece) in self.pieces.iter().enumerate() { - if piece_type % 2 == color as usize { - pieces[piece_type / 2] = *piece; - } + for piece_type in 0..6 { + pieces[piece_type] = self.pieces[piece_type + 6 * color as usize]; } pieces } @@ -126,10 +142,10 @@ impl Board { let index = rank * 8 + file; let position: Bitboard = 1 << index; let mut found = false; - for (piec_type, piece_bitboard) in self.pieces.iter().enumerate() { + for (piece_type, piece_bitboard) in self.pieces.iter().enumerate() { if (piece_bitboard & position) > 0 { found = true; - print!("{} ", PIECE_CHARS[piec_type]); + print!("{} ", PIECE_CHARS[piece_type]); } } if !found { @@ -140,10 +156,63 @@ impl Board { } println!(" a b c d e f g h"); } + + 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(); + for (piece_type, piece) in self.pieces_by_color(color).iter().enumerate() { + match PieceTypes::from_u32(piece_type as u32) { + PieceTypes::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 => { + 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 => { + 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 => { + 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 => { + 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 => { + for from in serialize_bitboard(*piece) { + for to in serialize_bitboard(self.attacks.queen(self.occupancy, from) & available_targets) { + moves.push(Move { from, to }); + }; + } + } + _ => todo!("Incorrect piece type") + } + } + moves + } } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq)] pub enum Color { White, Black, @@ -205,4 +274,19 @@ mod tests { assert_eq!(pop_count(board.color_occupancy(Color::White)), 16); assert_eq!(pop_count(board.color_occupancy(Color::Black)), 16); } + + #[test] + fn test_generate_moves_starting_position() { + let fen = String::from("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + let board = Board::from_FEN(fen); + let moves = board.generate_moves(Color::White); + let black_moves = board.generate_moves(Color::Black); + + assert_eq!(moves.len(), 20); + assert_eq!(black_moves.len(), 20); + + for mov in moves { + mov.print(); + } + } } |