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 pub fn to_index(&self) -> usize {
29 *self as usize
30 }
31
32 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
120impl 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}