monster_chess/bitboard/
numops.rs1use super::BitBoard;
2use std::ops::{Add, AddAssign, Sub, SubAssign};
3
4impl<const T: usize> Add<BitBoard<T>> for BitBoard<T> {
5    type Output = Self;
6
7    fn add(self, rhs: BitBoard<T>) -> BitBoard<T> {
8        let mut bit_board = self.clone();
9        bit_board += rhs;
10        bit_board
11    }
12}
13
14impl<const T: usize> AddAssign<BitBoard<T>> for BitBoard<T> {
15    fn add_assign(&mut self, rhs: BitBoard<T>) {
16        if T == 1 {
17            self.bits[0] += rhs.bits[0];
18            return;
19        }
20
21        let mut carry = *self & rhs;
22        *self ^= rhs;
23        while carry.is_set() {
24            let shifted_carry = carry << 1;
25            carry = *self & shifted_carry;
26            *self ^= shifted_carry;
27        }
28    }
29}
30
31impl<const T: usize> Sub<BitBoard<T>> for BitBoard<T> {
32    type Output = Self;
33
34    fn sub(self, rhs: BitBoard<T>) -> BitBoard<T> {
35        let mut bit_board = self.clone();
36        bit_board -= rhs;
37        bit_board
38    }
39}
40
41impl<const T: usize> SubAssign<BitBoard<T>> for BitBoard<T> {
42    fn sub_assign(&mut self, rhs: BitBoard<T>) {
43        if T == 1 {
44            self.bits[0] -= rhs.bits[0];
45            return;
46        }
47
48        let mut rhs = rhs.clone();
49        while rhs.is_set() {
50            let borrow = !(*self) & rhs;
51            *self ^= rhs;
52            rhs = borrow << 1;
53        }
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use super::BitBoard;
60
61    #[test]
62    fn add() {
63        assert_eq!(
64            BitBoard::from_data([2, 13]) + BitBoard::from_data([4, 19]),
65            BitBoard::from_data([6, 32])
66        );
67        assert_eq!(
68            BitBoard::from_data([0, u128::MAX]) + BitBoard::from_data([0, 1]),
69            BitBoard::from_data([1, 0])
70        );
71    }
72
73    #[test]
74    fn sub() {
75        assert_eq!(
76            BitBoard::from_data([6, 32]) - BitBoard::from_data([4, 19]),
77            BitBoard::from_data([2, 13])
78        );
79        assert_eq!(
80            BitBoard::from_data([1, 0]) - BitBoard::from_data([0, 1]),
81            BitBoard::from_data([0, u128::MAX])
82        );
83    }
84}