diff options
| -rw-r--r-- | src/bitboard.rs | 72 | ||||
| -rw-r--r-- | 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());  } | 
