friendly_chess/chess/
square.rs

1use super::piece::*;
2use super::utils::{self, *};
3
4#[derive(Debug, Clone, Copy)]
5pub struct Square {
6    pub piece: Option<Piece>,
7}
8
9#[rustfmt::skip]
10#[derive(Clone, Copy, PartialEq, Eq, Debug)]
11#[repr(u8)]
12pub enum SquareCoordinate {
13    A8 = 0,   B8 = 1,   C8 = 2,     D8 = 3,     E8 = 4,     F8 = 5,     G8 = 6,     H8 = 7,
14    A7 = 16,  B7 = 17,  C7 = 18,    D7 = 19,    E7 = 20,    F7 = 21,    G7 = 22,    H7 = 23,
15    A6 = 32,  B6 = 33,  C6 = 34,    D6 = 35,    E6 = 36,    F6 = 37,    G6 = 38,    H6 = 39,
16    A5 = 48,  B5 = 49,  C5 = 50,    D5 = 51,    E5 = 52,    F5 = 53,    G5 = 54,    H5 = 55,
17    A4 = 64,  B4 = 65,  C4 = 66,    D4 = 67,    E4 = 68,    F4 = 69,    G4 = 70,    H4 = 71,
18    A3 = 80,  B3 = 81,  C3 = 82,    D3 = 83,    E3 = 84,    F3 = 85,    G3 = 86,    H3 = 87,
19    A2 = 96,  B2 = 97,  C2 = 98,    D2 = 99,    E2 = 100,   F2 = 101,   G2 = 102,   H2 = 103,
20    A1 = 112, B1 = 113, C1 = 114,   D1 = 115,   E1 = 116,   F1 = 117,   G1 = 118,   H1 = 119,
21
22
23    __BAD_COORD = 200
24}
25
26impl SquareCoordinate {
27    /// Convert a `Square` enum to its associated value (A8 = 0, B8 = 1, etc.)
28    pub fn to_index(&self) -> usize {
29        *self as usize
30    }
31
32    /// Convert square to standard algebraic notation
33    pub fn to_san(&self) -> String {
34        convert_index_to_algebraic_notation(self.to_index() as u8)
35    }
36
37    pub fn is_light_sq(&self) -> bool {
38        let rank = self.rank();
39        let file = self.file();
40        (rank % 2 == 0 && file % 2 != 0) || (rank % 2 != 0 && file % 2 == 0)
41    }
42
43    pub fn is_dark_sq(&self) -> bool {
44        let rank = self.rank();
45        let file = self.file();
46        (rank % 2 != 0 && file % 2 != 0) || (rank % 2 == 0 && file % 2 == 0)
47    }
48
49    pub fn rank(&self) -> u8 {
50        let idx = self.to_index() as u8;
51
52        8 - ((idx >> 4) + 1) + 1
53    }
54
55    pub fn file(&self) -> u8 {
56        let idx = self.to_index() as u8;
57
58        idx & 7
59    }
60
61    pub fn above(&self) -> ChessResult<Self> {
62        let idx = utils::is_valid(self.to_index() - 16)? as u8;
63
64        Ok(idx.to_coordinate())
65    }
66
67    pub fn below(&self) -> ChessResult<Self> {
68        let idx = utils::is_valid(self.to_index() + 16)? as u8;
69
70        Ok(idx.to_coordinate())
71    }
72
73    pub fn left(&self) -> ChessResult<Self> {
74        let idx = utils::is_valid(self.to_index() - 1)? as u8;
75
76        Ok(idx.to_coordinate())
77    }
78
79    pub fn right(&self) -> ChessResult<Self> {
80        let idx = utils::is_valid(self.to_index() + 1)? as u8;
81
82        Ok(idx.to_coordinate())
83    }
84
85    pub fn upper_left(&self) -> ChessResult<Self> {
86        let idx = utils::is_valid(self.to_index() - 17)? as u8;
87
88        Ok(idx.to_coordinate())
89    }
90
91    pub fn upper_right(&self) -> ChessResult<Self> {
92        let idx = utils::is_valid(self.to_index() - 15)? as u8;
93
94        Ok(idx.to_coordinate())
95    }
96
97    pub fn lower_left(&self) -> ChessResult<Self> {
98        let idx = utils::is_valid(self.to_index() + 15)? as u8;
99
100        Ok(idx.to_coordinate())
101    }
102
103    pub fn lower_right(&self) -> ChessResult<Self> {
104        let idx = utils::is_valid(self.to_index() + 17)? as u8;
105
106        Ok(idx.to_coordinate())
107    }
108
109    pub fn subtract(&self, rhs: usize) -> ChessResult<Self> {
110        let idx = utils::is_valid(self.to_index() - rhs)? as u8;
111
112        Ok(idx.to_coordinate())
113    }
114}
115
116pub trait SquareCoordinateExt {
117    fn to_coordinate(&self) -> SquareCoordinate;
118}
119
120// I made a little script to generate this, I am not crazy
121impl SquareCoordinateExt for u8 {
122    fn to_coordinate(&self) -> SquareCoordinate {
123        use SquareCoordinate::*;
124
125        match *self {
126            0 => A8,
127            1 => B8,
128            2 => C8,
129            3 => D8,
130            4 => E8,
131            5 => F8,
132            6 => G8,
133            7 => H8,
134            16 => A7,
135            17 => B7,
136            18 => C7,
137            19 => D7,
138            20 => E7,
139            21 => F7,
140            22 => G7,
141            23 => H7,
142            32 => A6,
143            33 => B6,
144            34 => C6,
145            35 => D6,
146            36 => E6,
147            37 => F6,
148            38 => G6,
149            39 => H6,
150            48 => A5,
151            49 => B5,
152            50 => C5,
153            51 => D5,
154            52 => E5,
155            53 => F5,
156            54 => G5,
157            55 => H5,
158            64 => A4,
159            65 => B4,
160            66 => C4,
161            67 => D4,
162            68 => E4,
163            69 => F4,
164            70 => G4,
165            71 => H4,
166            80 => A3,
167            81 => B3,
168            82 => C3,
169            83 => D3,
170            84 => E3,
171            85 => F3,
172            86 => G3,
173            87 => H3,
174            96 => A2,
175            97 => B2,
176            98 => C2,
177            99 => D2,
178            100 => E2,
179            101 => F2,
180            102 => G2,
181            103 => H2,
182            112 => A1,
183            113 => B1,
184            114 => C1,
185            115 => D1,
186            116 => E1,
187            117 => F1,
188            118 => G1,
189            119 => H1,
190            _ => __BAD_COORD,
191        }
192    }
193}