1use std::fmt;
3use std::fmt::Formatter;
4use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Shl, Shr, Sub};
5use bits::pop_lsb;
6use rule::Square;
7
8#[derive(Clone, Copy)]
10pub union BitBoard {
11 merged_bitboard:u128,
12 bitboard:[u64; 2]
13}
14impl From<u128> for BitBoard {
15 #[inline]
16 fn from(bits: u128) -> Self {
17 BitBoard {
18 merged_bitboard: bits
19 }
20 }
21}
22impl Default for BitBoard {
23 #[inline]
24 fn default() -> Self {
25 BitBoard {
26 merged_bitboard: 0
27 }
28 }
29}
30impl From<BitBoard> for (u64,u64) {
31 #[inline]
32 fn from(bitboard: BitBoard) -> Self {
33 unsafe { (*bitboard.bitboard.get_unchecked(0), *bitboard.bitboard.get_unchecked(1)) }
34 }
35}
36impl BitOr for BitBoard {
37 type Output = Self;
38
39 #[inline]
40 fn bitor(self, rhs: Self) -> Self {
41 unsafe {
42 BitBoard { merged_bitboard: self.merged_bitboard | rhs.merged_bitboard }
43 }
44 }
45}
46impl BitAnd for BitBoard {
47 type Output = Self;
48
49 #[inline]
50 fn bitand(self, rhs: Self) -> Self::Output {
51 unsafe {
52 BitBoard { merged_bitboard: self.merged_bitboard & rhs.merged_bitboard }
53 }
54 }
55}
56impl BitAndAssign for BitBoard {
57 #[inline]
58 fn bitand_assign(&mut self, rhs: Self) {
59 *self = unsafe {
60 BitBoard { merged_bitboard: self.merged_bitboard & rhs.merged_bitboard }
61 }
62 }
63}
64impl BitOrAssign for BitBoard {
65 #[inline]
66 fn bitor_assign(&mut self, rhs: Self) {
67 *self = unsafe {
68 BitBoard { merged_bitboard: self.merged_bitboard | rhs.merged_bitboard }
69 }
70 }
71}
72impl BitXor for BitBoard {
73 type Output = Self;
74
75 #[inline]
76 fn bitxor(self, rhs: Self) -> Self {
77 unsafe {
78 BitBoard { merged_bitboard: self.merged_bitboard ^ rhs.merged_bitboard }
79 }
80 }
81}
82impl BitXorAssign for BitBoard {
83
84 #[inline]
85 fn bitxor_assign(&mut self, rhs: Self) {
86 unsafe {
87 self.merged_bitboard ^= rhs.merged_bitboard;
88 }
89 }
90}
91impl Not for BitBoard {
92 type Output = Self;
93
94 #[inline]
95 fn not(self) -> Self {
96 unsafe {
97 BitBoard { merged_bitboard: !self.merged_bitboard }
98 }
99 }
100}
101impl Sub for BitBoard {
102 type Output = Self;
103
104 #[inline]
105 fn sub(self, rhs: Self) -> Self::Output {
106 unsafe {
107 BitBoard { merged_bitboard: self.merged_bitboard - rhs.merged_bitboard }
108 }
109 }
110}
111impl PartialEq for BitBoard {
112 #[inline]
113 fn eq(&self,other:&BitBoard) -> bool {
114 unsafe { self.merged_bitboard == other.merged_bitboard }
115 }
116}
117impl BitOr<u128> for BitBoard {
118 type Output = Self;
119
120 #[inline]
121 fn bitor(self, rhs: u128) -> Self {
122 unsafe {
123 BitBoard { merged_bitboard: self.merged_bitboard | rhs }
124 }
125 }
126}
127impl BitAnd<u128> for BitBoard {
128 type Output = Self;
129
130 #[inline]
131 fn bitand(self, rhs: u128) -> Self::Output {
132 unsafe {
133 BitBoard { merged_bitboard: self.merged_bitboard & rhs }
134 }
135 }
136}
137impl BitAndAssign<u128> for BitBoard {
138 #[inline]
139 fn bitand_assign(&mut self, rhs: u128) {
140 *self = unsafe {
141 BitBoard { merged_bitboard: self.merged_bitboard & rhs }
142 }
143 }
144}
145impl BitOrAssign<u128> for BitBoard {
146 #[inline]
147 fn bitor_assign(&mut self, rhs: u128) {
148 *self = unsafe {
149 BitBoard { merged_bitboard: self.merged_bitboard | rhs }
150 }
151 }
152}
153impl BitXor<u128> for BitBoard {
154 type Output = Self;
155
156 #[inline]
157 fn bitxor(self, rhs: u128) -> Self {
158 unsafe {
159 BitBoard { merged_bitboard: self.merged_bitboard ^ rhs }
160 }
161 }
162}
163impl BitXorAssign<u128> for BitBoard {
164
165 #[inline]
166 fn bitxor_assign(&mut self, rhs: u128) {
167 unsafe {
168 self.merged_bitboard ^= rhs;
169 }
170 }
171}
172impl Sub<u128> for BitBoard {
173 type Output = Self;
174
175 #[inline]
176 fn sub(self, rhs: u128) -> Self::Output {
177 unsafe {
178 BitBoard { merged_bitboard: self.merged_bitboard - rhs }
179 }
180 }
181}
182impl Shl<u128> for BitBoard {
183 type Output = Self;
184
185 #[inline]
186 fn shl(self, rhs: u128) -> Self::Output {
187 BitBoard { merged_bitboard: unsafe { self.merged_bitboard } << rhs }
188 }
189}
190impl Shr<u128> for BitBoard {
191 type Output = Self;
192
193 #[inline]
194 fn shr(self, rhs: u128) -> Self::Output {
195 BitBoard { merged_bitboard: unsafe { self.merged_bitboard } >> rhs }
196 }
197}
198impl PartialEq<u128> for BitBoard {
199 #[inline]
200 fn eq(&self,other:&u128) -> bool {
201 unsafe { self.merged_bitboard == *other }
202 }
203}
204impl Eq for BitBoard {}
205impl fmt::Debug for BitBoard {
206 #[inline]
207 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
208 write!(f, "{}", unsafe { self.merged_bitboard })
209 }
210}
211impl BitAnd<BitBoard> for u128 {
212 type Output = BitBoard;
213
214 #[inline]
215 fn bitand(self, rhs: BitBoard) -> Self::Output {
216 unsafe {
217 BitBoard { merged_bitboard: self & rhs.merged_bitboard }
218 }
219 }
220}
221pub struct PopLsbIterByCallback<F> {
223 callback:F
224}
225impl BitBoard {
226 #[inline]
228 pub fn iter(self) -> impl Iterator<Item = Square> {
229 let br = (unsafe { *self.bitboard.get_unchecked(0) } == 0) as usize;
230 let bl = (unsafe { *self.bitboard.get_unchecked(1) } == 0) as usize;
231
232 let mut index = br + (bl & br);
233
234 let mut board = self;
235
236 PopLsbIterByCallback {
237 callback: move || {
238 if index == 2 {
239 None
240 } else {
241 let p = unsafe { board.bitboard.get_unchecked_mut(index) };
242
243 if *p == 0 {
244 return None;
245 }
246
247 let s = pop_lsb(&mut *p) as Square + index as Square * 64 - 1;
248
249 index += ((*p) == 0) as usize;
250
251 Some(s as Square)
252 }
253 }
254 }
255 }
256
257 #[inline]
259 pub fn reverse(self) -> BitBoard {
260 BitBoard {
261 merged_bitboard: unsafe { self.merged_bitboard.reverse_bits() >> 45 }
262 }
263 }
264
265 #[inline]
267 pub fn bitcount(self) -> usize {
268 unsafe {
269 self.bitboard.get_unchecked(0).count_ones() as usize + self.bitboard.get_unchecked(1).count_ones() as usize
270 }
271 }
272
273 #[inline]
275 pub fn wrapping_sub(self,rhs: u128) -> BitBoard {
276 BitBoard {
277 merged_bitboard: unsafe { self.merged_bitboard.wrapping_sub(rhs) }
278 }
279 }
280}
281impl<F> Iterator for PopLsbIterByCallback<F> where F: FnMut() -> Option<Square> {
282 type Item = Square;
283
284 #[inline]
285 fn next(&mut self) -> Option<Self::Item> {
286 (self.callback)()
287 }
288}