diff options
| author | eug-vs <eugene@eug-vs.xyz> | 2023-01-21 19:52:56 +0300 | 
|---|---|---|
| committer | eug-vs <eugene@eug-vs.xyz> | 2023-01-21 19:52:56 +0300 | 
| commit | d0a67b462b492f136c5d07f4a75819d3516652d5 (patch) | |
| tree | 407f8f24db4a6304a19887c9276d0ae2fbd16a91 /src | |
| parent | 7d93bee082fb561d80a8fe3e1c60a9fcb0a399ba (diff) | |
| download | chessnost-d0a67b462b492f136c5d07f4a75819d3516652d5.tar.gz | |
feat: precompute ray attacks
Diffstat (limited to 'src')
| -rw-r--r-- | src/attacks.rs | 126 | 
1 files changed, 115 insertions, 11 deletions
diff --git a/src/attacks.rs b/src/attacks.rs index a8daec9..97e4f37 100644 --- a/src/attacks.rs +++ b/src/attacks.rs @@ -4,7 +4,7 @@ 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 B_FILE:     Bitboard = 0x0202020202020202;  /// An array where N-th item is an attack bitboard  /// of a piece on N-th square @@ -21,21 +21,24 @@ pub type Byte = u8;  /// ```  type FirstRankAttacks = [[Byte; 8]; 256]; +enum Direction { +    Nort, +    NoEa, +    East, +    SoEa, +    Sout, +    SoWe, +    West, +    NoWe, +}  #[derive(Debug)]  pub struct Attacks {      pub knight: AttackTable,      pub king: AttackTable,      pub first_rank_attacks: FirstRankAttacks, - -    // pub nort_ray: AttackTable, -    // pub noea_ray: AttackTable, -    // pub east_ray: AttackTable, -    // pub soea_ray: AttackTable, -    // pub sout_ray: AttackTable, -    // pub sowe_ray: AttackTable, -    // pub west_ray: AttackTable, -    // pub nowe_ray: AttackTable, +    /// Should be indexed by Direction +    pub ray_attacks: [AttackTable; 8],  }  #[allow(unused)] @@ -44,11 +47,13 @@ impl Attacks {          let knight = Self::precompute_knight_attacks();          let king = Self::precompute_king_attacks();          let first_rank_attacks = Self::precompute_first_rank_attacks(); +        let ray_attacks = Self::precompute_ray_attacks();          Self {              knight,              king,              first_rank_attacks, +            ray_attacks,          }      } @@ -121,11 +126,93 @@ impl Attacks {          }          attacks      } + +    fn precompute_ray_attacks() -> [AttackTable; 8] { +        let mut nort = [0; 64]; +        let mut noea = [0; 64]; +        let mut east = [0; 64]; +        let mut soea = [0; 64]; +        let mut sout = [0; 64]; +        let mut sowe = [0; 64]; +        let mut west = [0; 64]; +        let mut nowe = [0; 64]; + +        for rank in 0..8 { +            for file in 0..8 { +                let index = rank * 8 + file; +                { +                    let mut rank = rank; +                    while rank != 7 { +                        rank += 1; +                        nort[index] |= 1 << (rank * 8 + file); +                    } +                } +                { +                    let mut rank = rank; +                    let mut file = file; +                    while (rank < 7) && (file < 7) { +                        rank += 1; +                        file += 1; +                        noea[index] |= 1 << (rank * 8 + file); +                    } +                } +                { +                    let mut file = file; +                    while file < 7 { +                        file += 1; +                        east[index] |= 1 << (rank * 8 + file); +                    } +                } +                { +                    let mut rank = rank; +                    let mut file = file; +                    while (rank > 0) && (file < 7) { +                        rank -= 1; +                        file += 1; +                        soea[index] |= 1 << (rank * 8 + file); +                    } +                } +                { +                    let mut rank = rank; +                    while rank > 0 { +                        rank -= 1; +                        sout[index] |= 1 << (rank * 8 + file); +                    } +                } +                { +                    let mut rank = rank; +                    let mut file = file; +                    while (rank > 0) && (file > 0) { +                        rank -= 1; +                        file -= 1; +                        sowe[index] |= 1 << (rank * 8 + file); +                    } +                } +                { +                    let mut file = file; +                    while file > 0 { +                        file -= 1; +                        west[index] |= 1 << (rank * 8 + file); +                    } +                } +                { +                    let mut rank = rank; +                    let mut file = file; +                    while (file > 0) && (rank < 7) { +                        file -= 1; +                        rank += 1; +                        nowe[index] |= 1 << (rank * 8 + file); +                    } +                } +            } +        } +        [nort, noea, east, soea, sout, sowe, west, nowe] +    }  }  #[cfg(test)]  mod tests { -    use crate::{bitboard::pop_count, board::Square}; +    use crate::{bitboard::{pop_count, print}, board::Square};      use super::*; @@ -180,4 +267,21 @@ mod tests {          assert_eq!(attacks[0b01010010][4], 0b01101110);      } + +    #[test] +    fn test_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]; +        print(bitboard); +    }  }  |