Skip to main content

bitboard_minimal/
lib.rs

1use std::fmt;
2
3pub type BitBoard = u64;
4
5#[derive(PartialEq, Debug)]
6pub enum Side {
7    White,
8    Black
9}
10
11#[derive(PartialEq)]
12pub struct Board {
13    pub white_pawn: BitBoard,
14    pub black_pawn: BitBoard,
15
16    pub white_knight: BitBoard,
17    pub black_knight: BitBoard,
18
19    pub white_bishop: BitBoard,
20    pub black_bishop: BitBoard,
21
22    pub white_rook: BitBoard,
23    pub black_rook: BitBoard,
24
25    pub white_queen: BitBoard,
26    pub black_queen: BitBoard,
27
28    pub white_king: BitBoard,
29    pub black_king: BitBoard,
30
31    pub white_pieces: BitBoard,
32    pub black_pieces: BitBoard,
33    pub all_pieces: BitBoard,
34
35    pub side: Side,
36}
37
38impl Board {
39    pub fn new() -> Self {
40        return Board {
41            white_pawn: 0,
42            black_pawn: 0,
43            white_knight: 0,
44            black_knight: 0,
45            white_bishop: 0,
46            black_bishop: 0,
47            white_rook: 0,
48            black_rook: 0,
49            white_queen: 0,
50            black_queen: 0,
51            white_king: 0,
52            black_king: 0,
53            white_pieces: 0,
54            black_pieces: 0,
55            all_pieces: 0,
56            side: Side::White
57        }
58    }
59
60    pub fn new_from_fen(fen: &str) -> Self {
61        let mut board: Board = Self::new();
62
63        let mut rank: u8 = 7;
64        let mut file: u8 = 0;
65
66        for (i, c) in fen.chars().enumerate() {
67            match c {
68                ' ' => {
69                    board.side = match fen.as_bytes()[i+1] {
70                        119 => {Side::White}
71                        98 => {Side::Black}
72                        _ => {Side::White}
73                    };
74
75                    break;
76                }
77
78                '/' => {
79                    rank -= 1; file = 0; 
80                    continue;
81                }
82
83                'p' => {board.black_pawn   |= 1u64 << (rank * 8 + file); board.black_pieces |= 1u64 << (rank * 8 + file); board.all_pieces |= 1u64 << (rank * 8 + file);}
84                'n' => {board.black_knight |= 1u64 << (rank * 8 + file); board.black_pieces |= 1u64 << (rank * 8 + file); board.all_pieces |= 1u64 << (rank * 8 + file);}
85                'b' => {board.black_bishop |= 1u64 << (rank * 8 + file); board.black_pieces |= 1u64 << (rank * 8 + file); board.all_pieces |= 1u64 << (rank * 8 + file);}
86                'r' => {board.black_rook   |= 1u64 << (rank * 8 + file); board.black_pieces |= 1u64 << (rank * 8 + file); board.all_pieces |= 1u64 << (rank * 8 + file);}
87                'q' => {board.black_queen  |= 1u64 << (rank * 8 + file); board.black_pieces |= 1u64 << (rank * 8 + file); board.all_pieces |= 1u64 << (rank * 8 + file);}
88                'k' => {board.black_king   |= 1u64 << (rank * 8 + file); board.black_pieces |= 1u64 << (rank * 8 + file); board.all_pieces |= 1u64 << (rank * 8 + file);}
89
90                'P' => {board.white_pawn   |= 1u64 << (rank * 8 + file); board.white_pieces |= 1u64 << (rank * 8 + file); board.all_pieces |= 1u64 << (rank * 8 + file);}
91                'N' => {board.white_knight |= 1u64 << (rank * 8 + file); board.white_pieces |= 1u64 << (rank * 8 + file); board.all_pieces |= 1u64 << (rank * 8 + file);}
92                'B' => {board.white_bishop |= 1u64 << (rank * 8 + file); board.white_pieces |= 1u64 << (rank * 8 + file); board.all_pieces |= 1u64 << (rank * 8 + file);}
93                'R' => {board.white_rook   |= 1u64 << (rank * 8 + file); board.white_pieces |= 1u64 << (rank * 8 + file); board.all_pieces |= 1u64 << (rank * 8 + file);}
94                'Q' => {board.white_queen  |= 1u64 << (rank * 8 + file); board.white_pieces |= 1u64 << (rank * 8 + file); board.all_pieces |= 1u64 << (rank * 8 + file);}
95                'K' => {board.white_king   |= 1u64 << (rank * 8 + file); board.white_pieces |= 1u64 << (rank * 8 + file); board.all_pieces |= 1u64 << (rank * 8 + file);}
96                _   => {}
97            }
98
99            let as_number = c as i8 - '0' as i8;
100            if as_number > 0 && as_number < 10 {file += as_number as u8; continue;}
101
102            file += 1;
103        }
104        return board;
105    }
106}
107
108impl fmt::Debug for Board {
109    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110        write!(f, "Board: {{\n\twhite_pawn:   {:#064b}", self.white_pawn).unwrap();
111        write!(f, "\n\tblack_pawn:   {:#064b}", self.black_pawn).unwrap();
112        write!(f, "\n\twhite_knight: {:#064b}", self.white_knight).unwrap();
113        write!(f, "\n\tblack_knight: {:#064b}", self.black_knight).unwrap();
114        write!(f, "\n\twhite_bishop: {:#064b}", self.white_bishop).unwrap();
115        write!(f, "\n\tblack_bishop: {:#064b}", self.black_bishop).unwrap();
116        write!(f, "\n\twhite_rook:   {:#064b}", self.white_rook).unwrap();
117        write!(f, "\n\tblack_rook:   {:#064b}", self.black_rook).unwrap();
118        write!(f, "\n\twhite_queen:  {:#064b}", self.white_queen).unwrap();
119        write!(f, "\n\tblack_queen:  {:#064b}", self.black_queen).unwrap();
120        write!(f, "\n\twhite_king:   {:#064b}", self.white_king).unwrap();
121        write!(f, "\n\tblack_king:   {:#064b}", self.black_king).unwrap();
122        write!(f, "\n\twhite_pieces: {:#064b}", self.white_pieces).unwrap();
123        write!(f, "\n\tblack_pieces: {:#064b}", self.black_pieces).unwrap();
124        write!(f, "\n\tall_pieces:   {:#064b}\n", self.all_pieces).unwrap();
125        write!(f, "\n\tside:         {:?}\n}}\n", self.side)
126    }
127}
128
129pub const STARTING_FEN: &str = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR";
130pub const EMPTY_FEN:    &str = "8/8/8/8/8/8/8/8";
131
132#[cfg(test)]
133mod tests {
134    use super::*;
135
136    #[test]
137    fn test_new_from_fen() {
138        let mut board = Board::new_from_fen(STARTING_FEN);
139        assert!(board == Board {
140            white_pawn:   0b00000000000000000000000000000000000000000000001111111100000000,
141            black_pawn:   0b00000011111111000000000000000000000000000000000000000000000000,
142            white_knight: 0b00000000000000000000000000000000000000000000000000000001000010,
143            black_knight: 0b100001000000000000000000000000000000000000000000000000000000000,
144            white_bishop: 0b00000000000000000000000000000000000000000000000000000000100100,
145            black_bishop: 0b10010000000000000000000000000000000000000000000000000000000000,
146            white_rook:   0b00000000000000000000000000000000000000000000000000000010000001,
147            black_rook:   0b1000000100000000000000000000000000000000000000000000000000000000,
148            white_queen:  0b00000000000000000000000000000000000000000000000000000000001000,
149            black_queen:  0b00100000000000000000000000000000000000000000000000000000000000,
150            white_king:   0b00000000000000000000000000000000000000000000000000000000010000,
151            black_king:   0b01000000000000000000000000000000000000000000000000000000000000,
152            white_pieces: 0b00000000000000000000000000000000000000000000001111111111111111,
153            black_pieces: 0b1111111111111111000000000000000000000000000000000000000000000000,
154            all_pieces:   0b1111111111111111000000000000000000000000000000001111111111111111,
155            side: Side::White,
156        });
157
158        board = Board::new_from_fen(EMPTY_FEN);
159        assert!(board == Board::new());
160    }
161}