diff options
author | eug-vs <eugene@eug-vs.xyz> | 2023-01-26 21:28:09 +0300 |
---|---|---|
committer | eug-vs <eugene@eug-vs.xyz> | 2023-01-26 21:51:47 +0300 |
commit | 7e9fb647616178391bedc677e488bb2b1ea54786 (patch) | |
tree | 26dd2f2d1b147adce10a3d847610daa06425997a | |
parent | 1eeda0725263aa1cab7c8f5a81773896ad8bda4f (diff) | |
download | chessnost-7e9fb647616178391bedc677e488bb2b1ea54786.tar.gz |
refactor: exclude enemy king from capture targets
-rw-r--r-- | src/board/mod.rs | 57 |
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 } } |