From 746e3bf17463a377b6c54b291ebef9a736d6ceb7 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Thu, 25 Jan 2024 11:24:36 +0100 Subject: chore: autoformat code Use #[rustfmt:skip] to preserve aligned blocks --- src/attacks.rs | 236 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 147 insertions(+), 89 deletions(-) (limited to 'src/attacks.rs') diff --git a/src/attacks.rs b/src/attacks.rs index f666bae..bec2b62 100644 --- a/src/attacks.rs +++ b/src/attacks.rs @@ -1,15 +1,15 @@ -use crate::{bitboard::Bitboard, square::Square, board::color::Color}; +use crate::{bitboard::Bitboard, board::color::Color, square::Square}; static NOT_A_FILE: Bitboard = 0xFEFEFEFEFEFEFEFE; static NOT_B_FILE: Bitboard = 0xFDFDFDFDFDFDFDFD; static NOT_G_FILE: Bitboard = 0xBFBFBFBFBFBFBFBF; static NOT_H_FILE: Bitboard = 0x7F7F7F7F7F7F7F7F; -static B_FILE: Bitboard = 0x0202020202020202; -static H_FILE: Bitboard = 0x8080808080808080; +static B_FILE: Bitboard = 0x0202020202020202; +static H_FILE: Bitboard = 0x8080808080808080; static DIAG_C2_H7: Bitboard = 0x0080402010080400; static DIAG_A1_H8: Bitboard = 0x8040201008040201; -static RANK_2: Bitboard = 0x000000000000FF00; -static RANK_7: Bitboard = 0x00FF000000000000; +static RANK_2: Bitboard = 0x000000000000FF00; +static RANK_7: Bitboard = 0x00FF000000000000; /// An array where N-th item is an attack bitboard /// of a piece on N-th square @@ -80,8 +80,10 @@ impl Attacks { let mut attacks = [[0; 64]; 2]; for index in 0..64 { let square = 1u64 << index; - attacks[Color::White as usize][index] = ((square & NOT_A_FILE) << 7) | ((square & NOT_H_FILE) << 9); - attacks[Color::Black as usize][index] = ((square & NOT_A_FILE) >> 9) | ((square & NOT_H_FILE) >> 7); + attacks[Color::White as usize][index] = + ((square & NOT_A_FILE) << 7) | ((square & NOT_H_FILE) << 9); + attacks[Color::Black as usize][index] = + ((square & NOT_A_FILE) >> 9) | ((square & NOT_H_FILE) >> 7); } attacks } @@ -92,10 +94,10 @@ impl Attacks { for index in 0..64 { let square = 1u64 << index; - pushes [Color::White as usize][index] = (square << 8); + pushes[Color::White as usize][index] = (square << 8); double_pushes[Color::White as usize][index] = ((square & RANK_2) << 16); - pushes [Color::Black as usize][index] = (square >> 8); + pushes[Color::Black as usize][index] = (square >> 8); double_pushes[Color::Black as usize][index] = ((square & RANK_7) >> 16); } (pushes, double_pushes) @@ -106,15 +108,14 @@ impl Attacks { for (index, bitboard) in attacks.iter_mut().enumerate() { let square_bb = Square::from(index as u8).to_bitboard(); - *bitboard = - ((square_bb & NOT_A_FILE & NOT_B_FILE) << 6) | - ((square_bb & NOT_G_FILE & NOT_H_FILE) << 10) | - ((square_bb & NOT_A_FILE) << 15) | - ((square_bb & NOT_H_FILE) << 17) | - ((square_bb & NOT_G_FILE & NOT_H_FILE) >> 6) | - ((square_bb & NOT_A_FILE & NOT_B_FILE) >> 10) | - ((square_bb & NOT_H_FILE) >> 15) | - ((square_bb & NOT_A_FILE) >> 17); + *bitboard = ((square_bb & NOT_A_FILE & NOT_B_FILE) << 6) + | ((square_bb & NOT_G_FILE & NOT_H_FILE) << 10) + | ((square_bb & NOT_A_FILE) << 15) + | ((square_bb & NOT_H_FILE) << 17) + | ((square_bb & NOT_G_FILE & NOT_H_FILE) >> 6) + | ((square_bb & NOT_A_FILE & NOT_B_FILE) >> 10) + | ((square_bb & NOT_H_FILE) >> 15) + | ((square_bb & NOT_A_FILE) >> 17); } attacks } @@ -124,20 +125,18 @@ impl Attacks { for (index, bitboard) in attacks.iter_mut().enumerate() { let square_bb = Square::from(index as u8).to_bitboard(); - *bitboard = - ((square_bb & NOT_A_FILE) >> 1) | - ((square_bb & NOT_A_FILE) << 7) | - ((square_bb & NOT_A_FILE) >> 9) | - ((square_bb & NOT_H_FILE) << 1) | - ((square_bb & NOT_H_FILE) >> 7) | - ((square_bb & NOT_H_FILE) << 9) | - (square_bb << 8) | - (square_bb >> 8); + *bitboard = ((square_bb & NOT_A_FILE) >> 1) + | ((square_bb & NOT_A_FILE) << 7) + | ((square_bb & NOT_A_FILE) >> 9) + | ((square_bb & NOT_H_FILE) << 1) + | ((square_bb & NOT_H_FILE) >> 7) + | ((square_bb & NOT_H_FILE) << 9) + | (square_bb << 8) + | (square_bb >> 8); } attacks } - // Compute rook-like attacks on the first rank based on // occupancy and rook file. fn precompute_first_rank_attacks() -> FirstRankAttacks { @@ -164,7 +163,7 @@ impl Attacks { } } - for index in left_bound..right_bound+1 { + for index in left_bound..right_bound + 1 { if index != file { attacks[occupancy as usize][file as usize] |= 1 << index; } @@ -260,11 +259,17 @@ impl Attacks { /// /// Given a square and occupancy masked for rank, diagonal or anti-diagonal (note: not a file!) /// return an attack bitboard that considers blocking pieces - fn kindergarten_attacks_base(&self, occupancy: Bitboard, mask: Bitboard, square: Square) -> Bitboard { + fn kindergarten_attacks_base( + &self, + occupancy: Bitboard, + mask: Bitboard, + square: Square, + ) -> Bitboard { let file = square.file(); let masked_occupancy = occupancy & mask; let occupancy_rank = ((masked_occupancy as u128 * B_FILE as u128) >> 58 & 0b111111) << 1; - let rank_attacks = self.first_rank_attacks[occupancy_rank as usize][file as usize] as Bitboard; + let rank_attacks = + self.first_rank_attacks[occupancy_rank as usize][file as usize] as Bitboard; let mut filled_up_attacks = 0; for rank in 0..8 { @@ -274,38 +279,43 @@ impl Attacks { } /// https://www.chessprogramming.org/Kindergarten_Bitboards - fn kindergarten_attacks_file(&self, occupancy: Bitboard, mask: Bitboard, square: Square) -> Bitboard { + fn kindergarten_attacks_file( + &self, + occupancy: Bitboard, + mask: Bitboard, + square: Square, + ) -> Bitboard { let file = square.file(); let rank = square.rank(); let masked_occupancy = (occupancy & mask) >> file; // Shift occupancy to A file - let occupancy_rank = ((masked_occupancy as u128 * DIAG_C2_H7 as u128) >> 58 & 0b111111) << 1; + let occupancy_rank = + ((masked_occupancy as u128 * DIAG_C2_H7 as u128) >> 58 & 0b111111) << 1; // Use reversed rank as index, since occupancy is reversed - let rank_attacks = self.first_rank_attacks[occupancy_rank as usize][7 - rank as usize] as Bitboard; + let rank_attacks = + self.first_rank_attacks[occupancy_rank as usize][7 - rank as usize] as Bitboard; ((rank_attacks as u128 * DIAG_A1_H8 as u128) as Bitboard & H_FILE) >> (7 - file) } pub fn bishop(&self, occupancy: Bitboard, square: Square) -> Bitboard { - let diagonal_mask = - self.ray_attacks[Direction::NoEa as usize][square as usize] | - self.ray_attacks[Direction::SoWe as usize][square as usize]; - let anti_diagonal_mask = - self.ray_attacks[Direction::NoWe as usize][square as usize] | - self.ray_attacks[Direction::SoEa as usize][square as usize]; - - self.kindergarten_attacks_base(occupancy, diagonal_mask, square) | self.kindergarten_attacks_base(occupancy, anti_diagonal_mask, square) + let diagonal_mask = self.ray_attacks[Direction::NoEa as usize][square as usize] + | self.ray_attacks[Direction::SoWe as usize][square as usize]; + let anti_diagonal_mask = self.ray_attacks[Direction::NoWe as usize][square as usize] + | self.ray_attacks[Direction::SoEa as usize][square as usize]; + + self.kindergarten_attacks_base(occupancy, diagonal_mask, square) + | self.kindergarten_attacks_base(occupancy, anti_diagonal_mask, square) } pub fn rook(&self, occupancy: Bitboard, square: Square) -> Bitboard { - let vertical = - self.ray_attacks[Direction::Nort as usize][square as usize] | - self.ray_attacks[Direction::Sout as usize][square as usize]; - let horizontal = - self.ray_attacks[Direction::West as usize][square as usize] | - self.ray_attacks[Direction::East as usize][square as usize]; - - self.kindergarten_attacks_file(occupancy, vertical, square) | self.kindergarten_attacks_base(occupancy, horizontal, square) + let vertical = self.ray_attacks[Direction::Nort as usize][square as usize] + | self.ray_attacks[Direction::Sout as usize][square as usize]; + let horizontal = self.ray_attacks[Direction::West as usize][square as usize] + | self.ray_attacks[Direction::East as usize][square as usize]; + + self.kindergarten_attacks_file(occupancy, vertical, square) + | self.kindergarten_attacks_base(occupancy, horizontal, square) } pub fn queen(&self, occupancy: Bitboard, square: Square) -> Bitboard { @@ -319,11 +329,10 @@ mod tests { use super::*; - static DEFAULT_OCCUPANCY: Bitboard = - 1 << Square::B7 as usize | - 1 << Square::B1 as usize | - 1 << Square::C2 as usize | - 1 << Square::F3 as usize; + static DEFAULT_OCCUPANCY: Bitboard = 1 << Square::B7 as usize + | 1 << Square::B1 as usize + | 1 << Square::C2 as usize + | 1 << Square::F3 as usize; #[test] fn pawn_attacks() { @@ -333,27 +342,60 @@ mod tests { white_attacks.print("Pawn e4"); - assert_eq!(white_attacks, Square::D5.to_bitboard() | Square::F5.to_bitboard()); - - assert_eq!(attacks[Color::White as usize][Square::H4 as usize], Square::G5.to_bitboard()); - assert_eq!(attacks[Color::White as usize][Square::A4 as usize], Square::B5.to_bitboard()); - - assert_eq!(attacks[Color::White as usize][Square::E8 as usize].pop_count(), 0); - assert_eq!(attacks[Color::Black as usize][Square::E1 as usize].pop_count(), 0); + assert_eq!( + white_attacks, + Square::D5.to_bitboard() | Square::F5.to_bitboard() + ); + + assert_eq!( + attacks[Color::White as usize][Square::H4 as usize], + Square::G5.to_bitboard() + ); + assert_eq!( + attacks[Color::White as usize][Square::A4 as usize], + Square::B5.to_bitboard() + ); + + assert_eq!( + attacks[Color::White as usize][Square::E8 as usize].pop_count(), + 0 + ); + assert_eq!( + attacks[Color::Black as usize][Square::E1 as usize].pop_count(), + 0 + ); } #[test] fn pawn_pushes() { let (pushes, double_pushes) = Attacks::precompute_pawn_pushes(); - assert_eq!(pushes[Color::White as usize][Square::E4 as usize], Square::E5.to_bitboard()); - assert_eq!(pushes[Color::White as usize][Square::A2 as usize], Square::A3.to_bitboard()); - assert_eq!(pushes[Color::Black as usize][Square::E4 as usize], Square::E3.to_bitboard()); - assert_eq!(pushes[Color::Black as usize][Square::H6 as usize], Square::H5.to_bitboard()); + assert_eq!( + pushes[Color::White as usize][Square::E4 as usize], + Square::E5.to_bitboard() + ); + assert_eq!( + pushes[Color::White as usize][Square::A2 as usize], + Square::A3.to_bitboard() + ); + assert_eq!( + pushes[Color::Black as usize][Square::E4 as usize], + Square::E3.to_bitboard() + ); + assert_eq!( + pushes[Color::Black as usize][Square::H6 as usize], + Square::H5.to_bitboard() + ); assert_eq!(double_pushes[Color::White as usize][Square::E4 as usize], 0); - assert_eq!(double_pushes[Color::White as usize][Square::A2 as usize], Square::A4.to_bitboard()); + assert_eq!( + double_pushes[Color::White as usize][Square::A2 as usize], + Square::A4.to_bitboard() + ); assert_eq!(double_pushes[Color::Black as usize][Square::E4 as usize], 0); - assert_eq!(double_pushes[Color::Black as usize][Square::H7 as usize], Square::H5.to_bitboard()); + assert_eq!( + double_pushes[Color::Black as usize][Square::H7 as usize], + Square::H5.to_bitboard() + ); } #[test] @@ -403,12 +445,30 @@ mod tests { fn first_rank_attacks() { let attacks = Attacks::precompute_first_rank_attacks(); // HGFEDCBA HGFEDCBA - assert_eq!(attacks[0b00010000][4], 0b11101111, "If rook is the only piece on a rank, it should be able to attack all rank"); - assert_eq!(attacks[0b00000000][4], 0b11101111, "Even with 0 occupancy rook should be able to attack all rank"); - assert_eq!(attacks[0b00000000][0], 0b11111110, "Even with 0 occupancy rook should be able to attack all rank"); - assert_eq!(attacks[0b00010001][4], 0b11101111, "If only other piece is on A rank, rook should be able to attack all rank"); - assert_eq!(attacks[0b10010000][4], 0b11101111, "If only other piece is on H rank, rook should be able to attack all rank"); - assert_eq!(attacks[0b10010001][4], 0b11101111, "If only other pieces are on A and H ranks, rook should be able to attack all rank"); + assert_eq!( + attacks[0b00010000][4], 0b11101111, + "If rook is the only piece on a rank, it should be able to attack all rank" + ); + assert_eq!( + attacks[0b00000000][4], 0b11101111, + "Even with 0 occupancy rook should be able to attack all rank" + ); + assert_eq!( + attacks[0b00000000][0], 0b11111110, + "Even with 0 occupancy rook should be able to attack all rank" + ); + assert_eq!( + attacks[0b00010001][4], 0b11101111, + "If only other piece is on A rank, rook should be able to attack all rank" + ); + assert_eq!( + attacks[0b10010000][4], 0b11101111, + "If only other piece is on H rank, rook should be able to attack all rank" + ); + assert_eq!( + attacks[0b10010001][4], 0b11101111, + "If only other pieces are on A and H ranks, rook should be able to attack all rank" + ); assert_eq!(attacks[0b00010100][4], 0b11101100); assert_eq!(attacks[0b01010100][4], 0b01101100); assert_eq!(attacks[0b01010010][4], 0b01101110); @@ -420,15 +480,14 @@ mod tests { fn ray_attacks() { let attacks = Attacks::precompute_ray_attacks(); let square = Square::E4 as usize; - let bitboard = - attacks[0][square] | - attacks[1][square] | - attacks[2][square] | - attacks[3][square] | - attacks[4][square] | - attacks[5][square] | - attacks[6][square] | - attacks[7][square]; + let bitboard = attacks[0][square] + | attacks[1][square] + | attacks[2][square] + | attacks[3][square] + | attacks[4][square] + | attacks[5][square] + | attacks[6][square] + | attacks[7][square]; bitboard.print("Rays from e4"); } @@ -454,12 +513,11 @@ mod tests { fn rook_attacks() { let attacks = Attacks::new(); let square = Square::E4; - let occupancy = - Square::B7.to_bitboard() | - Square::B1.to_bitboard() | - Square::C2.to_bitboard() | - Square::E3.to_bitboard() | - Square::F3.to_bitboard(); + let occupancy = Square::B7.to_bitboard() + | Square::B1.to_bitboard() + | Square::C2.to_bitboard() + | Square::E3.to_bitboard() + | Square::F3.to_bitboard(); let bb = attacks.rook(occupancy, square); occupancy.print("Occupancy"); -- cgit v1.2.3