aboutsummaryrefslogtreecommitdiff
path: root/src/board.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/board.rs')
-rw-r--r--src/board.rs124
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();
+ }
+ }
}