diff options
-rw-r--r-- | src/attacks.rs | 49 | ||||
-rw-r--r-- | src/bitboard.rs | 4 | ||||
-rw-r--r-- | src/board.rs | 27 |
3 files changed, 51 insertions, 29 deletions
diff --git a/src/attacks.rs b/src/attacks.rs index 73f3d73..d5bc8a3 100644 --- a/src/attacks.rs +++ b/src/attacks.rs @@ -307,14 +307,21 @@ mod tests { use super::*; + static DEFAULT_OCCUPANCY: Bitboard = + 1 << Square::B7 as usize | + 1 << Square::B1 as usize | + 1 << Square::C2 as usize | + 1 << Square::F3 as usize; + #[test] fn test_pawn_attacks() { let attacks = Attacks::precompute_pawn_attacks(); let square = Square::E4 as usize; - let white_attacks = attacks[Color::White as usize][square]; + + print(white_attacks, "Pawn e4"); + assert_eq!(white_attacks, 1 << Square::D5 as usize | 1 << Square::F5 as usize); - print(white_attacks); assert_eq!(attacks[Color::White as usize][Square::H4 as usize], 1 << Square::G5 as usize); assert_eq!(attacks[Color::White as usize][Square::A4 as usize], 1 << Square::B5 as usize); @@ -337,6 +344,8 @@ mod tests { let attacks = Attacks::precompute_knight_attacks(); let e4_attacks = attacks[Square::E4 as usize]; + print(e4_attacks, "Knight e4"); + assert_ne!(e4_attacks & 1 << Square::G5 as usize, 0); assert_ne!(e4_attacks & 1 << Square::G3 as usize, 0); assert_ne!(e4_attacks & 1 << Square::C5 as usize, 0); @@ -352,12 +361,14 @@ mod tests { assert_eq!(pop_count(attacks[Square::G1 as usize]), 3); assert_eq!(pop_count(attacks[Square::H8 as usize]), 2); - print(e4_attacks); } #[test] fn test_king_attacks() { let attacks = Attacks::precompute_king_attacks(); + + print(attacks[Square::E4 as usize], "King e4"); + assert_eq!(pop_count(attacks[Square::E4 as usize]), 8); assert_eq!(pop_count(attacks[Square::A1 as usize]), 3); @@ -369,7 +380,6 @@ mod tests { assert_eq!(pop_count(attacks[Square::E8 as usize]), 5); assert_eq!(pop_count(attacks[Square::A4 as usize]), 5); assert_eq!(pop_count(attacks[Square::H4 as usize]), 5); - print(attacks[Square::E4 as usize]); } #[test] @@ -402,19 +412,17 @@ mod tests { attacks[5][square] | attacks[6][square] | attacks[7][square]; - print(bitboard); + print(bitboard, "Rays from e4"); } #[test] fn test_bishop_attacks() { let attacks = Attacks::new(); let square = Square::E4 as u8; - let occupancy = - 1 << Square::B7 as usize | - 1 << Square::B1 as usize | - 1 << Square::C2 as usize | - 1 << Square::F3 as usize; - let bb = attacks.bishop(occupancy, square); + let bb = attacks.bishop(DEFAULT_OCCUPANCY, square); + + print(DEFAULT_OCCUPANCY, "Occupancy"); + print(bb, "Bishop e4"); assert_ne!(bb & 1 << Square::C2 as u8, 0); assert_eq!(bb & 1 << Square::B1 as u8, 0); @@ -423,8 +431,6 @@ mod tests { assert_ne!(bb & 1 << Square::H7 as u8, 0); assert_ne!(bb & 1 << Square::B7 as u8, 0); assert_eq!(bb & 1 << Square::A8 as u8, 0); - - print(bb); } #[test] @@ -439,6 +445,9 @@ mod tests { 1 << Square::F3 as usize; let bb = attacks.rook(occupancy, square); + print(occupancy, "Occupancy"); + print(bb, "Rook e4"); + assert_ne!(bb & 1 << Square::E8 as u8, 0); assert_ne!(bb & 1 << Square::E7 as u8, 0); assert_ne!(bb & 1 << Square::E6 as u8, 0); @@ -449,22 +458,14 @@ mod tests { assert_ne!(bb & 1 << Square::A4 as u8, 0); assert_ne!(bb & 1 << Square::H4 as u8, 0); assert_eq!(bb & 1 << Square::E4 as u8, 0); - - print(bb); } #[test] fn test_queen_attacks() { let attacks = Attacks::new(); let square = Square::E4 as u8; - let occupancy = - 1 << Square::B7 as usize | - 1 << Square::B1 as usize | - 1 << Square::C2 as usize | - 1 << Square::E3 as usize | - 1 << Square::F3 as usize; - let bb = attacks.queen(occupancy, square); - print(occupancy); - print(bb); + let bb = attacks.queen(DEFAULT_OCCUPANCY, square); + print(DEFAULT_OCCUPANCY, "Occupancy"); + print(bb, "Queen e4"); } } diff --git a/src/bitboard.rs b/src/bitboard.rs index 1d6d0bc..6312dd8 100644 --- a/src/bitboard.rs +++ b/src/bitboard.rs @@ -4,8 +4,8 @@ pub type Bitboard = u64; /// Print bitboard on screen in the same way squares appear in memory /// (i.e the board is actually flipped along X) #[allow(dead_code)] -pub fn print(bb: Bitboard) { - println!(); +pub fn print(bb: Bitboard, title: &str) { + println!("\n {}", title); for rank in (0..8).rev() { print!("{}|", rank + 1); for file in 0..8 { diff --git a/src/board.rs b/src/board.rs index 241412e..b76356f 100644 --- a/src/board.rs +++ b/src/board.rs @@ -3,6 +3,9 @@ use crate::bitboard::Bitboard; #[derive(Debug)] pub struct Board { pub pieces: [Bitboard; 12], + + pub occupancy: Bitboard, + pub ply: u16, } @@ -80,7 +83,21 @@ impl Board { } } - Self { pieces } + let mut board = Self { pieces, occupancy: 0, ply: 0 }; + board.update_occupancy(); + board + } + + fn update_occupancy(&mut self) { + self.occupancy = 0; + // TODO: reduce + for piece in self.pieces { + self.occupancy |= piece; + } + } + + fn empty(&self) -> Bitboard { + !self.occupancy } pub fn print(&self) { @@ -130,7 +147,7 @@ pub enum Square { #[cfg(test)] mod tests { use super::*; - use crate::bitboard::{pop_count, bitscan}; + use crate::bitboard::{pop_count, bitscan, print}; #[test] fn test_square_enum() { @@ -144,6 +161,9 @@ mod tests { let fen = String::from("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); 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); @@ -161,6 +181,7 @@ mod tests { 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); - board.print(); + assert_eq!(pop_count(board.occupancy), 32); + assert_eq!(pop_count(board.empty()), 32); } } |