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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use std::fmt;
use square::*;
use side::Side;
#[derive(PartialEq, PartialOrd, Copy, Clone)]
pub struct Castle(pub usize);
pub const QUEEN_SIDE: Castle = Castle(0);
pub const KING_SIDE: Castle = Castle(1);
const CASTLE_KING_MOVES: [[(Square, Square); 2]; 2] = [[(E1, C1), (E8, C8)], [(E1, G1), (E8, G8)]];
const CASTLE_ROOK_MOVES: [[(Square, Square); 2]; 2] = [[(A1, D1), (A8, D8)], [(H1, F1), (H8, F8)]];
#[inline]
pub fn castle_king_squares(side: Side, castle: Castle) -> (Square, Square) {
CASTLE_KING_MOVES[castle.to_usize()][side.to_usize()]
}
#[inline]
pub fn castle_rook_squares(side: Side, castle: Castle) -> (Square, Square) {
CASTLE_ROOK_MOVES[castle.to_usize()][side.to_usize()]
}
impl Castle {
#[inline]
pub fn new(s: usize) -> Castle {
Castle(s)
}
#[inline]
pub fn to_usize(&self) -> usize {
self.0
}
#[inline]
pub fn to_u8(&self) -> u8 {
self.0 as u8
}
pub fn pgn_string(&self) -> &'static str {
if *self == QUEEN_SIDE { "O-O-O" } else { "O-O" }
}
#[inline]
pub fn iter() -> CastlesIter {
CastlesIter(QUEEN_SIDE)
}
}
#[derive(Debug)]
pub struct CastlesIter(Castle);
impl Iterator for CastlesIter {
type Item = Castle;
fn next(&mut self) -> Option<Castle> {
let castle = self.0;
if castle > KING_SIDE {
return None;
}
(self.0).0 += 1;
Some(castle)
}
}
impl fmt::Display for Castle {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.pgn_string())
}
}
impl fmt::Debug for Castle {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.pgn_string())
}
}
#[cfg(test)]
mod test {
use super::*;
use side::*;
#[test]
fn test_castle_squares() {
let qs_king_squares = castle_king_squares(WHITE, QUEEN_SIDE);
assert_eq!(qs_king_squares, (E1, C1));
let qs_rook_squares = castle_rook_squares(WHITE, QUEEN_SIDE);
assert_eq!(qs_rook_squares, (A1, D1));
}
}