Compare commits
12 Commits
Server/web
...
Engine/boa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5425ccc5cd | ||
|
|
1104c8e6c5 | ||
|
|
274ffcf5ec | ||
|
|
5854dbc20b | ||
|
|
f36a196b2f | ||
|
|
11f26809df | ||
|
|
c88fbe68e3 | ||
|
|
7f4c53ddb7 | ||
|
|
38b38845d6 | ||
|
|
66dd2877b2 | ||
|
|
3cd53c7d70 | ||
|
|
5b3bdc750f |
@@ -1,2 +1,3 @@
|
|||||||
mod attackmaps;
|
mod attackmaps;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
pub mod board;
|
||||||
182
engine/src/bitboard/board.rs
Normal file
182
engine/src/bitboard/board.rs
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
use super::utils::try_get_square_number_from_notation;
|
||||||
|
|
||||||
|
pub struct Board {
|
||||||
|
pub(in super) bitboards: [u64; 12], // 0-5 -> white pieces (P, N, B, R, Q, K), 6-11 -> black pieces (p, n, b, r, q, k)
|
||||||
|
pub(in super) piece_board: [u8; 64], // same as board indexes, 12 -> empty square
|
||||||
|
pub(in super) occupancy: [u64; 3], // 0 -> white, 1 -> black, 2 -> combined
|
||||||
|
pub(in super) castling_rights: u8, // 0b0000_KQkq
|
||||||
|
pub(in super) pinned_squares: [u8; 64], // 0 -> E-W, 1 -> NE-SW, 2 -> N-S, 3 -> SE-NW, 4 -> no pin
|
||||||
|
pub(in super) pin_mask: u64, // 1 -> pin, 0 -> no pin
|
||||||
|
pub(in super) en_passant_square: u64, // 1 -> ep square, 0 -> no ep square
|
||||||
|
pub(in super) side_to_move: u8 // 0 -> white to play, 1 -> black to play
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Board {
|
||||||
|
|
||||||
|
pub fn new_clear() -> Self {
|
||||||
|
let mut bit_board: Self = Self {
|
||||||
|
bitboards: [0x0000_0000_0000_0000; 12],
|
||||||
|
piece_board: [12; 64],
|
||||||
|
occupancy: [0x0000_0000_0000_0000; 3],
|
||||||
|
castling_rights: 0b0000_0000,
|
||||||
|
pinned_squares: [4; 64],
|
||||||
|
pin_mask: 0u64,
|
||||||
|
en_passant_square: 0x0000_0000_0000_0000,
|
||||||
|
side_to_move: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
return bit_board;
|
||||||
|
}
|
||||||
|
pub fn new() -> Self {
|
||||||
|
let mut bit_board: Board = Self {
|
||||||
|
bitboards: [0x0000_0000_0000_FF00,
|
||||||
|
0x0000_0000_0000_0042,
|
||||||
|
0x0000_0000_0000_0024,
|
||||||
|
0x0000_0000_0000_0081,
|
||||||
|
0x0000_0000_0000_0008,
|
||||||
|
0x0000_0000_0000_0010,
|
||||||
|
0x00FF_0000_0000_0000,
|
||||||
|
0x4200_0000_0000_0000,
|
||||||
|
0x2400_0000_0000_0000,
|
||||||
|
0x8100_0000_0000_0000,
|
||||||
|
0x0800_0000_0000_0000,
|
||||||
|
0x1000_0000_0000_0000],
|
||||||
|
piece_board: [12; 64],
|
||||||
|
occupancy: [0; 3],
|
||||||
|
castling_rights: 0b0000_1111,
|
||||||
|
pinned_squares: [4; 64],
|
||||||
|
pin_mask: 0u64,
|
||||||
|
en_passant_square: 0x0000_0000_0000_0000,
|
||||||
|
side_to_move: 0
|
||||||
|
};
|
||||||
|
bit_board.calc_occupancy();
|
||||||
|
bit_board.calc_piece_board();
|
||||||
|
|
||||||
|
return bit_board;
|
||||||
|
}
|
||||||
|
pub fn build(fen: &str) -> Self {
|
||||||
|
let mut board: Board = Board::new_clear();
|
||||||
|
|
||||||
|
let mut col: i32 = 0;
|
||||||
|
let mut row: i32 = 7;
|
||||||
|
let pieces: [char; 12] = ['p', 'n', 'b', 'r', 'q', 'k', 'P', 'N', 'B', 'R', 'Q', 'K'];
|
||||||
|
let mut coming_up: &str = fen;
|
||||||
|
|
||||||
|
for (i, c) in coming_up.chars().enumerate() {
|
||||||
|
if pieces.contains(&c) {
|
||||||
|
// board.place_piece(row*8 + col, c);
|
||||||
|
col += 1;
|
||||||
|
}
|
||||||
|
else if ('1'..='8').contains(&c) {
|
||||||
|
col += c.to_string().parse::<i32>().unwrap();
|
||||||
|
}
|
||||||
|
else if c == '/' {
|
||||||
|
row -= 1;
|
||||||
|
col = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
coming_up = &coming_up[i+1..];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
board.calc_occupancy();
|
||||||
|
|
||||||
|
match coming_up.chars().next().unwrap() {
|
||||||
|
'w' => board.side_to_move = 0,
|
||||||
|
'b' => board.side_to_move = 1,
|
||||||
|
_ => panic!("invalid fen notation / to be handled later")
|
||||||
|
}
|
||||||
|
coming_up = &coming_up[2..];
|
||||||
|
|
||||||
|
for (i, c) in coming_up.chars().enumerate() {
|
||||||
|
match c {
|
||||||
|
'K' => board.castling_rights |= 1 << 3,
|
||||||
|
'Q' => board.castling_rights |= 1 << 2,
|
||||||
|
'k' => board.castling_rights |= 1 << 1,
|
||||||
|
'q' => board.castling_rights |= 1,
|
||||||
|
'-' => {
|
||||||
|
coming_up = &coming_up[i+2..];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
coming_up = &coming_up[i+1..];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match coming_up.chars().next().unwrap() {
|
||||||
|
'-' => {
|
||||||
|
coming_up = &coming_up[1..];
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let notation = coming_up.split(' ').next().unwrap();
|
||||||
|
if let Ok(epsq_index) = try_get_square_number_from_notation(notation) {
|
||||||
|
board.en_passant_square = 1 << epsq_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// board.calc_pinned_squares();
|
||||||
|
board.calc_piece_board();
|
||||||
|
|
||||||
|
return board;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn bitboards(&self, index: usize) -> u64 {
|
||||||
|
return self.bitboards[index];
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn piece_board(&self, sq: u8) -> u8 {
|
||||||
|
return self.piece_board[sq as usize];
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn occupancy(&self, side: usize) -> u64 {
|
||||||
|
return self.occupancy[side];
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn castling_rights(&self) -> u8 {
|
||||||
|
return self.castling_rights;
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn pinned_squares(&self, sq: usize) -> u8 {
|
||||||
|
return self.pinned_squares[sq];
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn pin_mask(&self) -> u64 {
|
||||||
|
return self.pin_mask;
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn en_passant_square(&self) -> u64 {
|
||||||
|
return self.en_passant_square;
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn side_to_move(&self) -> u8 {
|
||||||
|
return self.side_to_move;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn current_king_square(&self) -> u32 {
|
||||||
|
return if self.side_to_move == 0 { self.bitboards[5].trailing_zeros() } else { self.bitboards[11].trailing_zeros() };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calc_occupancy(&mut self) {
|
||||||
|
self.occupancy = [0u64; 3];
|
||||||
|
for b in 0..6 {
|
||||||
|
self.occupancy[0] |= self.bitboards[b];
|
||||||
|
}
|
||||||
|
for b in 6..12 {
|
||||||
|
self.occupancy[1] |= self.bitboards[b];
|
||||||
|
}
|
||||||
|
self.occupancy[2] = self.occupancy[0] | self.occupancy[1];
|
||||||
|
}
|
||||||
|
fn calc_piece_board(&mut self) {
|
||||||
|
for sq in 0..64 {
|
||||||
|
for b in 0..12 {
|
||||||
|
if (self.bitboards[b as usize] & 1 << sq) != 0 {
|
||||||
|
self.piece_board[sq] = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -27,6 +27,27 @@ pub fn notation_from_square_number(sq: u8) -> String {
|
|||||||
return notation;
|
return notation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn try_get_square_number_from_notation(notation: &str) -> Result<u8, ()> {
|
||||||
|
|
||||||
|
let file = match notation.chars().nth(0).unwrap() {
|
||||||
|
'a' => 0,
|
||||||
|
'b' => 1,
|
||||||
|
'c' => 2,
|
||||||
|
'd' => 3,
|
||||||
|
'e' => 4,
|
||||||
|
'f' => 5,
|
||||||
|
'g' => 6,
|
||||||
|
'h' => 7,
|
||||||
|
_ => { return Result::Err(()); }
|
||||||
|
};
|
||||||
|
if let Some(rank) = notation.chars().nth(1) {
|
||||||
|
return Result::Ok(file + 8 * (rank.to_digit(10).unwrap() as u8) - 8);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Result::Err(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// <----- TESTS ----->
|
// <----- TESTS ----->
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user