diff options
| author | eug-vs <eugene@eug-vs.xyz> | 2023-01-23 08:47:23 +0300 | 
|---|---|---|
| committer | eug-vs <eugene@eug-vs.xyz> | 2023-01-23 08:55:01 +0300 | 
| commit | 6719e247a3e0c75261665eca166fc5c8c8fdaf27 (patch) | |
| tree | 29e286f0c7b7886a97737cddf0a2d303bfa1bbf9 /src | |
| parent | 208b35121f9dab4c60c82813b051eeabc9d502cd (diff) | |
| download | chessnost-6719e247a3e0c75261665eca166fc5c8c8fdaf27.tar.gz | |
refactor: separately store pawn double pushes
Diffstat (limited to 'src')
| -rw-r--r-- | src/attacks.rs | 28 | ||||
| -rw-r--r-- | src/board.rs | 21 | 
2 files changed, 33 insertions, 16 deletions
| diff --git a/src/attacks.rs b/src/attacks.rs index 5399c96..6762bb3 100644 --- a/src/attacks.rs +++ b/src/attacks.rs @@ -45,6 +45,7 @@ pub struct Attacks {      /// TODO: compute pawn attacks set-wise      pub pawn: [AttackTable; 2],      pub pawn_pushes: [AttackTable; 2], +    pub pawn_double_pushes: [AttackTable; 2],      pub first_rank_attacks: FirstRankAttacks,      /// Should be indexed by Direction @@ -59,13 +60,14 @@ impl Attacks {          let first_rank_attacks = Self::precompute_first_rank_attacks();          let ray_attacks = Self::precompute_ray_attacks();          let pawn = Self::precompute_pawn_attacks(); -        let pawn_pushes = Self::precompute_pawn_pushes(); +        let (pawn_pushes, pawn_double_pushes) = Self::precompute_pawn_pushes();          Self {              knight,              king,              pawn,              pawn_pushes, +            pawn_double_pushes,              first_rank_attacks,              ray_attacks,          } @@ -81,14 +83,19 @@ impl Attacks {          attacks      } -    fn precompute_pawn_pushes() -> [AttackTable; 2] { +    fn precompute_pawn_pushes() -> ([AttackTable; 2], [AttackTable; 2]) {          let mut pushes = [[0; 64]; 2]; +        let mut double_pushes = [[0; 64]; 2]; +          for index in 0..64 {              let square = 1u64 << index; -            pushes[Color::White as usize][index] = (square << 8) | ((square & RANK_2) << 16); -            pushes[Color::Black as usize][index] = (square >> 8) | ((square & RANK_6) >> 16); +            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); +            double_pushes[Color::Black as usize][index] = ((square & RANK_6) >> 16);          } -        pushes +        (pushes, double_pushes)      }      fn precompute_knight_attacks() -> AttackTable { @@ -332,11 +339,16 @@ mod tests {      #[test]      fn test_pawn_pushes() { -        let pushes = Attacks::precompute_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() | Square::A4.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() | Square::H4.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::Black as usize][Square::E4 as usize], 0); +        assert_eq!(double_pushes[Color::Black as usize][Square::H6 as usize], Square::H4.to_bitboard());      }      #[test] diff --git a/src/board.rs b/src/board.rs index 625711e..24bdefa 100644 --- a/src/board.rs +++ b/src/board.rs @@ -144,7 +144,8 @@ impl Board {      pub fn generate_moves(&self, color: Color) -> Vec<Move> {          let mut moves = Vec::with_capacity(1024);          let opponent_occupancy = self.color_occupancy(Color::from(1 - color as u8)); -        let available_targets = opponent_occupancy | self.empty(); +        let empty = self.empty(); +        let available_targets = opponent_occupancy | empty;          for (piece_type, piece) in self.pieces_by_color(color).iter().enumerate() {              match PieceType::from(piece_type) {                  PieceType::Pawn => { @@ -152,14 +153,18 @@ impl Board {                          for target in serialize_bitboard(self.attacks.pawn[color as usize][source as usize] & opponent_occupancy) {                              moves.push(Move { source, target });                          }; -                    } -                    for source in serialize_bitboard(*piece) {                          for target in serialize_bitboard(self.attacks.pawn_pushes[color as usize][source as usize] & available_targets) { -                            // Exclude double pushes in a monkey way -                            // TODO: properly rewrite this storing a separate bitboard for double pushes -                            if !((source as u8 / 8 == 1) && (target as u8 / 8 == 3) && (self.occupancy & (1 << (source as u8 + 8)) > 0)) { -                                moves.push(Move { source, target }); -                            } +                            moves.push(Move { source, target }); +                        }; +                    } + +                    let able_to_double_push_mask = match color { +                        Color::White => empty >> 8, +                        Color::Black => empty << 8, +                    }; +                    for source in serialize_bitboard(*piece & able_to_double_push_mask) { +                        for target in serialize_bitboard(self.attacks.pawn_double_pushes[color as usize][source as usize] & available_targets) { +                            moves.push(Move { source, target });                          };                      }                  } | 
