monster_chess/bitboard/
bitscan.rs1use super::BitBoard;
2
3#[derive(Debug, Copy, Clone, PartialEq, Eq)]
5pub enum Direction {
6 LEFT,
7 RIGHT,
8}
9
10impl Direction {
11 pub fn opposite(&self) -> Direction {
12 match self {
13 Direction::RIGHT => Direction::LEFT,
14 Direction::LEFT => Direction::LEFT
15 }
16 }
17}
18
19impl<const T: usize> BitBoard<T> {
20 pub fn bitscan_forward(&self) -> u16 {
22 assert!(
23 self.is_set(),
24 "Bitscan Forward only works for non-empty BitBoards."
25 );
26
27 if T == 1 {
28 self.bits[0].trailing_zeros() as u16
29 } else {
30 let mut zeros: u16 = 0;
31 for i in (0..T).rev() {
32 let data = self.bits[i];
33 if data != 0 {
34 zeros += data.trailing_zeros() as u16;
35 break;
36 }
37
38 zeros += 128;
39 }
40 zeros
41 }
42 }
43
44 pub fn bitscan_reverse(&self) -> u16 {
46 assert!(
47 self.is_set(),
48 "Bitscan Reverse only works for non-empty BitBoards."
49 );
50
51 if T == 1 {
52 127 - self.bits[0].leading_zeros() as u16
53 } else {
54 let mut zeros: u16 = 0;
55 for i in 0..T {
56 let data = self.bits[i];
57 if data != 0 {
58 zeros += data.leading_zeros() as u16;
59 break;
60 }
61
62 zeros += 128;
63 }
64 (((T as u16) * 128) - 1) - zeros
65 }
66 }
67
68 pub fn bitscan(&self, direction: Direction) -> u16 {
70 match direction {
71 Direction::LEFT => self.bitscan_forward(),
72 Direction::RIGHT => self.bitscan_reverse(),
73 }
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::BitBoard;
80
81 #[test]
82 fn bitscan_forward() {
83 assert_eq!(BitBoard::from_data([0, 1]).bitscan_forward(), 0);
84 assert_eq!(BitBoard::from_data([1, 1]).bitscan_forward(), 0);
85 assert_eq!(BitBoard::from_data([3, 3]).bitscan_forward(), 0);
86 assert_eq!(BitBoard::from_data([1, 0]).bitscan_forward(), 128);
87 }
88
89 #[test]
90 fn bitscan_reverse() {
91 assert_eq!(BitBoard::from_data([0, 1]).bitscan_reverse(), 0);
92 assert_eq!(BitBoard::from_data([1, 1]).bitscan_reverse(), 128);
93 assert_eq!(BitBoard::from_data([3, 3]).bitscan_reverse(), 129);
94 assert_eq!(BitBoard::from_data([1, 0]).bitscan_reverse(), 128);
95 }
96}