aboutsummaryrefslogtreecommitdiff
path: root/src/bitboard.rs
diff options
context:
space:
mode:
authoreug-vs <eugene@eug-vs.xyz>2023-01-21 00:38:43 +0300
committereug-vs <eugene@eug-vs.xyz>2023-01-21 00:38:43 +0300
commit0a890b42e8b701feed27faee4b0caf601f5bb258 (patch)
tree25726e47382cda8637cce9834916e5a9e8f8a2f4 /src/bitboard.rs
parent3284607b0461e4bd4386b324f8bdf63835ed22c9 (diff)
downloadchessnost-0a890b42e8b701feed27faee4b0caf601f5bb258.tar.gz
refactor: do not wrap Bitboard into struct
Diffstat (limited to 'src/bitboard.rs')
-rw-r--r--src/bitboard.rs72
1 files changed, 49 insertions, 23 deletions
diff --git a/src/bitboard.rs b/src/bitboard.rs
index a2d34cb..6aba264 100644
--- a/src/bitboard.rs
+++ b/src/bitboard.rs
@@ -1,42 +1,68 @@
-use std::fmt;
+pub type Bitboard = u64;
-pub struct Bitboard(pub u64);
-
-impl fmt::Display for Bitboard {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- for index in 0..64 {
- f.write_str(if &self.0 >> index & 1 == 1 { "1" } else { "." });
- if (index + 1) % 8 == 0 {
- f.write_str("\n");
- }
+/// Print bitboard on screen in the same way squares appear in memory
+/// (i.e the board is actually flipped along X)
+pub fn print(bb: &Bitboard) {
+ for index in 0..64 {
+ print!("{}", if bb >> index & 1 == 1 { "1" } else { "." });
+ if (index + 1) % 8 == 0 {
+ println!();
}
- return write!(f, "\n")
}
+ return println!();
}
-impl Bitboard {
- pub fn pop_count(&self) -> i32 {
- if self.0 == 0 {
- return 0;
- }
- return Bitboard::pop_count(&Bitboard(self.0 >> 1)) + (self.0 & 1) as i32;
+/// Return bitboard cardinality, aka number of elements in the set
+pub fn pop_count(bb: &Bitboard) -> u8 {
+ if bb == &0u64 {
+ return 0;
}
+ return pop_count(&(bb >> 1)) + (bb & 1) as u8;
+}
+
+/// Return Bitboard with only Least Single Bit
+pub fn ls1b(bb: &Bitboard) -> u64 {
+ bb & !(bb - 1)
}
+/// Log base 2 (aka Trailing Zero Count)
+///
+/// WARNING: Only works for SINGLE Bitboards
+/// Useful for calculating bit-index of LS1B
+pub fn bitscan(bb: &Bitboard) -> u8 {
+ debug_assert!(pop_count(bb) == 1, "Bitscan only works for SINGLE Bitboards!");
+ pop_count(&(bb - 1))
+}
+
+
#[cfg(test)]
mod tests {
use super::*;
#[test]
- fn test_print() {
- const bb: Bitboard = Bitboard(127);
- println!("{}", bb);
+ fn test_pop_count() {
+ assert_eq!(pop_count(&127), 7);
}
#[test]
- fn test_pop_count() {
- const bb: Bitboard = Bitboard(127);
- assert_eq!(bb.pop_count(), 7);
+ fn test_ls1b() {
+ assert_eq!(ls1b(&38), 2);
+ assert_eq!(ls1b(&16), 16);
+ assert_eq!(ls1b(&20), 4);
+ }
+
+ #[test]
+ fn test_bitscan() {
+ assert_eq!(bitscan(&4), 2);
+ assert_eq!(bitscan(&16), 4);
+ assert_eq!(bitscan(&64), 6);
+ assert_eq!(bitscan(&128), 7);
+ }
+
+ #[test]
+ #[should_panic(expected = "Bitscan only works for SINGLE Bitboards!")]
+ fn test_bitscan_with_non_single_bb() {
+ bitscan(&5);
}
}