Add get_all_occupancies, is_attacked method and unit tests
This commit is contained in:
@@ -370,6 +370,14 @@ pub fn init_rook_attacks() {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_attacks() {
|
||||
init_pawn_attacks();
|
||||
init_knight_attacks();
|
||||
init_king_attacks();
|
||||
init_bishop_attacks();
|
||||
init_rook_attacks()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
77
src/board.rs
77
src/board.rs
@@ -1,6 +1,11 @@
|
||||
use std::fmt;
|
||||
use u64 as Bitboard;
|
||||
|
||||
use crate::attack::{
|
||||
get_bishop_attacks, get_king_attacks, get_knight_attacks, get_pawn_attacks, get_queen_attacks,
|
||||
get_rook_attacks,
|
||||
};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Board {
|
||||
white_pieces: [Piece; 6],
|
||||
@@ -12,17 +17,17 @@ impl Board {
|
||||
Self {
|
||||
white_pieces: [
|
||||
Piece::new(0xff00, Kind::Pawn, Color::White),
|
||||
Piece::new(0x81, Kind::Rook, Color::White),
|
||||
Piece::new(0x42, Kind::Knight, Color::White),
|
||||
Piece::new(0x24, Kind::Bishop, Color::White),
|
||||
Piece::new(0x81, Kind::Rook, Color::White),
|
||||
Piece::new(0x8, Kind::Queen, Color::White),
|
||||
Piece::new(0x10, Kind::King, Color::White),
|
||||
],
|
||||
black_pieces: [
|
||||
Piece::new(0xff000000000000, Kind::Pawn, Color::Black),
|
||||
Piece::new(0x8100000000000000, Kind::Rook, Color::Black),
|
||||
Piece::new(0x4200000000000000, Kind::Knight, Color::Black),
|
||||
Piece::new(0x2400000000000000, Kind::Bishop, Color::Black),
|
||||
Piece::new(0x8100000000000000, Kind::Rook, Color::Black),
|
||||
Piece::new(0x800000000000000, Kind::Queen, Color::Black),
|
||||
Piece::new(0x1000000000000000, Kind::King, Color::Black),
|
||||
],
|
||||
@@ -33,17 +38,17 @@ impl Board {
|
||||
Self {
|
||||
white_pieces: [
|
||||
Piece::new(0x0, Kind::Pawn, Color::White),
|
||||
Piece::new(0x0, Kind::Rook, Color::White),
|
||||
Piece::new(0x0, Kind::Knight, Color::White),
|
||||
Piece::new(0x0, Kind::Bishop, Color::White),
|
||||
Piece::new(0x0, Kind::Rook, Color::White),
|
||||
Piece::new(0x0, Kind::Queen, Color::White),
|
||||
Piece::new(0x0, Kind::King, Color::White),
|
||||
],
|
||||
black_pieces: [
|
||||
Piece::new(0x0, Kind::Pawn, Color::Black),
|
||||
Piece::new(0x0, Kind::Rook, Color::Black),
|
||||
Piece::new(0x0, Kind::Knight, Color::Black),
|
||||
Piece::new(0x0, Kind::Bishop, Color::Black),
|
||||
Piece::new(0x0, Kind::Rook, Color::Black),
|
||||
Piece::new(0x0, Kind::Queen, Color::Black),
|
||||
Piece::new(0x0, Kind::King, Color::Black),
|
||||
],
|
||||
@@ -52,10 +57,32 @@ impl Board {
|
||||
|
||||
pub fn set_piece(&mut self, piece: Piece) {
|
||||
match piece.color {
|
||||
Color::Black => self.black_pieces[piece.kind as usize].bitboard |= piece.bitboard,
|
||||
Color::White => self.white_pieces[piece.kind as usize].bitboard |= piece.bitboard,
|
||||
Color::Black => self.black_pieces[piece.kind.idx()].bitboard |= piece.bitboard,
|
||||
Color::White => self.white_pieces[piece.kind.idx()].bitboard |= piece.bitboard,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn get_all_occupancies(&self) -> Bitboard {
|
||||
let white_blockers = self.white_pieces.iter().fold(0, |acc, p| p.bitboard | acc);
|
||||
let black_blockers = self.black_pieces.iter().fold(0, |acc, p| p.bitboard | acc);
|
||||
|
||||
white_blockers | black_blockers
|
||||
}
|
||||
|
||||
pub fn is_attacked(&self, sq: usize, opponent_color: Color) -> bool {
|
||||
let all_occupancies = self.get_all_occupancies();
|
||||
let enemy = match opponent_color {
|
||||
Color::Black => &self.black_pieces,
|
||||
Color::White => &self.white_pieces,
|
||||
};
|
||||
|
||||
enemy[Kind::Pawn.idx()].bitboard & get_pawn_attacks(sq, opponent_color) != 0
|
||||
|| enemy[Kind::Knight.idx()].bitboard & get_knight_attacks(sq) != 0
|
||||
|| enemy[Kind::Bishop.idx()].bitboard & get_bishop_attacks(all_occupancies, sq) != 0
|
||||
|| enemy[Kind::Rook.idx()].bitboard & get_rook_attacks(all_occupancies, sq) != 0
|
||||
|| enemy[Kind::Queen.idx()].bitboard & get_queen_attacks(all_occupancies, sq) != 0
|
||||
|| enemy[Kind::King.idx()].bitboard & get_king_attacks(sq) != 0
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Board {
|
||||
@@ -116,18 +143,52 @@ impl fmt::Display for Piece {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
pub enum Kind {
|
||||
Pawn,
|
||||
Rook,
|
||||
Knight,
|
||||
Bishop,
|
||||
Rook,
|
||||
Queen,
|
||||
King,
|
||||
}
|
||||
|
||||
impl Kind {
|
||||
fn idx(&self) -> usize {
|
||||
*self as usize
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum Color {
|
||||
White,
|
||||
Black,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{attack::init_attacks, fen::from_fen};
|
||||
|
||||
use super::*;
|
||||
|
||||
const FEN_EXAMPLE: [&str; 1] = [
|
||||
"8/6P1/4n2b/1p6/1Kp5/6n1/4b3/1k6 w - - 0 1",
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn test_get_all_occupancies() -> Result<(), String> {
|
||||
let new_game = from_fen(FEN_EXAMPLE[0])?;
|
||||
assert_eq!(new_game.board.get_all_occupancies(), 0x40900206401002);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_attacked() -> Result<(), String> {
|
||||
let new_game = from_fen(FEN_EXAMPLE[0])?;
|
||||
init_attacks();
|
||||
assert!(new_game.board.is_attacked(54, Color::Black));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user