Line data Source code
1 : //////////////////////////////////////////////////////////////////////
2 : //
3 : // FILE: position.h
4 : // Position class
5 : //
6 : // Part of: Scid (Shane's Chess Information Database)
7 : // Version: 3.5
8 : //
9 : // Notice: Copyright (c) 1999-2003 Shane Hudson. All rights reserved.
10 : //
11 : // Author: Shane Hudson (sgh@users.sourceforge.net)
12 : //
13 : //////////////////////////////////////////////////////////////////////
14 :
15 :
16 : #ifndef SCID_POSITION_H
17 : #define SCID_POSITION_H
18 :
19 : #include "common.h"
20 : #include "movelist.h"
21 : #include <stdio.h>
22 :
23 : class DString;
24 : class SquareSet;
25 : class SquareList;
26 :
27 :
28 : //////////////////////////////////////////////////////////////////////
29 : // Position: Constants
30 :
31 : const byte WQ_CASTLE = 1, WK_CASTLE = 2,
32 : BQ_CASTLE = 4, BK_CASTLE = 8;
33 :
34 : // SANFlag: since checking if a move is check (to add the "+" to its
35 : // SAN string) takes time, and checking for mate takes even
36 : // longer, we specify whether we want this done with a flag.
37 : typedef byte sanFlagT;
38 : const sanFlagT SAN_NO_CHECKTEST = 0,
39 : SAN_CHECKTEST = 1,
40 : SAN_MATETEST = 2;
41 :
42 :
43 : // Flags that Position::PrintFEN() recognises:
44 : //
45 : const uint
46 : FEN_COMPACT = 0,
47 : FEN_BOARD = 1,
48 : FEN_CASTLING_EP = 2,
49 : FEN_ALL_FIELDS = 3;
50 :
51 :
52 : // Flags that Position::GenerateMoves() recognises:
53 : //
54 : typedef uint genMovesT;
55 : const genMovesT
56 : GEN_CAPTURES = 1,
57 : GEN_NON_CAPS = 2,
58 : GEN_ALL_MOVES = (GEN_CAPTURES | GEN_NON_CAPS);
59 :
60 :
61 : // SANList: list of legal move strings in SAN.
62 : //
63 : struct sanListT
64 : {
65 : bool current;
66 : ushort num;
67 : sanStringT list [MAX_LEGAL_MOVES];
68 : };
69 :
70 :
71 : ///////////////////////////////////////////////////////////////////////////
72 : // Position: Class definition
73 :
74 : class Position
75 : {
76 :
77 : private:
78 : //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
79 : // Position: Data structures
80 :
81 : pieceT Board[66]; // the actual board + a color square
82 : // and a NULL square.
83 : uint Count[2]; // count of pieces & pawns each
84 : byte Material[16]; // count of each type of piece
85 : byte ListPos[64]; // ListPos stores the position in
86 : // List[][] for the piece on
87 : // square x.
88 : squareT List[2][16]; // list of piece squares for each side
89 : byte NumOnRank[16][8];
90 : byte NumOnFyle[16][8];
91 : byte NumOnLeftDiag[16][16]; // Num Queens/Bishops
92 : byte NumOnRightDiag[16][16];
93 : byte NumOnSquareColor[16][2];
94 :
95 : directionT Pinned[16]; // For each List[ToMove][x], stores
96 : // whether piece is pinned to its
97 : // own king and dir from king.
98 :
99 : squareT EPTarget; // square pawns can EP capture to
100 : colorT ToMove;
101 : ushort HalfMoveClock; // Count of halfmoves since last capture
102 : // or pawn move.
103 : ushort PlyCounter;
104 : byte Castling; // castling flags
105 :
106 : uint Hash; // Hash value.
107 : uint PawnHash; // Pawn structure hash value.
108 :
109 : //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
110 : // Position: Private Functions
111 :
112 : inline void AddHash (pieceT p, squareT sq);
113 : inline void UnHash (pieceT p, squareT sq);
114 :
115 : inline void AddToBoard (pieceT p, squareT sq);
116 : inline void RemoveFromBoard (pieceT p, squareT sq);
117 :
118 : void CalcPinsDir (directionT dir, pieceT attacker);
119 :
120 : void GenSliderMoves (MoveList * mlist, colorT c, squareT sq,
121 : directionT dir, SquareSet * sqset,
122 : bool capturesOnly);
123 : void GenKnightMoves (MoveList * mlist, colorT c, squareT sq,
124 : SquareSet * sqset, bool capturesOnly);
125 :
126 : void AddLegalMove (MoveList * mlist, squareT from, squareT to, pieceT promo);
127 : void GenCastling (MoveList * mlist);
128 : void GenKingMoves (MoveList * mlist, genMovesT genType, bool castling);
129 : void AddPromotions (MoveList * mlist, squareT from, squareT dest);
130 : bool IsValidEnPassant (squareT from, squareT to);
131 : void GenPawnMoves (MoveList * mlist, squareT from, directionT dir,
132 : SquareSet * sqset, genMovesT genType);
133 :
134 : void GenCheckEvasions(MoveList* mlist, pieceT mask, genMovesT genType,
135 : SquareList* checkSquares);
136 : errorT MatchPawnMove(MoveList* mlist, fyleT fromFyle, squareT to,
137 : pieceT promote);
138 :
139 : errorT ReadMove(simpleMoveT* sm, const char* str, int slen, pieceT p);
140 : errorT ReadMoveCastle(simpleMoveT* sm, const char* str, int slen);
141 : errorT ReadMovePawn(simpleMoveT* sm, const char* str, int slen, fyleT from);
142 : errorT ReadMoveKing(simpleMoveT* sm, const char* str, int slen);
143 :
144 :
145 : //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
146 : // Position: Public Functions
147 : public:
148 : Position();
149 : static const Position& getStdStart();
150 :
151 : void Clear(); // No pieces on board
152 19869 : void StdStart() { *this = getStdStart(); }
153 : bool IsStdStart() const;
154 : errorT AddPiece (pieceT p, squareT sq);
155 :
156 : // Set and Get attributes -- one-liners
157 0 : byte PieceCount (pieceT p) { return Material[p]; }
158 9016 : const byte* GetMaterial() const { return Material; }
159 : void SetEPTarget (squareT s) { EPTarget = s; }
160 : squareT GetEPTarget () const { return EPTarget; }
161 21 : void SetToMove (colorT c) { ToMove = c; }
162 2848236 : colorT GetToMove () const { return ToMove; }
163 : void SetPlyCounter (ushort x) { PlyCounter = x; }
164 3162 : ushort GetPlyCounter () const { return PlyCounter; }
165 1155998 : ushort GetFullMoveCount() const { return PlyCounter / 2 + 1; }
166 :
167 : // Methods to get the Board or piece lists -- used in game.cpp to
168 : // decode moves:
169 783051 : const squareT* GetList(colorT c) const { return List[c]; }
170 68 : squareT * GetList (colorT c) { return List[c]; }
171 68 : uint GetCount (colorT c) const { return Count[c]; }
172 : uint TotalMaterial () { return Count[WHITE] + Count[BLACK]; }
173 : uint NumNonPawns (colorT c) {
174 : return Count[c] - Material[piece_Make(c,PAWN)];
175 : }
176 : bool InPawnEnding () {
177 : return (NumNonPawns(WHITE) == 1 && NumNonPawns(BLACK) == 1);
178 : }
179 : uint MaterialValue (colorT c);
180 9546218 : inline uint FyleCount (pieceT p, fyleT f) const {
181 9546218 : return NumOnFyle[p][f];
182 : }
183 9546302 : inline uint RankCount (pieceT p, rankT r) const {
184 9546302 : return NumOnRank[p][r];
185 : }
186 9727794 : inline uint LeftDiagCount (pieceT p, leftDiagT diag) {
187 9727794 : return NumOnLeftDiag[p][diag];
188 : }
189 9727794 : inline uint RightDiagCount (pieceT p, rightDiagT diag) {
190 9727794 : return NumOnRightDiag[p][diag];
191 : }
192 3574549 : inline uint SquareColorCount (pieceT p, colorT sqColor) {
193 3574549 : return NumOnSquareColor[p][sqColor];
194 : }
195 : uint GetSquares (pieceT p, SquareList * sqlist);
196 :
197 783065 : const pieceT* GetBoard() const {
198 783065 : const_cast<Position*>(this)->Board[COLOR_SQUARE] = COLOR_CHAR[ToMove];
199 783065 : return Board;
200 : }
201 :
202 415 : pieceT GetPiece(squareT sq) const {
203 415 : ASSERT(sq < 64);
204 415 : return Board[sq];
205 : }
206 :
207 : // Other one-line methods
208 4557008 : squareT GetKingSquare (colorT c) { return List[c][0]; }
209 1958228 : squareT GetKingSquare () { return List[ToMove][0]; }
210 2495980 : squareT GetEnemyKingSquare () { return List[1-ToMove][0]; }
211 :
212 : // Castling flags
213 : inline void SetCastling (colorT c, castleDirT dir, bool flag);
214 275841 : bool GetCastling(colorT c, castleDirT dir) const {
215 275841 : int b = (c == WHITE) ? 1 : 4;
216 275841 : if (dir == KSIDE)
217 138031 : b += b;
218 : // Now b == 1 or 2 (white flags), or 4 or 8 (black flags)
219 275841 : return Castling & b;
220 : }
221 : inline bool CastlingPossible () { return (Castling ? true : false); }
222 : byte GetCastlingFlags () { return Castling; }
223 : void SetCastlingFlags (byte b) { Castling = b; }
224 :
225 : // Hashing
226 0 : inline uint HashValue (void) { return Hash; }
227 0 : inline uint PawnHashValue (void) { return PawnHash; }
228 : uint GetHPSig ();
229 :
230 : // Move generation and execution
231 : void CalcPins();
232 : void GenPieceMoves (MoveList * mlist, squareT sq,
233 : SquareSet * sqset, bool capturesOnly);
234 :
235 : // Generate all legal moves:
236 : void GenerateMoves (MoveList* mlist, pieceT mask, genMovesT genType, bool maybeInCheck);
237 16411 : void GenerateMoves (MoveList * mlist) { GenerateMoves (mlist, EMPTY, GEN_ALL_MOVES, true); }
238 : void GenerateMoves (MoveList * mlist, genMovesT genType) { GenerateMoves (mlist, EMPTY, genType, true); }
239 0 : void GenerateCaptures (MoveList * mlist) { GenerateMoves (mlist, EMPTY, GEN_CAPTURES, true); }
240 : bool IsLegalMove (simpleMoveT * sm);
241 :
242 : uint CalcAttacks (colorT toMove, squareT kingSq, SquareList * squares);
243 : int TreeCalcAttacks (colorT toMove, squareT target);
244 742378 : uint CalcNumChecks () {
245 742378 : return CalcAttacks (1-ToMove, GetKingSquare(), NULL);
246 : }
247 5018908 : uint CalcNumChecks (squareT kingSq) {
248 5018908 : return CalcAttacks (1-ToMove, kingSq, NULL);
249 : }
250 795750 : uint CalcNumChecks (squareT kingSq, SquareList * checkSquares) {
251 795750 : return CalcAttacks (1-ToMove, kingSq, checkSquares);
252 : }
253 :
254 : uint Mobility (pieceT p, colorT color, squareT from);
255 742378 : bool IsKingInCheck () { return (CalcNumChecks() > 0); }
256 : bool IsKingInCheckDir (directionT dir);
257 : bool IsKingInCheck (simpleMoveT * sm);
258 : bool IsKingInMate ();
259 : bool IsLegal ();
260 :
261 : bool IsPromoMove (squareT from, squareT to);
262 :
263 : void DoSimpleMove (simpleMoveT * sm); // move execution ...
264 : void UndoSimpleMove (simpleMoveT * sm); // ... and taking back
265 :
266 : errorT RelocatePiece (squareT fromSq, squareT toSq);
267 :
268 : void MakeSANString (simpleMoveT * sm, char * s, sanFlagT flag);
269 : void MakeUCIString (simpleMoveT * sm, char * s);
270 : void CalcSANStrings (sanListT *sanList, sanFlagT flag);
271 :
272 : errorT ReadCoordMove(simpleMoveT* m, const char* s, int slen, bool reverse);
273 : errorT ParseMove(simpleMoveT* sm, const char* str);
274 : errorT ParseMove(simpleMoveT* sm, const char* begin, const char* end);
275 :
276 : // Board I/O
277 : void MakeLongStr (char * str);
278 : errorT ReadFromLongStr (const char * str);
279 : errorT ReadFromCompactStr (const byte * str);
280 : errorT ReadFromFEN (const char * s);
281 : void PrintCompactStr (char * cboard);
282 : void PrintCompactStrFlipped (char * cboard);
283 : byte CompactStrFirstByte () {
284 : return (Board[0] << 4) | Board[1];
285 : }
286 : void PrintFEN(char* str, uint flags) const;
287 : void DumpLatexBoard (DString * dstr, bool flip);
288 0 : void DumpLatexBoard (DString * dstr) {
289 0 : DumpLatexBoard (dstr, false);
290 0 : }
291 : void DumpHtmlBoard (DString * dstr, uint style, const char * dir,
292 : bool flip);
293 0 : void DumpHtmlBoard (DString * dstr, uint style, const char * dir) {
294 0 : DumpHtmlBoard (dstr, style, dir, false);
295 0 : }
296 :
297 : // Copy, compare positions
298 : int Compare (Position * p);
299 : void CopyFrom (Position * src) { *this = *src; }
300 :
301 : // Set up a random position:
302 : errorT Random (const char * material);
303 : };
304 :
305 :
306 :
307 : //////////////////////////////////////////////////////////////////////
308 : // Position: Public Inline Functions
309 :
310 :
311 : //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
312 : // Position::SetCastling():
313 : // Set a castling flag.
314 : //
315 : inline void
316 267954 : Position::SetCastling (colorT c, castleDirT dir, bool flag)
317 : {
318 267954 : byte b = (c==WHITE ? 1 : 4);
319 267954 : if (dir == KSIDE) b += b;
320 : // Now b = 1 or 2 (white flags), or 4 or 8 (black flags)
321 267954 : if (flag) { Castling |= b; } else { Castling &= (255-b); }
322 267954 : return;
323 : }
324 :
325 : #endif // SCID_POSITION_H
326 :
327 : //////////////////////////////////////////////////////////////////////
328 : // EOF: position.h
329 : //////////////////////////////////////////////////////////////////////
330 :
|