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}