Add get_all_occupancies, is_attacked method and unit tests

This commit is contained in:
2024-06-03 21:59:36 +03:00
parent 7ccc1c404b
commit a6d6347270
2 changed files with 77 additions and 8 deletions

View File

@@ -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::*;

View File

@@ -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(())
}
}