chess_move_gen/
castle.rs

1use crate::square::*;
2use crate::side::Side;
3use std::fmt;
4
5/// Represents a castleove
6#[derive(PartialEq, PartialOrd, Copy, Clone)]
7pub struct Castle(pub usize);
8
9pub const QUEEN_SIDE: Castle = Castle(0);
10pub const KING_SIDE: Castle = Castle(1);
11
12const CASTLE_KING_MOVES: [[(Square, Square); 2]; 2] = [[(E1, C1), (E8, C8)], [(E1, G1), (E8, G8)]];
13const CASTLE_ROOK_MOVES: [[(Square, Square); 2]; 2] = [[(A1, D1), (A8, D8)], [(H1, F1), (H8, F8)]];
14
15pub fn castle_king_squares(side: Side, castle: Castle) -> (Square, Square) {
16    CASTLE_KING_MOVES[castle.to_usize()][side.to_usize()]
17}
18
19pub fn castle_rook_squares(side: Side, castle: Castle) -> (Square, Square) {
20    CASTLE_ROOK_MOVES[castle.to_usize()][side.to_usize()]
21}
22
23impl Castle {
24    pub fn new(s: usize) -> Castle {
25        Castle(s)
26    }
27
28    pub const fn to_usize(&self) -> usize {
29        self.0
30    }
31
32    pub const fn to_u8(&self) -> u8 {
33        self.0 as u8
34    }
35
36    /// Convert to PGN string eg "O-O-O" or "O-O"
37    pub fn pgn_string(&self) -> &'static str {
38        if *self == QUEEN_SIDE { "O-O-O" } else { "O-O" }
39    }
40
41    pub fn iter() -> CastlesIter {
42        CastlesIter(QUEEN_SIDE)
43    }
44}
45
46#[derive(Debug)]
47pub struct CastlesIter(Castle);
48
49impl Iterator for CastlesIter {
50    type Item = Castle;
51
52    fn next(&mut self) -> Option<Castle> {
53        let castle = self.0;
54
55        if castle > KING_SIDE {
56            return None;
57        }
58
59        (self.0).0 += 1;
60
61        Some(castle)
62    }
63}
64
65impl fmt::Display for Castle {
66    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67        write!(f, "{}", self.pgn_string())
68    }
69}
70
71impl fmt::Debug for Castle {
72    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
73        write!(f, "{}", self.pgn_string())
74    }
75}
76
77#[cfg(test)]
78mod test {
79    use super::*;
80    use crate::side::*;
81
82    #[test]
83    fn test_castle_squares() {
84        let qs_king_squares = castle_king_squares(WHITE, QUEEN_SIDE);
85        assert_eq!(qs_king_squares, (E1, C1));
86        let qs_rook_squares = castle_rook_squares(WHITE, QUEEN_SIDE);
87        assert_eq!(qs_rook_squares, (A1, D1));
88    }
89}