Reduce bitboards from 12 to 8, add color info in mailbox representation
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
use strum_macros::EnumIter;
|
||||
use u64 as Bitboard;
|
||||
|
||||
use crate::board::bitboard::{have_common_bit, lsb, square_to_bitboard};
|
||||
@@ -14,62 +15,42 @@ use crate::movegen::r#move::{Move, MoveType, Promote};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Board {
|
||||
pub white_pieces: [Piece; 6],
|
||||
pub black_pieces: [Piece; 6],
|
||||
pub pieces: [Bitboard; 6],
|
||||
pub color: [Bitboard; 2],
|
||||
|
||||
pub state: State,
|
||||
}
|
||||
|
||||
impl Board {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
white_pieces: [
|
||||
Piece::new(0xff00, PieceType::Pawn, Color::White),
|
||||
Piece::new(0x42, PieceType::Knight, Color::White),
|
||||
Piece::new(0x24, PieceType::Bishop, Color::White),
|
||||
Piece::new(0x81, PieceType::Rook, Color::White),
|
||||
Piece::new(0x8, PieceType::Queen, Color::White),
|
||||
Piece::new(0x10, PieceType::King, Color::White),
|
||||
],
|
||||
black_pieces: [
|
||||
Piece::new(0xff000000000000, PieceType::Pawn, Color::Black),
|
||||
Piece::new(0x4200000000000000, PieceType::Knight, Color::Black),
|
||||
Piece::new(0x2400000000000000, PieceType::Bishop, Color::Black),
|
||||
Piece::new(0x8100000000000000, PieceType::Rook, Color::Black),
|
||||
Piece::new(0x800000000000000, PieceType::Queen, Color::Black),
|
||||
Piece::new(0x1000000000000000, PieceType::King, Color::Black),
|
||||
pieces: [
|
||||
0xff00000000ff00,
|
||||
0x4200000000000042,
|
||||
0x2400000000000024,
|
||||
0x8100000000000081,
|
||||
0x800000000000008,
|
||||
0x1000000000000010,
|
||||
],
|
||||
color: [0xffff, 0xffff000000000000],
|
||||
state: State::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn empty_board() -> Self {
|
||||
Self {
|
||||
white_pieces: [
|
||||
Piece::new(0x0, PieceType::Pawn, Color::White),
|
||||
Piece::new(0x0, PieceType::Knight, Color::White),
|
||||
Piece::new(0x0, PieceType::Bishop, Color::White),
|
||||
Piece::new(0x0, PieceType::Rook, Color::White),
|
||||
Piece::new(0x0, PieceType::Queen, Color::White),
|
||||
Piece::new(0x0, PieceType::King, Color::White),
|
||||
],
|
||||
black_pieces: [
|
||||
Piece::new(0x0, PieceType::Pawn, Color::Black),
|
||||
Piece::new(0x0, PieceType::Knight, Color::Black),
|
||||
Piece::new(0x0, PieceType::Bishop, Color::Black),
|
||||
Piece::new(0x0, PieceType::Rook, Color::Black),
|
||||
Piece::new(0x0, PieceType::Queen, Color::Black),
|
||||
Piece::new(0x0, PieceType::King, Color::Black),
|
||||
],
|
||||
pieces: [0x0, 0x0, 0x0, 0x0, 0x0, 0x0],
|
||||
color: [0x0, 0x0],
|
||||
state: State::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn white_occupancies(&self) -> Bitboard {
|
||||
self.white_pieces.iter().fold(0, |acc, p| p.bitboard | acc)
|
||||
fn white_occupancies(&self) -> Bitboard {
|
||||
self.color[Color::White]
|
||||
}
|
||||
|
||||
pub fn black_occupancies(&self) -> Bitboard {
|
||||
self.black_pieces.iter().fold(0, |acc, p| p.bitboard | acc)
|
||||
fn black_occupancies(&self) -> Bitboard {
|
||||
self.color[Color::Black]
|
||||
}
|
||||
|
||||
pub fn all_occupancies(&self) -> Bitboard {
|
||||
@@ -78,17 +59,15 @@ impl Board {
|
||||
|
||||
pub fn is_attacked(&self, square: usize, opponent_color: Color) -> bool {
|
||||
let all_occupancies = self.all_occupancies();
|
||||
let (opponent, own_color) = match opponent_color {
|
||||
Color::Black => (&self.black_pieces, Color::White),
|
||||
Color::White => (&self.white_pieces, Color::Black),
|
||||
};
|
||||
let own_color = opponent_color.opponent();
|
||||
let opponent_color_bb = &self.color[opponent_color];
|
||||
|
||||
let pawns = opponent[PieceType::Pawn].bitboard;
|
||||
let knights = opponent[PieceType::Knight].bitboard;
|
||||
let bishops = opponent[PieceType::Bishop].bitboard;
|
||||
let rooks = opponent[PieceType::Rook].bitboard;
|
||||
let queens = opponent[PieceType::Queen].bitboard;
|
||||
let king = opponent[PieceType::King].bitboard;
|
||||
let pawns = self.pieces[PieceType::Pawn] & opponent_color_bb;
|
||||
let knights = self.pieces[PieceType::Knight] & opponent_color_bb;
|
||||
let bishops = self.pieces[PieceType::Bishop] & opponent_color_bb;
|
||||
let rooks = self.pieces[PieceType::Rook] & opponent_color_bb;
|
||||
let queens = self.pieces[PieceType::Queen] & opponent_color_bb;
|
||||
let king = self.pieces[PieceType::King] & opponent_color_bb;
|
||||
|
||||
have_common_bit(pawns, fetch_pawn_attacks(square, own_color))
|
||||
|| have_common_bit(knights, fetch_knight_attacks(square))
|
||||
@@ -99,11 +78,7 @@ impl Board {
|
||||
}
|
||||
|
||||
pub fn king_under_check(&self, color: Color) -> bool {
|
||||
let own_king_square = match color {
|
||||
Color::White => lsb(self.white_pieces[PieceType::King].bitboard),
|
||||
Color::Black => lsb(self.black_pieces[PieceType::King].bitboard),
|
||||
};
|
||||
|
||||
let own_king_square = lsb(self.pieces[PieceType::King] & self.color[color]);
|
||||
self.is_attacked(own_king_square, color.opponent())
|
||||
}
|
||||
|
||||
@@ -134,18 +109,9 @@ impl Board {
|
||||
|
||||
pub fn pseudo_moves(&self, color: Color, piece_type: PieceType) -> Vec<Move> {
|
||||
let all_occupancies = self.all_occupancies();
|
||||
let (pieces, opponent_occupancies, own_occupancies) = match color {
|
||||
Color::White => (
|
||||
self.white_pieces[piece_type].bitboard,
|
||||
self.black_occupancies(),
|
||||
self.white_occupancies(),
|
||||
),
|
||||
Color::Black => (
|
||||
self.black_pieces[piece_type].bitboard,
|
||||
self.white_occupancies(),
|
||||
self.black_occupancies(),
|
||||
),
|
||||
};
|
||||
let pieces = self.pieces[piece_type] & self.color[color];
|
||||
let own_occupancies = self.color[color];
|
||||
let opponent_occupancies = self.color[color.opponent()];
|
||||
|
||||
match piece_type {
|
||||
PieceType::Pawn => pawn_pseudo_moves(
|
||||
@@ -165,70 +131,56 @@ impl Board {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_piece(&mut self, piece: &Piece) {
|
||||
match piece.color {
|
||||
Color::Black => self.black_pieces[piece.piece_type].bitboard |= piece.bitboard,
|
||||
Color::White => self.white_pieces[piece.piece_type].bitboard |= piece.bitboard,
|
||||
};
|
||||
pub fn set_piece(&mut self, bb: Bitboard, piece_type: PieceType, color: Color) {
|
||||
self.pieces[piece_type] |= bb;
|
||||
self.color[color] |= bb;
|
||||
}
|
||||
|
||||
pub fn set_state(&mut self, state: State) {
|
||||
self.state = state;
|
||||
}
|
||||
|
||||
pub fn is_pawn_move(&mut self, square: usize) -> bool {
|
||||
let pieces = self.own_pieces();
|
||||
have_common_bit(square_to_bitboard(square), pieces[PieceType::Pawn].bitboard)
|
||||
}
|
||||
|
||||
pub fn own_pieces(&mut self) -> &mut [Piece; 6] {
|
||||
match self.state.current_player() {
|
||||
Color::White => &mut self.white_pieces,
|
||||
Color::Black => &mut self.black_pieces,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn opponent_pieces(&mut self) -> &mut [Piece; 6] {
|
||||
match self.state.current_player() {
|
||||
Color::White => &mut self.black_pieces,
|
||||
Color::Black => &mut self.white_pieces,
|
||||
}
|
||||
pub fn is_pawn_move(&self, square: usize) -> bool {
|
||||
let side = self.state.current_player();
|
||||
let own_pawns = self.pieces[PieceType::Pawn] & self.color[side];
|
||||
have_common_bit(square_to_bitboard(square), own_pawns)
|
||||
}
|
||||
|
||||
pub fn move_piece(&mut self, src: usize, dst: usize, piece_type: PieceType) {
|
||||
let pieces = self.own_pieces();
|
||||
pieces[piece_type].bitboard &= !square_to_bitboard(src);
|
||||
pieces[piece_type].bitboard |= square_to_bitboard(dst);
|
||||
self.pieces[piece_type] &= !square_to_bitboard(src);
|
||||
self.pieces[piece_type] |= square_to_bitboard(dst);
|
||||
self.color[self.state.current_player()] &= !square_to_bitboard(src);
|
||||
self.color[self.state.current_player()] |= square_to_bitboard(dst);
|
||||
}
|
||||
|
||||
pub fn insert_own_piece(&mut self, square: usize, piece_type: PieceType) {
|
||||
let pieces = self.own_pieces();
|
||||
pieces[piece_type].bitboard |= square_to_bitboard(square);
|
||||
self.pieces[piece_type] |= square_to_bitboard(square);
|
||||
self.color[self.state.current_player()] |= square_to_bitboard(square);
|
||||
}
|
||||
|
||||
pub fn insert_opponent_piece(&mut self, square: usize, piece_type: PieceType) {
|
||||
let pieces = self.opponent_pieces();
|
||||
pieces[piece_type].bitboard |= square_to_bitboard(square);
|
||||
self.pieces[piece_type] |= square_to_bitboard(square);
|
||||
self.color[self.state.next_player()] |= square_to_bitboard(square);
|
||||
}
|
||||
|
||||
pub fn remove_own_piece(&mut self, square: usize, piece_type: PieceType) {
|
||||
let pieces = self.own_pieces();
|
||||
pieces[piece_type].bitboard &= !square_to_bitboard(square);
|
||||
self.pieces[piece_type] &= !square_to_bitboard(square);
|
||||
self.color[self.state.current_player()] &= !square_to_bitboard(square);
|
||||
}
|
||||
|
||||
pub fn remove_opponent_piece(&mut self, square: usize, piece_type: PieceType) {
|
||||
let pieces = self.opponent_pieces();
|
||||
pieces[piece_type].bitboard &= !square_to_bitboard(square);
|
||||
self.pieces[piece_type] &= !square_to_bitboard(square);
|
||||
self.color[self.state.next_player()] &= !square_to_bitboard(square);
|
||||
}
|
||||
|
||||
pub fn promote_piece(&mut self, square: usize, promote: &Promote) {
|
||||
let pieces = self.own_pieces();
|
||||
match promote {
|
||||
Promote::Knight => pieces[PieceType::Knight].bitboard |= square_to_bitboard(square),
|
||||
Promote::Bishop => pieces[PieceType::Bishop].bitboard |= square_to_bitboard(square),
|
||||
Promote::Rook => pieces[PieceType::Rook].bitboard |= square_to_bitboard(square),
|
||||
Promote::Queen => pieces[PieceType::Queen].bitboard |= square_to_bitboard(square),
|
||||
Promote::Knight => self.pieces[PieceType::Knight] |= square_to_bitboard(square),
|
||||
Promote::Bishop => self.pieces[PieceType::Bishop] |= square_to_bitboard(square),
|
||||
Promote::Rook => self.pieces[PieceType::Rook] |= square_to_bitboard(square),
|
||||
Promote::Queen => self.pieces[PieceType::Queen] |= square_to_bitboard(square),
|
||||
};
|
||||
self.color[self.state.current_player()] |= square_to_bitboard(square);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,24 +190,7 @@ impl Default for Board {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub struct Piece {
|
||||
pub bitboard: Bitboard,
|
||||
pub piece_type: PieceType,
|
||||
pub color: Color,
|
||||
}
|
||||
|
||||
impl Piece {
|
||||
pub const fn new(bitboard: Bitboard, piece_type: PieceType, color: Color) -> Self {
|
||||
Self {
|
||||
bitboard,
|
||||
piece_type,
|
||||
color,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, EnumIter)]
|
||||
pub enum PieceType {
|
||||
Pawn,
|
||||
Knight,
|
||||
@@ -286,7 +221,7 @@ impl<T> IndexMut<PieceType> for [T] {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, EnumIter)]
|
||||
pub enum Color {
|
||||
White,
|
||||
Black,
|
||||
|
||||
Reference in New Issue
Block a user