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
StdStart()152 void StdStart() { *this = getStdStart(); }
153 bool IsStdStart() const;
154 errorT AddPiece (pieceT p, squareT sq);
155
156 // Set and Get attributes -- one-liners
PieceCount(pieceT p)157 byte PieceCount (pieceT p) { return Material[p]; }
GetMaterial()158 const byte* GetMaterial() const { return Material; }
SetEPTarget(squareT s)159 void SetEPTarget (squareT s) { EPTarget = s; }
GetEPTarget()160 squareT GetEPTarget () const { return EPTarget; }
SetToMove(colorT c)161 void SetToMove (colorT c) { ToMove = c; }
GetToMove()162 colorT GetToMove () const { return ToMove; }
SetPlyCounter(ushort x)163 void SetPlyCounter (ushort x) { PlyCounter = x; }
GetPlyCounter()164 ushort GetPlyCounter () const { return PlyCounter; }
GetFullMoveCount()165 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:
GetList(colorT c)169 const squareT* GetList(colorT c) const { return List[c]; }
GetList(colorT c)170 squareT * GetList (colorT c) { return List[c]; }
GetCount(colorT c)171 uint GetCount (colorT c) const { return Count[c]; }
TotalMaterial()172 uint TotalMaterial () { return Count[WHITE] + Count[BLACK]; }
NumNonPawns(colorT c)173 uint NumNonPawns (colorT c) {
174 return Count[c] - Material[piece_Make(c,PAWN)];
175 }
InPawnEnding()176 bool InPawnEnding () {
177 return (NumNonPawns(WHITE) == 1 && NumNonPawns(BLACK) == 1);
178 }
179 uint MaterialValue (colorT c);
FyleCount(pieceT p,fyleT f)180 inline uint FyleCount (pieceT p, fyleT f) const {
181 return NumOnFyle[p][f];
182 }
RankCount(pieceT p,rankT r)183 inline uint RankCount (pieceT p, rankT r) const {
184 return NumOnRank[p][r];
185 }
LeftDiagCount(pieceT p,leftDiagT diag)186 inline uint LeftDiagCount (pieceT p, leftDiagT diag) {
187 return NumOnLeftDiag[p][diag];
188 }
RightDiagCount(pieceT p,rightDiagT diag)189 inline uint RightDiagCount (pieceT p, rightDiagT diag) {
190 return NumOnRightDiag[p][diag];
191 }
SquareColorCount(pieceT p,colorT sqColor)192 inline uint SquareColorCount (pieceT p, colorT sqColor) {
193 return NumOnSquareColor[p][sqColor];
194 }
195 uint GetSquares (pieceT p, SquareList * sqlist);
196
GetBoard()197 const pieceT* GetBoard() const {
198 const_cast<Position*>(this)->Board[COLOR_SQUARE] = COLOR_CHAR[ToMove];
199 return Board;
200 }
201
GetPiece(squareT sq)202 pieceT GetPiece(squareT sq) const {
203 ASSERT(sq < 64);
204 return Board[sq];
205 }
206
207 // Other one-line methods
GetKingSquare(colorT c)208 squareT GetKingSquare (colorT c) { return List[c][0]; }
GetKingSquare()209 squareT GetKingSquare () { return List[ToMove][0]; }
GetEnemyKingSquare()210 squareT GetEnemyKingSquare () { return List[1-ToMove][0]; }
211
212 // Castling flags
213 inline void SetCastling (colorT c, castleDirT dir, bool flag);
GetCastling(colorT c,castleDirT dir)214 bool GetCastling(colorT c, castleDirT dir) const {
215 int b = (c == WHITE) ? 1 : 4;
216 if (dir == KSIDE)
217 b += b;
218 // Now b == 1 or 2 (white flags), or 4 or 8 (black flags)
219 return Castling & b;
220 }
CastlingPossible()221 inline bool CastlingPossible () { return (Castling ? true : false); }
GetCastlingFlags()222 byte GetCastlingFlags () { return Castling; }
SetCastlingFlags(byte b)223 void SetCastlingFlags (byte b) { Castling = b; }
224
225 // Hashing
HashValue(void)226 inline uint HashValue (void) { return Hash; }
PawnHashValue(void)227 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);
GenerateMoves(MoveList * mlist)237 void GenerateMoves (MoveList * mlist) { GenerateMoves (mlist, EMPTY, GEN_ALL_MOVES, true); }
GenerateMoves(MoveList * mlist,genMovesT genType)238 void GenerateMoves (MoveList * mlist, genMovesT genType) { GenerateMoves (mlist, EMPTY, genType, true); }
GenerateCaptures(MoveList * mlist)239 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);
CalcNumChecks()244 uint CalcNumChecks () {
245 return CalcAttacks (1-ToMove, GetKingSquare(), NULL);
246 }
CalcNumChecks(squareT kingSq)247 uint CalcNumChecks (squareT kingSq) {
248 return CalcAttacks (1-ToMove, kingSq, NULL);
249 }
CalcNumChecks(squareT kingSq,SquareList * checkSquares)250 uint CalcNumChecks (squareT kingSq, SquareList * checkSquares) {
251 return CalcAttacks (1-ToMove, kingSq, checkSquares);
252 }
253
254 uint Mobility (pieceT p, colorT color, squareT from);
IsKingInCheck()255 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);
CompactStrFirstByte()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);
DumpLatexBoard(DString * dstr)288 void DumpLatexBoard (DString * dstr) {
289 DumpLatexBoard (dstr, false);
290 }
291 void DumpHtmlBoard (DString * dstr, uint style, const char * dir,
292 bool flip);
DumpHtmlBoard(DString * dstr,uint style,const char * dir)293 void DumpHtmlBoard (DString * dstr, uint style, const char * dir) {
294 DumpHtmlBoard (dstr, style, dir, false);
295 }
296
297 // Copy, compare positions
298 int Compare (Position * p);
CopyFrom(Position * src)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
SetCastling(colorT c,castleDirT dir,bool flag)316 Position::SetCastling (colorT c, castleDirT dir, bool flag)
317 {
318 byte b = (c==WHITE ? 1 : 4);
319 if (dir == KSIDE) b += b;
320 // Now b = 1 or 2 (white flags), or 4 or 8 (black flags)
321 if (flag) { Castling |= b; } else { Castling &= (255-b); }
322 return;
323 }
324
325 #endif // SCID_POSITION_H
326
327 //////////////////////////////////////////////////////////////////////
328 // EOF: position.h
329 //////////////////////////////////////////////////////////////////////
330
331