chess/
castle_rights.rs

1use crate::Color;
2
3/// What castle rights does a particular player have?
4///
5/// > rule: <https://en.wikipedia.org/wiki/Castling>
6#[derive(Debug, Clone, Copy, PartialOrd, PartialEq, Eq)]
7pub enum CastleRights {
8    /// No right to Castle.
9    NoRights,
10    /// Right to Castle only on King side (little Castle).
11    KingSide,
12    /// Right to Castle only on Queen side (big Castle).
13    QueenSide,
14    /// Right to Castle in both side (little and big Castle).
15    Both,
16}
17
18impl CastleRights {
19    /// Convert [`usize`] to [`CastleRights`].
20    ///
21    /// # Panics
22    ///
23    /// Panic if index is not in range 0..=3.
24    pub fn from_index(index: usize) -> CastleRights {
25        match index {
26            0 => CastleRights::NoRights,
27            1 => CastleRights::KingSide,
28            2 => CastleRights::QueenSide,
29            3 => CastleRights::Both,
30            e => panic!("IndexError for CastleRights: {}", e),
31        }
32    }
33
34    /// Convert [`CastleRights`] to [`usize`].
35    pub fn to_index(&self) -> usize {
36        *self as usize
37    }
38
39    /// Check the castling on the king side.
40    pub fn has_kingside(&self) -> bool {
41        self.to_index() & 1 == 1
42    }
43
44    /// Check the castling on the queen side.
45    pub fn has_queenside(&self) -> bool {
46        self.to_index() & 2 == 2
47    }
48
49    /// Convert the castle rights to an FEN compatible [`String`].
50    ///
51    /// ```
52    /// use chess::{CastleRights, Color};
53    ///
54    /// assert_eq!(CastleRights::NoRights.to_string(Color::Black), "");
55    /// assert_eq!(CastleRights::KingSide.to_string(Color::White), "K");
56    /// assert_eq!(CastleRights::QueenSide.to_string(Color::Black), "q");
57    /// assert_eq!(CastleRights::Both.to_string(Color::White), "KQ");
58    /// ```
59    pub fn to_string(&self, color: Color) -> String {
60        let result = match *self {
61            CastleRights::NoRights => "",
62            CastleRights::KingSide => "k",
63            CastleRights::QueenSide => "q",
64            CastleRights::Both => "kq",
65        };
66
67        match color {
68            Color::White => result.to_uppercase(),
69            Color::Black => result.to_string(),
70        }
71    }
72}