libscid 0.1.0
Chess applications made easy.
Loading...
Searching...
No Matches
position.h
Go to the documentation of this file.
1
5#pragma once
6
7#include "scid/core/error.h"
8#include "scid/core/move.h"
10#include "scid/core/notation.h"
11
12#include <cassert>
13#include <cstddef>
14#include <stdio.h>
15#include <string>
16#include <string_view>
17
18namespace scid::core {
19
20class DString;
21class SquareSet;
22class SquareList;
23
24
26// Position: Constants
27
28const byte WQ_CASTLE = 1, WK_CASTLE = 2,
29 BQ_CASTLE = 4, BK_CASTLE = 8;
30
31// Flags that Position::GenerateMoves() recognises:
32//
33typedef uint genMovesT;
34const genMovesT
35 GEN_CAPTURES = 1,
36 GEN_NON_CAPS = 2,
37 GEN_ALL_MOVES = (GEN_CAPTURES | GEN_NON_CAPS);
38
39
41// Position: Class definition
42
44{
45
46private:
47 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
48 // Position: Data structures
49
50 pieceT Board[66]; // the actual board + a color square
51 // and a NULL square.
52 uint Count[2]; // count of pieces & pawns each
53 byte Material[16]; // count of each type of piece
54 byte ListPos[64]; // ListPos stores the position in
55 // List[][] for the piece on
56 // square x.
57 squareT List[2][16]; // list of piece squares for each side
58 byte NumOnRank[16][8];
59 byte NumOnFyle[16][8];
60 byte NumOnLeftDiag[16][16]; // Num Queens/Bishops
61 byte NumOnRightDiag[16][16];
62 byte NumOnSquareColor[16][2];
63
64 directionT Pinned[16]; // For each List[ToMove][x], stores
65 // whether piece is pinned to its
66 // own king and dir from king.
67
68 squareT EPTarget; // square pawns can EP capture to
69 colorT ToMove;
70 ushort HalfMoveClock; // Count of halfmoves since last capture
71 // or pawn move.
72 ushort PlyCounter;
73 byte Castling; // castling flags
74 byte variant_; // 0 -> normal; 1 -> chess960
75 squareT castleRookSq_[4]; // start rook squares
76
77 uint Hash; // Hash value.
78 uint PawnHash; // Pawn structure hash value.
79
80 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
81 // Position: Private Functions
82
83 inline void AddHash (pieceT p, squareT sq);
84 inline void UnHash (pieceT p, squareT sq);
85
86 inline void AddToBoard (pieceT p, squareT sq);
87 inline void RemoveFromBoard (pieceT p, squareT sq);
88
89 void CalcPinsDir (directionT dir, pieceT attacker);
90
91 void GenSliderMoves (MoveList * mlist, colorT c, squareT sq,
92 directionT dir, SquareSet * sqset,
93 bool capturesOnly);
94 void GenKnightMoves (MoveList * mlist, colorT c, squareT sq,
95 SquareSet * sqset, bool capturesOnly);
96
97 void AddLegalMove (MoveList * mlist, squareT from, squareT to, pieceT promo);
98 void GenCastling (MoveList * mlist);
99 void GenKingMoves (MoveList * mlist, genMovesT genType);
100 void AddPromotions (MoveList * mlist, squareT from, squareT dest);
101 bool IsValidEnPassant (squareT from, squareT to);
102 void GenPawnMoves (MoveList * mlist, squareT from, directionT dir,
103 SquareSet * sqset, genMovesT genType);
104
105 void GenCheckEvasions(MoveList* mlist, pieceT mask, genMovesT genType,
106 SquareList* checkSquares);
107
108 errorT readPieceMoveAction(MoveAction* sm, const char* str, size_t slen,
109 pieceT p) const;
110 errorT readCastleMoveAction(MoveAction* sm, std::string_view str) const;
111 errorT readPawnMoveAction(MoveAction* sm, const char* str, size_t slen,
112 fyleT from);
113 errorT readKingMoveAction(MoveAction* sm, const char* str,
114 size_t slen) const;
115 errorT readCoordinateMoveAction(MoveAction* m, const char* s,
116 size_t slen, bool reverse);
117 errorT parseMoveAction(MoveAction* sm, const char* begin, const char* end);
118 void fillMoveAction(MoveAction& sm) const;
119 void resolveMove(squareT from, squareT to, pieceT promo,
120 MoveAction& action) const;
121
122 template <typename TFunc>
123 bool under_attack(squareT target_sq, squareT captured_sq,
124 TFunc not_empty) const;
125 bool under_attack(squareT target_sq) const;
126
127 static constexpr unsigned castlingIdx(colorT color, castleDirT side) {
128 return 2 * color + side;
129 }
130 squareT find_castle_rook(colorT col, squareT rsq) const;
131 squareT castleRookSq(colorT color, bool king_side) const {
132 return castleRookSq_[2 * color + (king_side ? 1 : 0)];
133 }
134
135 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
136 // Position: Public Functions
137public:
138 Position();
139 static const Position& getStdStart();
140
141 void Clear(); // No pieces on board
142 void StdStart() { *this = getStdStart(); }
143 bool IsStdStart() const;
144 errorT AddPiece (pieceT p, squareT sq);
145
146 bool isChess960() const { return variant_ == 1; }
147
148 // Set and Get attributes -- one-liners
149 byte PieceCount (pieceT p) { return Material[p]; }
150 const byte* GetMaterial() const { return Material; }
151 void SetEPTarget (squareT s) { EPTarget = s; }
152 squareT GetEPTarget () const { return EPTarget; }
153 void SetToMove (colorT c) { ToMove = c; }
154 colorT GetToMove () const { return ToMove; }
155 bool WhiteToMove () const { return ToMove == WHITE; }
156 void SetPlyCounter (ushort x) { PlyCounter = x; }
157 ushort GetPlyCounter () const { return PlyCounter; }
158 ushort GetFullMoveCount() const { return PlyCounter / 2 + 1; }
159
160 // Methods to get the Board or piece lists -- used in game.cpp to
161 // decode moves:
162 const squareT* GetList(colorT c) const { return List[c]; }
163 uint GetCount (colorT c) const { return Count[c]; }
164 uint TotalMaterial () const { return Count[WHITE] + Count[BLACK]; }
165 uint NumNonPawns (colorT c) {
166 return Count[c] - Material[piece_Make(c,PAWN)];
167 }
168 bool InPawnEnding () {
169 return (NumNonPawns(WHITE) == 1 && NumNonPawns(BLACK) == 1);
170 }
171 uint MaterialValue (colorT c);
172 inline uint FyleCount (pieceT p, fyleT f) const {
173 return NumOnFyle[p][f];
174 }
175 inline uint RankCount (pieceT p, rankT r) const {
176 return NumOnRank[p][r];
177 }
178 inline uint LeftDiagCount (pieceT p, leftDiagT diag) const {
179 return NumOnLeftDiag[p][diag];
180 }
181 inline uint RightDiagCount (pieceT p, rightDiagT diag) const {
182 return NumOnRightDiag[p][diag];
183 }
184 inline uint SquareColorCount (pieceT p, colorT sqColor) const {
185 return NumOnSquareColor[p][sqColor];
186 }
187
188 const pieceT* GetBoard() const {
189 const_cast<Position*>(this)->Board[COLOR_SQUARE] = COLOR_CHAR[ToMove];
190 return Board;
191 }
192
193 pieceT GetPiece(squareT sq) const {
194 assert(sq < 64);
195 return Board[sq];
196 }
197
198 // Other one-line methods
199 squareT GetKingSquare (colorT c) const { return List[c][0]; }
200 squareT GetKingSquare () const { return List[ToMove][0]; }
201 squareT GetEnemyKingSquare () const { return List[1-ToMove][0]; }
202
203 // Castling flags
204 bool GetCastling(colorT c, castleDirT dir) const {
205 return Castling & (1u << castlingIdx(c, dir));
206 }
207 byte GetCastlingFlags() const { return Castling; }
208 bool validCastlingFlag(colorT color, bool king_side) const;
209
210 // Hashing
211 inline uint HashValue (void) const { return Hash; }
212 inline uint PawnHashValue (void) const { return PawnHash; }
213 uint GetHPSig ();
214
215 // Move generation and execution
216 void CalcPins();
217 void GenPieceMoves (MoveList * mlist, squareT sq,
218 SquareSet * sqset, bool capturesOnly);
219
220 // Generate all legal moves:
221 void GenerateMoves (MoveList* mlist, pieceT mask, genMovesT genType, bool maybeInCheck);
222 void GenerateMoves (MoveList * mlist) { GenerateMoves (mlist, EMPTY, GEN_ALL_MOVES, true); }
223 void GenerateMoves (MoveList * mlist, genMovesT genType) { GenerateMoves (mlist, EMPTY, genType, true); }
224 void GenerateCaptures (MoveList * mlist) { GenerateMoves (mlist, EMPTY, GEN_CAPTURES, true); }
225 int IsLegalMove(squareT from, squareT to, pieceT promo) const;
226
232 template <bool check_legal = true> bool canCastle(bool king_side) const;
233
234 uint CalcAttacks (colorT toMove, squareT kingSq, SquareList * squares) const;
235 int TreeCalcAttacks (squareT target);
236 uint CalcNumChecks () const {
237 return CalcAttacks (1-ToMove, GetKingSquare(), NULL);
238 }
239 uint CalcNumChecks (squareT kingSq) const {
240 return CalcAttacks (1-ToMove, kingSq, NULL);
241 }
242 uint CalcNumChecks (squareT kingSq, SquareList * checkSquares) const {
243 return CalcAttacks (1-ToMove, kingSq, checkSquares);
244 }
245
246 uint Mobility (pieceT p, colorT color, squareT from);
247 bool IsKingInCheck () { return (CalcNumChecks() > 0); }
248 bool IsKingInCheck (MoveAction const& sm);
249 bool IsKingInMate ();
250 bool IsLegal ();
251
252 bool IsPromoMove (squareT from, squareT to);
253
254 errorT parseMoveSpec(MoveSpec& spec, std::string_view notation);
255 errorT readCoordinateMoveSpec(MoveSpec& spec,
256 std::string_view notation,
257 bool reverse);
258 std::string makeSan(MoveSpec const& spec, sanFlagT flag);
259 errorT applyMove(MoveSpec const& spec);
260
261 errorT resolveMove(MoveSpec const& spec, MoveAction& action) const;
262 void apply(MoveAction const& action);
263 void undo(MoveAction const& action);
264
265 void writeSan(MoveAction const& action, char* s, sanFlagT flag);
266
267 errorT applyCoordinateMoves(const char* moves, size_t movesLen,
268 std::string* toSAN = nullptr);
269
270 // Board I/O
271 void MakeLongStr (char* str) const;
272 errorT ReadFromLongStr (const char * str);
273 errorT ReadFromFEN (const char * s);
274 errorT ReadFromFENorUCI (std::string_view str);
275 void PrintCompactStr (char * cboard) const;
276 void PrintFEN(char* str, size_t len) const;
277 void DumpLatexBoard (DString * dstr, bool flip);
278 void DumpLatexBoard (DString * dstr) {
279 DumpLatexBoard (dstr, false);
280 }
281 void DumpHtmlBoard (DString * dstr, uint style, const char * dir,
282 bool flip);
283 void DumpHtmlBoard (DString * dstr, uint style, const char * dir) {
284 DumpHtmlBoard (dstr, style, dir, false);
285 }
286
287 // Copy, compare positions
288 int Compare (Position * p);
289 void CopyFrom (Position * src) { *this = *src; }
290
291 // Set up a random position:
292 errorT Random (const char * material);
293
294private:
295 void setCastling(colorT col, squareT rsq);
296 void ClearCastling(colorT col, castleDirT dir) {
297 Castling &= ~(1u << castlingIdx(col, dir));
298 }
299 void ClearCastlingFlags(colorT c) {
300 Castling &= (c == WHITE) ? 0b11111100 : 0b11110011;
301 }
302};
303
304
305} // namespace scid::core
Definition movelist.h:91
Definition position.h:44
bool canCastle(bool king_side) const
Check that the minimum requirements for castling are satisfied:
Definition square_collections.h:15
Definition square_collections.h:53
Shared status and error codes.
Portable move intent.
Generated move records and fixed-capacity move lists.
Definition movelist.h:27