1use crate::mv::Move;
2use crate::square::*;
3use crate::piece::Piece;
4use crate::position::*;
5
6pub struct Board {
7 position: Position,
8 stack: Vec<StackElem>,
9}
10
11#[derive(Clone)]
12struct StackElem {
13 pub key: u64,
14 pub captured: Option<(Piece, Square)>,
15 pub state: State,
16 pub mv: Move,
17}
18
19impl Board {
20 #[allow(dead_code)]
21 pub fn new(fen: &str) -> Board {
22 let position = Position::from_fen(fen).unwrap();
23
24 Board {
25 position,
26 stack: Vec::new(),
27 }
28 }
29
30 #[allow(dead_code)]
31 pub fn position(&self) -> &Position {
32 &self.position
33 }
34
35 #[allow(dead_code)]
36 pub fn key(&self) -> u64 {
37 self.position.hash_key()
38 }
39
40 #[allow(dead_code)]
41 pub fn depth(&self) -> usize {
42 self.stack.len()
43 }
44
45 #[allow(dead_code)]
46 pub fn make(&mut self, mv: Move) {
47 let state = self.position.state().clone();
48 let key = self.position.hash_key();
49 let captured = self.position.make(mv);
50
51 self.stack.push(StackElem {
52 key,
53 captured,
54 state,
55 mv,
56 })
57 }
58
59 #[allow(dead_code)]
60 pub fn unmake(&mut self) {
61 let elem = self.stack.pop().unwrap();
62 self.position
63 .unmake(elem.mv, elem.captured, &elem.state, elem.key);
64 }
65}
66
67#[cfg(test)]
68mod test {
69 use super::*;
70
71 #[test]
72 fn test_key() {
73 let mut tree = Board::new(STARTING_POSITION_FEN);
75
76 let key_init = tree.key();
77
78 let mv_a = Move::new_push(D2, D4);
79 let mv_b = Move::new_push(G7, G5);
80 let mv_c = Move::new_push(B1, A3);
81 let mv_d = Move::new_push(G5, G4);
82
83 tree.make(mv_a);
84 tree.make(mv_b);
85 tree.make(mv_c);
86 tree.make(mv_d);
87
88 let key_after_moves = tree.key();
89
90 tree.unmake();
91 tree.unmake();
92 tree.unmake();
93 tree.unmake();
94
95 assert_eq!(tree.key(), key_init);
96
97 tree.make(mv_c);
98 tree.make(mv_b);
99 tree.make(mv_a);
100 tree.make(mv_d);
101
102 assert_eq!(tree.key(), key_after_moves);
103 }
104}