diff --git a/src/attack.rs b/src/attack.rs
index 6a98689..f9cf02d 100644
--- a/src/attack.rs
+++ b/src/attack.rs
@@ -1,6 +1,6 @@
use crate::{
bitboard::{
- intersect, lsb, square_to_bitboard, square_to_bitboard_wrapping, EMPTY, NOT_FILE_A,
+ have_common_bit, lsb, square_to_bitboard, square_to_bitboard_wrapping, EMPTY, NOT_FILE_A,
NOT_FILE_AB, NOT_FILE_GH, NOT_FILE_H,
},
board::Color,
@@ -152,7 +152,7 @@ pub fn bishop_attacks_on_the_fly(bitboard: Bitboard, blocker: Bitboard) -> Bitbo
for (rank, file) in (rank..=7).zip(file..=7) {
let attack_square = square_to_bitboard(coords_to_square(rank, file));
attacks |= attack_square;
- if attack_square & blocker != 0 {
+ if have_common_bit(attack_square, blocker) {
break;
}
}
@@ -161,7 +161,7 @@ pub fn bishop_attacks_on_the_fly(bitboard: Bitboard, blocker: Bitboard) -> Bitbo
for (rank, file) in (0..target_rank).rev().zip(file..=7) {
let attack_square = square_to_bitboard(coords_to_square(rank, file));
attacks |= attack_square;
- if attack_square & blocker != 0 {
+ if have_common_bit(attack_square, blocker) {
break;
}
}
@@ -170,7 +170,7 @@ pub fn bishop_attacks_on_the_fly(bitboard: Bitboard, blocker: Bitboard) -> Bitbo
for (rank, file) in (rank..=7).zip((0..target_file).rev()) {
let attack_square = square_to_bitboard(coords_to_square(rank, file));
attacks |= attack_square;
- if attack_square & blocker != 0 {
+ if have_common_bit(attack_square, blocker) {
break;
}
}
@@ -178,7 +178,7 @@ pub fn bishop_attacks_on_the_fly(bitboard: Bitboard, blocker: Bitboard) -> Bitbo
for (rank, file) in (0..target_rank).rev().zip((0..target_file).rev()) {
let attack_square = square_to_bitboard(coords_to_square(rank, file));
attacks |= attack_square;
- if attack_square & blocker != 0 {
+ if have_common_bit(attack_square, blocker) {
break;
}
}
@@ -197,14 +197,14 @@ pub fn rook_attacks_on_the_fly(bitboard: Bitboard, blocker: Bitboard) -> Bitboar
for rank in rank..=7 {
let attack_square = square_to_bitboard(coords_to_square(rank, target_file));
attacks |= attack_square;
- if attack_square & blocker != 0 {
+ if have_common_bit(attack_square, blocker) {
break;
}
}
for file in file..=7 {
let attack_square = square_to_bitboard(coords_to_square(target_rank, file));
attacks |= attack_square;
- if attack_square & blocker != 0 {
+ if have_common_bit(attack_square, blocker) {
break;
}
}
@@ -213,14 +213,14 @@ pub fn rook_attacks_on_the_fly(bitboard: Bitboard, blocker: Bitboard) -> Bitboar
for rank in (0..=rank).rev() {
let attack_square = square_to_bitboard(coords_to_square(rank, target_file));
attacks |= attack_square;
- if attack_square & blocker != 0 {
+ if have_common_bit(attack_square, blocker) {
break;
}
}
for file in (0..=file).rev() {
let attack_square = square_to_bitboard(coords_to_square(target_rank, file));
attacks |= attack_square;
- if attack_square & blocker != 0 {
+ if have_common_bit(attack_square, blocker) {
break;
}
}
@@ -234,7 +234,7 @@ pub fn set_occupancy(index: u64, relevant_bits: usize, mut attack_mask: Bitboard
for bit in 0..relevant_bits {
let square = lsb(attack_mask);
attack_mask &= !square_to_bitboard(square);
- if intersect(index, square_to_bitboard(bit)) {
+ if have_common_bit(index, square_to_bitboard(bit)) {
occupancy |= square_to_bitboard(square);
}
}
diff --git a/src/bitboard.rs b/src/bitboard.rs
index 75cefac..b7fe7cb 100644
--- a/src/bitboard.rs
+++ b/src/bitboard.rs
@@ -3,10 +3,15 @@ use u64 as Bitboard;
pub const EMPTY: Bitboard = 0x0;
pub const FULL: Bitboard = 0xffffffffffffffff;
pub const NOT_FILE_A: Bitboard = 0xfefefefefefefefe;
-pub const NOT_FILE_AB: Bitboard = 0xfcfcfcfcfcfcfcfc;
pub const NOT_FILE_H: Bitboard = 0x7f7f7f7f7f7f7f7f;
+pub const NOT_FILE_AB: Bitboard = 0xfcfcfcfcfcfcfcfc;
pub const NOT_FILE_GH: Bitboard = 0x3f3f3f3f3f3f3f3f;
-pub const RANK_8: Bitboard = 0x0ff00000000000000;
+pub const RANK_1: Bitboard = 0xff;
+pub const RANK_2: Bitboard = 0xff00;
+pub const RANK_4: Bitboard = 0xff000000;
+pub const RANK_5: Bitboard = 0xff00000000;
+pub const RANK_7: Bitboard = 0xff000000000000;
+pub const RANK_8: Bitboard = 0xff00000000000000;
pub const fn square_to_bitboard(square: usize) -> Bitboard {
1_u64 << square
@@ -24,6 +29,6 @@ pub const fn bit_count(bitboard: Bitboard) -> usize {
bitboard.count_ones() as usize
}
-pub const fn intersect(bitboard_a: Bitboard, bitboard_b: Bitboard) -> bool {
+pub const fn have_common_bit(bitboard_a: Bitboard, bitboard_b: Bitboard) -> bool {
bitboard_a & bitboard_b != 0
}
diff --git a/src/board.rs b/src/board.rs
index 5e5e7fe..1024f15 100644
--- a/src/board.rs
+++ b/src/board.rs
@@ -4,6 +4,7 @@ use crate::attack::{
get_bishop_attacks, get_king_attacks, get_knight_attacks, get_pawn_attacks, get_queen_attacks,
get_rook_attacks,
};
+use crate::bitboard::{have_common_bit, lsb, square_to_bitboard};
use crate::game::{Castle, State};
use crate::movegen::{
bishop_pseudo_moves, king_pseudo_moves, knight_pseudo_moves, pawn_pseudo_moves,
@@ -93,12 +94,23 @@ impl Board {
Color::White => (&self.white_pieces, Color::Black),
};
- enemy[Kind::Pawn.idx()].bitboard & get_pawn_attacks(sq, own_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
+ have_common_bit(
+ enemy[Kind::Pawn.idx()].bitboard,
+ get_pawn_attacks(sq, own_color),
+ ) || have_common_bit(enemy[Kind::Knight.idx()].bitboard, get_knight_attacks(sq))
+ || have_common_bit(
+ enemy[Kind::Bishop.idx()].bitboard,
+ get_bishop_attacks(all_occupancies, sq),
+ )
+ || have_common_bit(
+ enemy[Kind::Rook.idx()].bitboard,
+ get_rook_attacks(all_occupancies, sq),
+ )
+ || have_common_bit(
+ enemy[Kind::Queen.idx()].bitboard,
+ get_queen_attacks(all_occupancies, sq),
+ )
+ || have_common_bit(enemy[Kind::King.idx()].bitboard, get_king_attacks(sq))
}
pub fn is_move_legit(&self, square: usize, opponent_color: Color) -> bool {
@@ -162,13 +174,12 @@ impl Board {
Color::Black => &self.black_pieces,
};
+ self.state.update_castling_state_quiet(mv.source, color);
self.state
- .update_castling_state_quiet(mv.source as u8, color);
- self.state
- .update_castling_state_capture(mv.target as u8, Color::opponent_color(color));
+ .update_castling_state_capture(mv.target, Color::opponent_color(color));
self.state.change_side();
- let own_king_square = pieces[Kind::King.idx()].bitboard.trailing_zeros() as usize;
+ let own_king_square = lsb(pieces[Kind::King.idx()].bitboard);
self.is_move_legit(own_king_square, Color::opponent_color(color))
}
@@ -180,58 +191,58 @@ impl Board {
match &mv.move_type {
MoveType::Quiet => {
- Self::move_piece(mv.source as u8, mv.target as u8, own_pieces);
+ Self::move_piece(mv.source, mv.target, own_pieces);
self.state.set_en_passant_target_square(None);
}
MoveType::Capture => {
- Self::move_piece(mv.source as u8, mv.target as u8, own_pieces);
- Self::remove_piece(mv.target as u8, opponent_pieces);
+ Self::move_piece(mv.source, mv.target, own_pieces);
+ Self::remove_piece(mv.target, opponent_pieces);
self.state.set_en_passant_target_square(None);
}
MoveType::EnPassant => {
- Self::move_piece(mv.source as u8, mv.target as u8, own_pieces);
- Self::remove_pawn_enpassant(mv.target as u8, opponent_pieces, color);
+ Self::move_piece(mv.source, mv.target, own_pieces);
+ Self::remove_pawn_enpassant(mv.target, opponent_pieces, color);
self.state.set_en_passant_target_square(None);
}
MoveType::DoublePush => {
- Self::move_piece(mv.source as u8, mv.target as u8, own_pieces);
+ Self::move_piece(mv.source, mv.target, own_pieces);
let en_passant = match color {
- Color::White => Some((mv.source + 8) as u8),
- Color::Black => Some((mv.source - 8) as u8),
+ Color::White => Some(mv.source + 8),
+ Color::Black => Some(mv.source - 8),
};
self.state.set_en_passant_target_square(en_passant);
}
MoveType::Promotion(promote) => {
- Self::remove_piece(mv.source as u8, own_pieces);
- Self::promote_piece(mv.target as u8, own_pieces, *promote);
+ Self::remove_piece(mv.source, own_pieces);
+ Self::promote_piece(mv.target, own_pieces, *promote);
self.state.set_en_passant_target_square(None);
}
MoveType::PromotionCapture(promote) => {
- Self::remove_piece(mv.source as u8, own_pieces);
- Self::remove_piece(mv.target as u8, opponent_pieces);
- Self::promote_piece(mv.target as u8, own_pieces, *promote);
+ Self::remove_piece(mv.source, own_pieces);
+ Self::remove_piece(mv.target, opponent_pieces);
+ Self::promote_piece(mv.target, own_pieces, *promote);
self.state.set_en_passant_target_square(None);
}
MoveType::Castle => {
- Self::move_piece(mv.source as u8, mv.target as u8, own_pieces);
- Self::move_rook_castle(mv.target as u8, own_pieces);
+ Self::move_piece(mv.source, mv.target, own_pieces);
+ Self::move_rook_castle(mv.target, own_pieces);
self.state.set_en_passant_target_square(None);
self.state.set_castling_ability(color, Castle::None)
}
}
}
- fn move_piece(source: u8, target: u8, pieces: &mut [Piece; 6]) {
+ fn move_piece(source: usize, target: usize, pieces: &mut [Piece; 6]) {
for p in pieces.iter_mut() {
- if p.bitboard & (1_u64 << source) != 0 {
- p.bitboard &= !(1_u64 << source);
- p.bitboard |= 1_u64 << target;
+ if have_common_bit(p.bitboard, square_to_bitboard(source)) {
+ p.bitboard &= !square_to_bitboard(source);
+ p.bitboard |= square_to_bitboard(target);
break;
}
}
}
- fn move_rook_castle(square: u8, pieces: &mut [Piece; 6]) {
+ fn move_rook_castle(square: usize, pieces: &mut [Piece; 6]) {
let (rook_source, rook_target) = match square {
2 | 58 => (square - 2, square + 1),
6 | 62 => (square + 1, square - 1),
@@ -241,33 +252,33 @@ impl Board {
Self::move_piece(rook_source, rook_target, pieces);
}
- fn promote_piece(square: u8, pieces: &mut [Piece; 6], promote: Promote) {
+ fn promote_piece(square: usize, pieces: &mut [Piece; 6], promote: Promote) {
match promote {
- Promote::Knight => pieces[Kind::Knight.idx()].bitboard |= 1_u64 << square,
- Promote::Bishop => pieces[Kind::Bishop.idx()].bitboard |= 1_u64 << square,
- Promote::Rook => pieces[Kind::Rook.idx()].bitboard |= 1_u64 << square,
- Promote::Queen => pieces[Kind::Queen.idx()].bitboard |= 1_u64 << square,
+ Promote::Knight => pieces[Kind::Knight.idx()].bitboard |= square_to_bitboard(square),
+ Promote::Bishop => pieces[Kind::Bishop.idx()].bitboard |= square_to_bitboard(square),
+ Promote::Rook => pieces[Kind::Rook.idx()].bitboard |= square_to_bitboard(square),
+ Promote::Queen => pieces[Kind::Queen.idx()].bitboard |= square_to_bitboard(square),
};
}
- fn remove_piece(square: u8, pieces: &mut [Piece; 6]) {
+ fn remove_piece(square: usize, pieces: &mut [Piece; 6]) {
for p in pieces.iter_mut() {
- if p.bitboard & (1_u64 << square) != 0 {
- p.bitboard &= !(1_u64 << square);
+ if have_common_bit(p.bitboard, square_to_bitboard(square)) {
+ p.bitboard &= !(square_to_bitboard(square));
break;
}
}
}
- fn remove_pawn_enpassant(square: u8, pieces: &mut [Piece; 6], color: Color) {
+ fn remove_pawn_enpassant(square: usize, pieces: &mut [Piece; 6], color: Color) {
let piece_to_remove = match color {
Color::White => square - 8,
Color::Black => square + 8,
};
for p in pieces.iter_mut() {
- if p.bitboard & (1_u64 << piece_to_remove) != 0 {
- p.bitboard &= !(1_u64 << piece_to_remove);
+ if have_common_bit(p.bitboard, square_to_bitboard(piece_to_remove)) {
+ p.bitboard &= !(square_to_bitboard(piece_to_remove));
break;
}
}
diff --git a/src/fen.rs b/src/fen.rs
index 4337155..3ee569c 100644
--- a/src/fen.rs
+++ b/src/fen.rs
@@ -122,10 +122,10 @@ fn castling_ability(castling: &str) -> Result<[Castle; 2], FenError> {
use std::collections::HashMap;
-fn en_passant_target_square(square: &str) -> Result