From 0a890b42e8b701feed27faee4b0caf601f5bb258 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 21 Jan 2023 00:38:43 +0300 Subject: refactor: do not wrap Bitboard into struct --- src/bitboard.rs | 72 +++++++++++++++++++++++++++++++++++++++------------------ src/main.rs | 5 ---- 2 files changed, 49 insertions(+), 28 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); } } diff --git a/src/main.rs b/src/main.rs index e0d9912..3555c81 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,5 @@ mod bitboard; -use bitboard::*; fn main() { - const bb: Bitboard = Bitboard(127); println!("Hello, world!"); - println!("{}", bb); - println!("{}", bb.0); - println!("{}", bb.pop_count()); } -- cgit v1.2.3