chess_move_gen/
board.rs

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        // Hash should not care what order moves are done in
74        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}