aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreug-vs <eugene@eug-vs.xyz>2023-01-26 21:28:09 +0300
committereug-vs <eugene@eug-vs.xyz>2023-01-26 21:51:47 +0300
commit7e9fb647616178391bedc677e488bb2b1ea54786 (patch)
tree26dd2f2d1b147adce10a3d847610daa06425997a
parent1eeda0725263aa1cab7c8f5a81773896ad8bda4f (diff)
downloadchessnost-7e9fb647616178391bedc677e488bb2b1ea54786.tar.gz
refactor: exclude enemy king from capture targets
-rw-r--r--src/board/mod.rs57
1 files changed, 25 insertions, 32 deletions
diff --git a/src/board/mod.rs b/src/board/mod.rs
index 589da8a..c889257 100644
--- a/src/board/mod.rs
+++ b/src/board/mod.rs
@@ -78,7 +78,6 @@ const PIECE_CHARS: [&str; 12] = [
];
-#[allow(unused)]
impl Board {
#[allow(non_snake_case)]
pub fn from_FEN(fen: String) -> Self {
@@ -156,11 +155,7 @@ impl Board {
}
fn update_occupancy(&mut self) {
- self.occupancy = 0;
- // TODO: reduce
- for piece in self.pieces {
- self.occupancy |= piece;
- }
+ self.occupancy = self.pieces.iter().fold(0, |acc, bitboard| acc | bitboard)
}
fn empty(&self) -> Bitboard {
@@ -175,11 +170,7 @@ impl Board {
}
fn color_occupancy(&self, color: Color) -> Bitboard {
- let mut occupancy = 0;
- for piece in self.pieces_by_color(color) {
- occupancy |= piece;
- }
- occupancy
+ self.pieces_by_color(color).iter().fold(0, |acc, bitboard| acc | bitboard)
}
/// Compute and store zobrist hash of the current position
@@ -241,9 +232,12 @@ impl Board {
pub fn generate_pseudolegal_moves(&self, color: Color) -> Vec<Move> {
let mut moves = Vec::with_capacity(1024);
- let opponent_occupancy = self.color_occupancy(color.flip());
+ let capture_targets = self.color_occupancy(color.flip()) ^ match color {
+ // Exclude opponent king because we can't capture it
+ Color::White => self.pieces[PieceType::KingBlack as usize],
+ Color::Black => self.pieces[PieceType::King as usize],
+ };
let empty = self.empty();
- let available_targets = opponent_occupancy | empty;
let player_pieces = self.pieces_by_color(color);
for (piece_id, piece) in player_pieces.iter().enumerate() {
@@ -254,13 +248,13 @@ impl Board {
Some(square) => square.to_bitboard(),
None => 0,
};
- for target in serialize_bitboard(self.attacks.pawn[color as usize][source as usize] & opponent_occupancy) {
+ for target in serialize_bitboard(self.attacks.pawn[color as usize][source as usize] & capture_targets) {
moves.push(Move { source, target, kind: MoveKind::Capture });
- if (target.rank() == 7) {
+ if target.rank() == 7 {
for promo_type in [PieceType::Bishop, PieceType::Knight, PieceType::Rook, PieceType::Queen] {
moves.push(Move { source, target, kind: MoveKind::Promotion(promo_type)})
}
- } else if (target.rank() == 0) {
+ } else if target.rank() == 0 {
for promo_type in [PieceType::BishopBlack, PieceType::KnightBlack, PieceType::RookBlack, PieceType::QueenBlack] {
moves.push(Move { source, target, kind: MoveKind::Promotion(promo_type)})
}
@@ -271,11 +265,11 @@ impl Board {
}
for target in serialize_bitboard(self.attacks.pawn_pushes[color as usize][source as usize] & empty) {
moves.push(Move { source, target, kind: MoveKind::Quiet });
- if (target.rank() == 7) {
+ if target.rank() == 7 {
for promo_type in [PieceType::Bishop, PieceType::Knight, PieceType::Rook, PieceType::Queen] {
moves.push(Move { source, target, kind: MoveKind::Promotion(promo_type)})
}
- } else if (target.rank() == 0) {
+ } else if target.rank() == 0 {
for promo_type in [PieceType::BishopBlack, PieceType::KnightBlack, PieceType::RookBlack, PieceType::QueenBlack] {
moves.push(Move { source, target, kind: MoveKind::Promotion(promo_type)})
}
@@ -300,7 +294,7 @@ impl Board {
for target in serialize_bitboard(self.attacks.king[source as usize] & empty) {
moves.push(Move { source, target, kind: MoveKind::Quiet });
};
- for target in serialize_bitboard(self.attacks.king[source as usize] & opponent_occupancy) {
+ for target in serialize_bitboard(self.attacks.king[source as usize] & capture_targets) {
moves.push(Move { source, target, kind: MoveKind::Capture });
};
@@ -369,7 +363,7 @@ impl Board {
for target in serialize_bitboard(self.attacks.knight[source as usize] & empty) {
moves.push(Move { source, target, kind: MoveKind::Quiet });
};
- for target in serialize_bitboard(self.attacks.knight[source as usize] & opponent_occupancy) {
+ for target in serialize_bitboard(self.attacks.knight[source as usize] & capture_targets) {
moves.push(Move { source, target, kind: MoveKind::Capture });
};
}
@@ -379,7 +373,7 @@ impl Board {
for target in serialize_bitboard(self.attacks.bishop(self.occupancy, source) & empty) {
moves.push(Move { source, target, kind: MoveKind::Quiet });
};
- for target in serialize_bitboard(self.attacks.bishop(self.occupancy, source) & opponent_occupancy) {
+ for target in serialize_bitboard(self.attacks.bishop(self.occupancy, source) & capture_targets) {
moves.push(Move { source, target, kind: MoveKind::Capture });
};
}
@@ -391,7 +385,7 @@ impl Board {
};
}
for source in serialize_bitboard(*piece) {
- for target in serialize_bitboard(self.attacks.rook(self.occupancy, source) & opponent_occupancy) {
+ for target in serialize_bitboard(self.attacks.rook(self.occupancy, source) & capture_targets) {
moves.push(Move { source, target, kind: MoveKind::Capture });
};
}
@@ -401,7 +395,7 @@ impl Board {
for target in serialize_bitboard(self.attacks.queen(self.occupancy, source) & empty) {
moves.push(Move { source, target, kind: MoveKind::Quiet });
};
- for target in serialize_bitboard(self.attacks.queen(self.occupancy, source) & opponent_occupancy) {
+ for target in serialize_bitboard(self.attacks.queen(self.occupancy, source) & capture_targets) {
moves.push(Move { source, target, kind: MoveKind::Capture });
};
}
@@ -516,7 +510,7 @@ impl Board {
self.pieces
.iter()
.enumerate()
- .find(|(piece_type, bitboard)| *bitboard & square.to_bitboard() > 0)
+ .find(|(_, bitboard)| *bitboard & square.to_bitboard() > 0)
.and_then(|(pt, _)| Some(PieceType::from(pt)))
}
@@ -708,7 +702,7 @@ impl Board {
match self.pieces
.iter()
.enumerate()
- .find(|(rook_type, bitboard)| *bitboard & rook_target_bb > 0)
+ .find(|(_, bitboard)| *bitboard & rook_target_bb > 0)
{
Some((rook_type, _)) => {
self.pieces[rook_type] |= rook_source_bb;
@@ -748,36 +742,35 @@ impl Board {
}
fn is_square_attacked(&self, square: Square, attacker_color: Color) -> bool {
- let square_bb = square.to_bitboard();
for (piece_type, piece) in self.pieces_by_color(attacker_color).iter().enumerate() {
match PieceType::from(piece_type) {
PieceType::Pawn => {
- if (self.attacks.pawn[attacker_color.flip() as usize][square as usize] & piece > 0) {
+ if self.attacks.pawn[attacker_color.flip() as usize][square as usize] & piece > 0 {
return true
}
}
PieceType::King => {
- if (self.attacks.king[square as usize] & piece > 0) {
+ if self.attacks.king[square as usize] & piece > 0 {
return true
}
}
PieceType::Knight => {
- if (self.attacks.knight[square as usize] & piece > 0) {
+ if self.attacks.knight[square as usize] & piece > 0 {
return true
}
}
PieceType::Bishop => {
- if (self.attacks.bishop(self.occupancy, square) & piece > 0) {
+ if self.attacks.bishop(self.occupancy, square) & piece > 0 {
return true
}
}
PieceType::Rook => {
- if (self.attacks.rook(self.occupancy, square) & piece > 0) {
+ if self.attacks.rook(self.occupancy, square) & piece > 0 {
return true
}
}
PieceType::Queen => {
- if (self.attacks.queen(self.occupancy, square) & piece > 0) {
+ if self.attacks.queen(self.occupancy, square) & piece > 0 {
return true
}
}