libscid 0.1.0
Chess applications made easy.
Loading...
Searching...
No Matches
board.h
Go to the documentation of this file.
1
5#pragma once
6
8
9#include <cassert>
10
11namespace scid::core {
12
13// Minor piece definitions, used for searching by material only:
14const pieceT WM = 16, BM = 17;
15
16const uint MAX_PIECE_TYPES = 18;
17
18// PIECE_FLIP[]: array of pieces, with colors reversed.
19const pieceT PIECE_FLIP[MAX_PIECE_TYPES] = {
20 END_OF_BOARD,
21 BK, BQ, BR, BB, BN, BP,
22 EMPTY, EMPTY,
23 WK, WQ, WR, WB, WN, WP,
24 EMPTY, BM, WM
25};
26
27const bool PIECE_IS_SLIDER[8] = {
28 false,
29 false, true, true, true, false, false,
30 false,
31};
32
33inline bool piece_IsKing(pieceT p) { return (piece_Type(p) == KING); }
34
35inline bool piece_IsSlider(pieceT p) { return PIECE_IS_SLIDER[piece_Type(p)]; }
36
37inline pieceT piece_FromChar(int x) {
38 switch (x) {
39 case 'K': return KING;
40 case 'Q': return QUEEN;
41 case 'R': return ROOK;
42 case 'N': return KNIGHT;
43 case 'B': return BISHOP;
44 default: return EMPTY;
45 }
46}
47
48inline leftDiagT square_LeftDiag(squareT sq) {
49 return square_Rank(sq) + square_Fyle(sq);
50}
51
52inline rightDiagT square_RightDiag(squareT sq) {
53 return (7 + square_Rank(sq) - square_Fyle(sq));
54}
55
56// square_Color:
57// Return WHITE for a light square, BLACK for a dark square.
58inline colorT square_Color(squareT sq) {
59 return 1 - (square_LeftDiag(sq) & 1);
60}
61
62// square_FlipFyle:
63// Return the square with its file flipped: a1 <-> h1, b1 <-> g1, etc.
64inline squareT square_FlipFyle(squareT sq) {
65 return square_Make(A_FYLE + H_FYLE - square_Fyle(sq), square_Rank(sq));
66}
67
68// square_FlipRank:
69// Return the square with its rank flipped: a1 <-> a8, a2 <-> a7, etc.
70inline squareT square_FlipRank(squareT sq) {
71 return square_Make(square_Fyle(sq), RANK_1 + RANK_8 - square_Rank(sq));
72}
73
74// square_FlipDiag:
75// Return the square flipped along the a1-h8 diagonal.
76inline squareT square_FlipDiag(squareT sq) {
77 return square_Make(square_Rank(sq), square_Fyle(sq));
78}
79
80const uint rankFyleDist[64] = {
81 0, 1, 2, 3, 4, 5, 6, 7,
82 1, 0, 1, 2, 3, 4, 5, 6,
83 2, 1, 0, 1, 2, 3, 4, 5,
84 3, 2, 1, 0, 1, 2, 3, 4,
85 4, 3, 2, 1, 0, 1, 2, 3,
86 5, 4, 3, 2, 1, 0, 1, 2,
87 6, 5, 4, 3, 2, 1, 0, 1,
88 7, 6, 5, 4, 3, 2, 1, 0
89};
90
91// square_Distance:
92// Return the distance in king moves between two squares.
93inline uint square_Distance(squareT from, squareT to) {
94 assert(from <= H8 && to <= H8);
95 uint rankd = rankFyleDist[(square_Rank(from) << 3) | square_Rank(to)];
96 uint fyled = rankFyleDist[(square_Fyle(from) << 3) | square_Fyle(to)];
97 return (rankd > fyled) ? rankd : fyled;
98}
99
100// square_NearestCorner:
101// Return the corner (A1/H1/A8/H8) closest to the specified square.
102inline squareT square_NearestCorner(squareT sq) {
103 if (square_Rank(sq) <= RANK_4) {
104 return (square_Fyle(sq) <= D_FYLE) ? A1 : H1;
105 } else {
106 return (square_Fyle(sq) <= D_FYLE) ? A8 : H8;
107 }
108}
109
110inline bool square_IsCornerSquare(squareT sq) {
111 return (sq == A1 || sq == H1 || sq == A8 || sq == H8);
112}
113
114inline bool square_IsEdgeSquare(squareT sq) {
115 rankT rank = square_Rank(sq);
116 if (rank == RANK_1 || rank == RANK_8) { return true; }
117 fyleT fyle = square_Fyle(sq);
118 if (fyle == A_FYLE || fyle == H_FYLE) { return true; }
119 return false;
120}
121
122const int edgeDist[66] = {
123 0, 0, 0, 0, 0, 0, 0, 0,
124 0, 1, 1, 1, 1, 1, 1, 0,
125 0, 1, 2, 2, 2, 2, 1, 0,
126 0, 1, 2, 3, 3, 2, 1, 0,
127 0, 1, 2, 3, 3, 2, 1, 0,
128 0, 1, 2, 2, 2, 2, 1, 0,
129 0, 1, 1, 1, 1, 1, 1, 0,
130 0, 0, 0, 0, 0, 0, 0, 0,
131 -1, -1
132};
133
134inline int square_EdgeDistance(squareT sq) {
135 return edgeDist[sq];
136}
137
138inline bool square_IsKnightHop(squareT from, squareT to) {
139 assert(from <= H8 && to <= H8);
140 uint rdist = rankFyleDist[(square_Rank(from) << 3) | square_Rank(to)];
141 uint fdist = rankFyleDist[(square_Fyle(from) << 3) | square_Fyle(to)];
142 // It is a knight hop only if one distance is two squares and the
143 // other is one square -- that is, only if their product equals two.
144 return ((rdist * fdist) == 2);
145}
146
147inline char square_FyleChar(squareT sq) {
148 return square_Fyle(sq) + 'a';
149}
150
151inline char square_RankChar(squareT sq) {
152 return square_Rank(sq) + '1';
153}
154
155// Directions:
156// Up = 1, Down = 2, Left = 4, Right = 8, UpLeft = 5, UpRight = 9,
157// DownLeft = 6, DownRight = 10
158const directionT
159 NULL_DIR = 0,
160 UP = 1,
161 DOWN = 2,
162 LEFT = 4,
163 RIGHT = 8,
164 UP_LEFT = (UP | LEFT),
165 UP_RIGHT = (UP | RIGHT),
166 DOWN_LEFT = (DOWN | LEFT),
167 DOWN_RIGHT = (DOWN | RIGHT);
168
169const directionT dirOpposite[11] = {
170 NULL_DIR,
171 DOWN, // opposite of UP (1)
172 UP, // opposite of DOWN (2)
173 NULL_DIR,
174 RIGHT, // opposite of LEFT (4)
175 DOWN_RIGHT, // opposite of UP_LEFT (5)
176 UP_RIGHT, // opposite of DOWN_LEFT (6)
177 NULL_DIR,
178 LEFT, // opposite of RIGHT (8)
179 DOWN_LEFT, // opposite of UP_RIGHT (9)
180 UP_LEFT // opposite of DOWN_RIGHT (10)
181};
182
183// direction_Opposite(): return the opposite direction to d
184inline directionT direction_Opposite(directionT d) {
185 return dirOpposite[d];
186}
187
188// dirIsDiagonal[]: array listing the diagonal directions, for fast
189// lookup of whether a direction is a diagonal.
190const bool dirIsDiagonal[11] = {
191 false, // 0 = NULL_DIR
192 false, // 1 = UP
193 false, // 2 = DOWN
194 false, // 3 = Invalid
195 false, // 4 = LEFT
196 true, // 5 = UP_LEFT
197 true, // 6 = DOWN_LEFT
198 false, // 7 = Invalid
199 false, // 8 = RIGHT
200 true, // 9 = UP_RIGHT
201 true // 10 = DOWN_RIGHT
202};
203
204inline bool direction_IsDiagonal(directionT dir) {
205 return dirIsDiagonal[dir];
206}
207
208// dirDelta:
209// Array giving the board delta of moving to the next square
210// in that direction.
211const int dirDelta[11] = {
212 0, // NULL_DIR
213 8, // UP
214 -8, // DOWN
215 0, // Invalid
216 -1, // LEFT
217 7, // UP_LEFT
218 -9, // DOWN_LEFT
219 0, // Invalid
220 1, // RIGHT
221 9, // UP_RIGHT
222 -7 // DOWN_RIGHT
223};
224
225inline int direction_Delta(directionT dir) {
226 return dirDelta[dir];
227}
228
229// The starting Board
230const pieceT START_BOARD[66] = {
231 WR, WN, WB, WQ, WK, WB, WN, WR, // A1--H1
232 WP, WP, WP, WP, WP, WP, WP, WP, // A2--H2
233 EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
234 EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
235 EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
236 EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
237 BP, BP, BP, BP, BP, BP, BP, BP,
238 BR, BN, BB, BQ, BK, BB, BN, BR,
239 EMPTY, // COLOR_SQUARE
240 END_OF_BOARD // NULL_SQUARE
241};
242
243// Square colors for the standard chess board:
244const colorT BOARD_SQUARECOLOR[66] = {
245 BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, // a1-h1
246 WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, // a2-h2
247 BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, // a3-h3
248 WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, // a4-h4
249 BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, // a5-h5
250 WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, // a6-h6
251 BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, // a7-h7
252 WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, // a8-h8
253 NOCOLOR, NOCOLOR // Color square and Null square
254};
255
256// square_Adjacent: returns 1 if the two squares are adjacent. Note that
257// diagonal adjacency is included: a1 and b2 are adjacent.
258// Also note that a square is adjacent to itself.
259inline bool square_Adjacent(squareT from, squareT to) {
260 assert(from <= H8 && to <= H8);
261 rankT fromRank = square_Rank(from);
262 rankT toRank = square_Rank(to);
263 int rdist = (int)fromRank - (int)toRank;
264 if (rdist < -1 || rdist > 1) { return false; }
265 fyleT fromFyle = square_Fyle(from);
266 fyleT toFyle = square_Fyle(to);
267 int fdist = (int)fromFyle - (int)toFyle;
268 if (fdist < -1 || fdist > 1) { return false; }
269 return true;
270}
271
272} // namespace scid::core
Constants and definitions of the chess board.