1use crate::file::File;
2use crate::rank::Rank;
3use crate::square::*;
4use std::fmt;
5use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Mul, Not};
6
7#[derive(PartialEq, Eq, PartialOrd, Clone, Copy, Debug, Default, Hash)]
27pub struct BitBoard(pub u64);
28
29pub const EMPTY: BitBoard = BitBoard(0);
39
40impl BitAnd for BitBoard {
42 type Output = BitBoard;
43
44 #[inline]
45 fn bitand(self, other: BitBoard) -> BitBoard {
46 BitBoard(self.0 & other.0)
47 }
48}
49
50impl BitAnd for &BitBoard {
51 type Output = BitBoard;
52
53 #[inline]
54 fn bitand(self, other: &BitBoard) -> BitBoard {
55 BitBoard(self.0 & other.0)
56 }
57}
58
59impl BitAnd<&BitBoard> for BitBoard {
60 type Output = BitBoard;
61
62 #[inline]
63 fn bitand(self, other: &BitBoard) -> BitBoard {
64 BitBoard(self.0 & other.0)
65 }
66}
67
68impl BitAnd<BitBoard> for &BitBoard {
69 type Output = BitBoard;
70
71 #[inline]
72 fn bitand(self, other: BitBoard) -> BitBoard {
73 BitBoard(self.0 & other.0)
74 }
75}
76
77impl BitOr for BitBoard {
79 type Output = BitBoard;
80
81 #[inline]
82 fn bitor(self, other: BitBoard) -> BitBoard {
83 BitBoard(self.0 | other.0)
84 }
85}
86
87impl BitOr for &BitBoard {
88 type Output = BitBoard;
89
90 #[inline]
91 fn bitor(self, other: &BitBoard) -> BitBoard {
92 BitBoard(self.0 | other.0)
93 }
94}
95
96impl BitOr<&BitBoard> for BitBoard {
97 type Output = BitBoard;
98
99 #[inline]
100 fn bitor(self, other: &BitBoard) -> BitBoard {
101 BitBoard(self.0 | other.0)
102 }
103}
104
105impl BitOr<BitBoard> for &BitBoard {
106 type Output = BitBoard;
107
108 #[inline]
109 fn bitor(self, other: BitBoard) -> BitBoard {
110 BitBoard(self.0 | other.0)
111 }
112}
113
114impl BitXor for BitBoard {
117 type Output = BitBoard;
118
119 #[inline]
120 fn bitxor(self, other: BitBoard) -> BitBoard {
121 BitBoard(self.0 ^ other.0)
122 }
123}
124
125impl BitXor for &BitBoard {
126 type Output = BitBoard;
127
128 #[inline]
129 fn bitxor(self, other: &BitBoard) -> BitBoard {
130 BitBoard(self.0 ^ other.0)
131 }
132}
133
134impl BitXor<&BitBoard> for BitBoard {
135 type Output = BitBoard;
136
137 #[inline]
138 fn bitxor(self, other: &BitBoard) -> BitBoard {
139 BitBoard(self.0 ^ other.0)
140 }
141}
142
143impl BitXor<BitBoard> for &BitBoard {
144 type Output = BitBoard;
145
146 #[inline]
147 fn bitxor(self, other: BitBoard) -> BitBoard {
148 BitBoard(self.0 ^ other.0)
149 }
150}
151
152impl BitAndAssign for BitBoard {
155 #[inline]
156 fn bitand_assign(&mut self, other: BitBoard) {
157 self.0 &= other.0;
158 }
159}
160
161impl BitAndAssign<&BitBoard> for BitBoard {
162 #[inline]
163 fn bitand_assign(&mut self, other: &BitBoard) {
164 self.0 &= other.0;
165 }
166}
167
168impl BitOrAssign for BitBoard {
170 #[inline]
171 fn bitor_assign(&mut self, other: BitBoard) {
172 self.0 |= other.0;
173 }
174}
175
176impl BitOrAssign<&BitBoard> for BitBoard {
177 #[inline]
178 fn bitor_assign(&mut self, other: &BitBoard) {
179 self.0 |= other.0;
180 }
181}
182
183impl BitXorAssign for BitBoard {
185 #[inline]
186 fn bitxor_assign(&mut self, other: BitBoard) {
187 self.0 ^= other.0;
188 }
189}
190
191impl BitXorAssign<&BitBoard> for BitBoard {
192 #[inline]
193 fn bitxor_assign(&mut self, other: &BitBoard) {
194 self.0 ^= other.0;
195 }
196}
197
198impl Mul for BitBoard {
200 type Output = BitBoard;
201
202 #[inline]
203 fn mul(self, other: BitBoard) -> BitBoard {
204 BitBoard(self.0.wrapping_mul(other.0))
205 }
206}
207
208impl Mul for &BitBoard {
209 type Output = BitBoard;
210
211 #[inline]
212 fn mul(self, other: &BitBoard) -> BitBoard {
213 BitBoard(self.0.wrapping_mul(other.0))
214 }
215}
216
217impl Mul<&BitBoard> for BitBoard {
218 type Output = BitBoard;
219
220 #[inline]
221 fn mul(self, other: &BitBoard) -> BitBoard {
222 BitBoard(self.0.wrapping_mul(other.0))
223 }
224}
225
226impl Mul<BitBoard> for &BitBoard {
227 type Output = BitBoard;
228
229 #[inline]
230 fn mul(self, other: BitBoard) -> BitBoard {
231 BitBoard(self.0.wrapping_mul(other.0))
232 }
233}
234
235impl Not for BitBoard {
237 type Output = BitBoard;
238
239 #[inline]
240 fn not(self) -> BitBoard {
241 BitBoard(!self.0)
242 }
243}
244
245impl Not for &BitBoard {
246 type Output = BitBoard;
247
248 #[inline]
249 fn not(self) -> BitBoard {
250 BitBoard(!self.0)
251 }
252}
253
254impl fmt::Display for BitBoard {
255 #[inline]
256 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
257 let mut s: String = "".to_owned();
258 for x in 0..64 {
259 if self.0 & (1u64 << x) == (1u64 << x) {
260 s.push_str("X ");
261 } else {
262 s.push_str(". ");
263 }
264 if x % 8 == 7 {
265 s.push_str("\n");
266 }
267 }
268 write!(f, "{}", s)
269 }
270}
271
272impl BitBoard {
273 #[inline]
275 pub fn new(b: u64) -> BitBoard {
276 BitBoard(b)
277 }
278
279 #[inline]
281 pub fn set(rank: Rank, file: File) -> BitBoard {
282 BitBoard::from_square(Square::make_square(rank, file))
283 }
284
285 #[inline]
287 pub fn from_square(sq: Square) -> BitBoard {
288 BitBoard(1u64 << sq.to_int())
289 }
290
291 #[inline]
293 pub fn from_maybe_square(sq: Option<Square>) -> Option<BitBoard> {
294 sq.map(|s| BitBoard::from_square(s))
295 }
296
297 #[inline]
299 pub fn to_square(&self) -> Square {
300 unsafe { Square::new(self.0.trailing_zeros() as u8) }
301 }
302
303 #[inline]
305 pub fn popcnt(&self) -> u32 {
306 self.0.count_ones()
307 }
308
309 #[inline]
311 pub fn reverse_colors(&self) -> BitBoard {
312 BitBoard(self.0.swap_bytes())
313 }
314
315 #[inline]
317 pub fn to_size(&self, rightshift: u8) -> usize {
318 (self.0 >> rightshift) as usize
319 }
320}
321
322impl Iterator for BitBoard {
324 type Item = Square;
325
326 #[inline]
327 fn next(&mut self) -> Option<Square> {
328 if self.0 == 0 {
329 None
330 } else {
331 let result = self.to_square();
332 *self ^= BitBoard::from_square(result);
333 Some(result)
334 }
335 }
336}