From d0a67b462b492f136c5d07f4a75819d3516652d5 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 21 Jan 2023 19:52:56 +0300 Subject: feat: precompute ray attacks --- src/attacks.rs | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file 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); + } } -- cgit v1.2.3