rustenginelib/
bitboard.rs

1use crate::constants::*;
2use crate::square::*;
3
4/// Bitboard type represents the squares of a 8x8 chess board as bits of an unsigned 64 bit integer
5pub type Bitboard = u64;
6
7/// Bitboard trait adds functions to an u64 that allow treating it as a chess engine bitboard
8pub trait BitboardTrait {
9    /// returns a string that represents the bitboard as pretty print string
10    fn pretty_print_string(&self) -> String;
11    /// pops a bitboard with only one bit set from the bitboard and returns it
12    /// together with a bool indicating whether the pop was succesful
13    fn pop_bitboard(&mut self) -> (Bitboard, bool);
14    /// pops a square from the bitboard and returns it
15    /// together with a bool indicating whether the pop was succesful
16    fn pop_square(&mut self) -> (Square, bool);
17    /// returns the number of ways the 1 bits in the bitboard can be set to either 1 or 0
18    fn variation_count(self) -> usize;
19}
20
21/// BitboardTrait adds methods to Bitboard
22impl BitboardTrait for Bitboard {
23    /// returns a string that represents the bitboard as pretty print string
24    fn pretty_print_string(&self) -> String {
25        let mut bb = *self;
26        let mut buff = "".to_string();
27        let mut bits = 0;
28        loop {
29            if bits % 8 == 0 {
30                buff += &format!("{}", NUM_FILES - bits / 8).to_string();
31            }
32            if bb & (1 << 63) != 0 {
33                buff += "1"
34            } else {
35                buff += "."
36            }
37            if bits % 8 == 7 {
38                buff += "*\n"
39            }
40            bb = bb << 1;
41            bits = bits + 1;
42            if bits == 64 {
43                break;
44            }
45        }
46        format! {"bitboard {:#016x}\n**********\n{}*abcdefgh*\n", &self, buff}
47    }
48
49    /// pops a bitboard with only one bit set from the bitboard and returns it
50    /// together with a bool indicating whether the pop was succesful
51    fn pop_bitboard(&mut self) -> (Bitboard, bool) {
52        if *self == 0 {
53            return (0, false);
54        }
55
56        let bb = 1 << (self.trailing_zeros() as usize);
57
58        *self &= !bb;
59
60        return (bb, true);
61    }
62
63    /// pops a square from the bitboard and returns it
64    /// together with a bool indicating whether the pop was succesful
65    fn pop_square(&mut self) -> (Square, bool) {
66        let (bb, ok) = self.pop_bitboard();
67
68        if ok {
69            let tzs = bb.trailing_zeros() as usize;
70
71            (
72                rank_file(tzs / NUM_FILES, LAST_FILE - (tzs % NUM_FILES)),
73                true,
74            )
75        } else {
76            (0, false)
77        }
78    }
79
80    /// returns the number of ways the 1 bits in the bitboard can be set to either 1 or 0
81    fn variation_count(self) -> usize {
82        1 << self.count_ones()
83    }
84}