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