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}