hermes_simd_intrinsics/bitboard/
hyperbola.rs1use hermes_simd_core::bitboard::BitBoardKernel;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7pub struct Hyperbola;
8
9const FILE_RAYS: [u64; 64] = {
10 let mut rays = [0u64; 64];
11 let mut sq = 0;
12 while sq < 64 {
13 rays[sq] = 0x0101010101010101u64 << (sq & 7);
14 sq += 1;
15 }
16 rays
17};
18
19const RANK_RAYS: [u64; 64] = {
20 let mut rays = [0u64; 64];
21 let mut sq = 0;
22 while sq < 64 {
23 rays[sq] = 0xFFu64 << (sq & 56);
24 sq += 1;
25 }
26 rays
27};
28
29const DIAGONAL_RAYS: [u64; 64] = {
30 let mut rays = [0u64; 64];
31 let mut sq = 0;
32 while sq < 64 {
33 let s_file = (sq & 7) as i32;
34 let s_rank = (sq >> 3) as i32;
35 let mut mask = 0u64;
36 let mut f = 0;
37 while f < 8 {
38 let r = s_rank + (f - s_file);
39 if r >= 0 && r < 8 {
40 mask |= 1u64 << (r * 8 + f);
41 }
42 f += 1;
43 }
44 rays[sq] = mask;
45 sq += 1;
46 }
47 rays
48};
49
50const ANTIDIAGONAL_RAYS: [u64; 64] = {
51 let mut rays = [0u64; 64];
52 let mut sq = 0;
53 while sq < 64 {
54 let s_file = (sq & 7) as i32;
55 let s_rank = (sq >> 3) as i32;
56 let mut mask = 0u64;
57 let mut f = 0;
58 while f < 8 {
59 let r = s_rank - (f - s_file);
60 if r >= 0 && r < 8 {
61 mask |= 1u64 << (r * 8 + f);
62 }
63 f += 1;
64 }
65 rays[sq] = mask;
66 sq += 1;
67 }
68 rays
69};
70
71#[inline(always)]
72fn file_ray(square: u8) -> u64 {
73 FILE_RAYS[square as usize]
74}
75
76#[inline(always)]
77fn rank_ray(square: u8) -> u64 {
78 RANK_RAYS[square as usize]
79}
80
81#[inline(always)]
82fn diagonal_ray(square: u8) -> u64 {
83 DIAGONAL_RAYS[square as usize]
84}
85
86#[inline(always)]
87fn antidiagonal_ray(square: u8) -> u64 {
88 ANTIDIAGONAL_RAYS[square as usize]
89}
90
91#[inline(always)]
93pub fn hyperbola_quintessence(square: u8, occupancy: u64, ray_mask: u64) -> u64 {
94 let slider = 1u64 << square;
95 let o = occupancy & ray_mask;
96
97 let forward = o.wrapping_sub(slider.wrapping_mul(2)) ^ o;
99
100 let o_rev = o.reverse_bits();
102 let slider_rev = slider.reverse_bits();
103 let backward = o_rev.wrapping_sub(slider_rev.wrapping_mul(2)) ^ o_rev;
104
105 ((forward & ray_mask) | (backward.reverse_bits() & ray_mask)) & !slider
107}
108
109impl BitBoardKernel for Hyperbola {
110 #[inline]
111 fn rook_attacks(square: u8, occupancy: u64) -> u64 {
112 hyperbola_quintessence(square, occupancy, file_ray(square))
113 | hyperbola_quintessence(square, occupancy, rank_ray(square))
114 }
115
116 #[inline]
117 fn bishop_attacks(square: u8, occupancy: u64) -> u64 {
118 hyperbola_quintessence(square, occupancy, diagonal_ray(square))
119 | hyperbola_quintessence(square, occupancy, antidiagonal_ray(square))
120 }
121}