pub const DIR_OFFSETS: [i8; 8] = [1, -1, -8, 8, -7, -9, 9, 7];
pub const RAYS: [[u64; 8]; 64] = build_rays();
const fn build_rays() -> [[u64; 8]; 64] {
let mut table: [[u64; 8]; 64] = [[0u64; 8]; 64];
let mut sq: usize = 0;
while sq < 64 {
let mut d: usize = 0;
while d < 8 {
table[sq][d] = build_ray_for(sq as i8, DIR_OFFSETS[d]);
d += 1;
}
sq += 1;
}
table
}
const fn build_ray_for(square: i8, dir: i8) -> u64 {
let mut mask: u64 = 0;
let rank = square / 8;
let file = square % 8;
let (dr, df) = match dir {
1 => (0, 1), -1 => (0, -1), -8 => (-1, 0), 8 => (1, 0), -7 => (-1, 1), -9 => (-1, -1), 9 => (1, 1), 7 => (1, -1), _ => (0, 0),
};
let mut r = rank + dr;
let mut f = file + df;
while r >= 0 && r < 8 && f >= 0 && f < 8 {
let cur = r * 8 + f;
mask |= 1u64 << (cur as u8);
r += dr;
f += df;
}
mask
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn rays_table_nonzero() {
let mut found = 0;
for row in RAYS.iter() {
for &val in row.iter() {
found += (val != 0) as usize;
}
}
assert!(found > 0);
}
}