Chess Engine
A Chess Engine project written in C++.
Loading...
Searching...
No Matches
navigation.hpp
1#pragma once
2
3#include <sys/types.h>
4
5#include <array>
6#include <cstdint>
7#include <iostream>
8#include <string_view>
9
10#include "iterator.hpp"
11#include "piece.hpp"
12
13template <typename Derived>
14struct Coordinate : Iterable<Derived> {
15 public:
16 constexpr void set(uint8_t value) { m_value = value; }
17 [[nodiscard]] constexpr uint8_t value() const { return m_value; }
18
19 [[nodiscard]] constexpr bool ok() const { return m_value <= Derived::LAST; }
20
21 [[nodiscard]] static constexpr Derived none() { return Derived::NONE; }
22
23 [[nodiscard]] static constexpr uint8_t number() { return Derived::NB; }
24 [[nodiscard]] static constexpr uint8_t mask() { return Derived::MASK; }
25 [[nodiscard]] static constexpr uint8_t size() { return Derived::SIZE; }
26
27 constexpr operator uint8_t() { return m_value; }
28
29 friend std::ostream& operator<<(std::ostream& os, const Derived& obj) {
30 obj.print(os);
31 return os;
32 }
33
34 friend Derived;
35
36 private:
37 uint8_t m_value;
38
39 constexpr Coordinate(uint8_t value = none()) : m_value(value) {}
40};
41
42struct File : Coordinate<File> {
43 // clang-format off
44 enum : uint8_t {
45 FA, FB, FC, FD, FE, FF, FG, FH,
46
47 FIRST = FA,
48 LAST = FH,
49
50 NONE = 8,
51 MASK = 0b111,
52 SIZE = 3,
53 NB = 8
54 };
55 // clang-format on
56
57 static constexpr std::string_view fileToChar = "abcdefgh";
58
59 constexpr File(uint8_t value = none()) : Coordinate(value) {}
60 constexpr File(int value = none()) : Coordinate(value) {}
61 explicit constexpr File(char c) {
62 if (c >= 'a' && c <= 'h') {
63 m_value = static_cast<uint8_t>(c - 'a');
64 } else if (c >= 'A' && c <= 'H') {
65 m_value = static_cast<uint8_t>(c - 'A');
66 }
67 }
68
69 static constexpr uint8_t distance(File from, File to) { return from > to ? from - to : to - from; }
70
71 void print(std::ostream& os) const {
72 if (ok()) {
73 os << fileToChar[m_value];
74 } else
75 os << '?';
76 }
77};
78
79struct Rank : Coordinate<Rank> {
80 public:
81 // clang-format off
82 enum : uint8_t {
83 R1, R2, R3, R4, R5, R6, R7, R8,
84
85 FIRST = R1,
86 LAST = R8,
87
88 NONE = 8,
89 MASK = 0b111,
90 SIZE = 3,
91 NB = 8
92 };
93 // clang-format on
94
95 static constexpr std::string_view rankToChar = "12345678";
96
97 constexpr Rank(uint8_t value = none()) : Coordinate(value) {}
98 constexpr Rank(int value = none()) : Coordinate(value) {}
99 explicit constexpr Rank(char c) { m_value = static_cast<uint8_t>(c - '1'); }
100
101 static constexpr uint8_t distance(Rank from, Rank to) { return from > to ? from - to : to - from; }
102
103 [[nodiscard]] constexpr bool pawnStarting(Color color) const {
104 return (color == Color::WHITE && m_value == R2) || (color == Color::BLACK && m_value == R7);
105 }
106 [[nodiscard]] constexpr bool pawnPromoting(Color color) const {
107 return (color == Color::WHITE && m_value == R8) || (color == Color::BLACK && m_value == R1);
108 }
109
110 void print(std::ostream& os) const {
111 if (ok()) {
112 os << rankToChar[m_value];
113 } else
114 os << '?';
115 }
116};
117
118struct Square : Coordinate<Square> {
119 public:
120 // clang-format off
121 enum : uint8_t {
122 A1, B1, C1, D1, E1, F1, G1, H1,
123 A2, B2, C2, D2, E2, F2, G2, H2,
124 A3, B3, C3, D3, E3, F3, G3, H3,
125 A4, B4, C4, D4, E4, F4, G4, H4,
126 A5, B5, C5, D5, E5, F5, G5, H5,
127 A6, B6, C6, D6, E6, F6, G6, H6,
128 A7, B7, C7, D7, E7, F7, G7, H7,
129 A8, B8, C8, D8, E8, F8, G8, H8,
130
131 FIRST = A1,
132 LAST = H8,
133
134 NONE = 64,
135 MASK = 0b111111,
136 SIZE = 6,
137 NB = 64
138 };
139 // clang-format on
140
141 constexpr Square(uint8_t value = none()) : Coordinate(value) {}
142 constexpr Square(int value = none()) : Coordinate(value) {}
143 explicit constexpr Square(File file, Rank rank) : Coordinate((rank << File::size()) | file) {}
144 explicit constexpr Square(std::string_view str) {
145 if (str.size() == 2) {
146 File file(str[0]);
147 Rank rank(str[1]);
148 if (file.ok() && rank.ok()) {
149 Square(file, rank);
150 }
151 }
152 }
153
154 [[nodiscard]] constexpr File file() const { return m_value & File::mask(); }
155 [[nodiscard]] constexpr Rank rank() const { return m_value >> File::size(); }
156
157 static constexpr uint8_t distance(Square from, Square to) {
158 static constexpr auto table = []() constexpr {
159 std::array<std::array<uint8_t, NB>, NB> t{};
160 for (auto i : Square::all()) {
161 for (auto j : Square::all()) {
162 t[i][j] = std::max(File::distance(i.file(), j.file()), Rank::distance(i.rank(), j.rank()));
163 }
164 }
165 return t;
166 }();
167 return table[from][to];
168 }
169
170 void print(std::ostream& os) const {
171 file().print(os);
172 rank().print(os);
173 }
174};
175
176struct Direction {
177 public:
178 enum : int8_t {
179 E = 1,
180 N = 8,
181 W = -1,
182 S = -8,
183
184 NN = N + N,
185 SS = S + S,
186
187 NE = N + E,
188 SE = S + E,
189 NW = N + W,
190 SW = S + W,
191
192 NNE = N + N + E,
193 ENE = E + E + N,
194 ESE = E + E + S,
195 SSE = S + S + E,
196 SSW = S + S + W,
197 WSW = W + W + S,
198 WNW = W + W + N,
199 NNW = N + N + W,
200
201 NONE = 0
202 };
203
204 constexpr Direction(int8_t value) : m_value(value) {};
205
206 constexpr void set(int8_t value) { m_value = value; }
207 [[nodiscard]] constexpr int8_t value() const { return m_value; }
208
209 constexpr operator int8_t() const { return m_value; }
210
211 private:
212 int8_t m_value;
213};
214
215constexpr std::array<Direction, 1> whitePawnPushDirections = {Direction::N};
216
217constexpr std::array<Direction, 2> whitePawnAttackDirections = {Direction::NE, Direction::NW};
218
219constexpr std::array<Direction, 8> knightDirections = {Direction::NNE, Direction::NNW, Direction::ENE, Direction::WNW,
220 Direction::SSE, Direction::SSW, Direction::ESE, Direction::WSW};
221
222constexpr std::array<Direction, 8> queenDirections = {Direction::NE, Direction::NW, Direction::SE, Direction::SW,
223 Direction::N, Direction::S, Direction::E, Direction::W};
224
225constexpr std::array<Direction, 8> kingDirections = {Direction::E, Direction::N, Direction::W, Direction::S,
226 Direction::NE, Direction::NW, Direction::SE, Direction::SW};
Definition piece.hpp:42
Definition navigation.hpp:42
Definition iterator.hpp:6
Definition navigation.hpp:79