1 //------------------------------------------------------------------------------
2 // SilChessMachine.h
3 //
4 // Copyright (C) 2000-2005,2007-2008 Oliver Hamann.
5 //
6 // Homepage: http://eaglemode.sourceforge.net/
7 //
8 // This program is free software: you can redistribute it and/or modify it under
9 // the terms of the GNU General Public License version 3 as published by the
10 // Free Software Foundation.
11 //
12 // This program is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 // FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for
15 // more details.
16 //
17 // You should have received a copy of the GNU General Public License version 3
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 //------------------------------------------------------------------------------
20
21 #ifndef SilChessMachine_h
22 #define SilChessMachine_h
23
24
25 class SilChessMachine {
26
27 public:
28
29 SilChessMachine();
30 SilChessMachine(const SilChessMachine & machine);
31 ~SilChessMachine();
32
33 SilChessMachine & operator = (const SilChessMachine & machine);
34
35 class Move {
36 public:
37 signed char X1,Y1,X2,Y2;
38 void ToString(char * str) const;
39 bool FromString(const char * str);
40 bool operator == (const Move & m) const;
41 };
42
43 void StartNewGame();
44
45 enum {
46 DEFAULT_SEARCH_DEPTH = 2,
47 MAX_SEARCH_DEPTH = 8
48 };
49 int GetSearchDepth() const;
50 void SetSearchDepth(int searchDepth);
51 // 0 means to find random moves.
52
53 bool IsHumanWhite() const;
54 void SetHumanWhite(bool humanWhite);
55
56 bool IsWhiteOn() const;
57 bool IsHumanOn() const;
58
59 int GetMoveCount() const;
60 const Move & GetMove(int index) const;
61
62 int GetField(int x, int y) const;
63 // 0=empty, 1=white pawn, 2=white knight, 3=white bishop,
64 // 4=white rook, 5=white queen, 6=white king, 7=black pawn,
65 // 8=black knight ... 12=black king.
66
67 bool IsLegalMove(const Move & m) const;
68
69 void DoMove(const Move & m);
70 void UndoMove();
71
72 bool SearchMove(Move * pResult);
73
74 void StartSearching(bool cloneEngine=true);
75 bool ContinueSearching();
76 bool EndSearching(Move * pResult=NULL);
77 bool IsSearching() const;
78
79 bool IsCheck() const;
80 bool IsMate() const;
81 bool IsDraw() const;
82 bool IsEndless() const;
83 int GetValue() const;
84
85 bool Save(const char * filename) const;
86 bool Load(const char * filename);
87
88 enum Charset {
89 CS_ASCII,
90 CS_ASCII2,
91 CS_ANSI,
92 CS_DOS,
93 CS_MINI
94 };
95 void Print(Charset charset, const char * lastMove) const;
96
97 void GeneticTraining();
98
99 private:
100
101 enum PieceValues {
102 PawnValue = 2,
103 KnightValue = 5,
104 BishopValue = 5,
105 RookValue = 10,
106 QueenValue = 20,
107 KingValue = 40
108 };
109
110 enum PieceTypeFlags {
111 TF_Pawn = (1<<0),
112 TF_Knight = (1<<1),
113 TF_Bishop = (1<<2),
114 TF_Rook = (1<<3),
115 TF_Queen = (1<<4),
116 TF_King = (1<<5),
117 TF_White = (1<<6),
118 TF_Black = (1<<7)
119 };
120
121 enum PieceStateFlags {
122 SF_CanCastle = (1<<0)
123 };
124
125 struct Piece {
126
127 int Type;
128 // Zero if unused, otherwise something like TF_Pawn|TF_White
129
130 int X,Y;
131 // Position (origin is at upper-left)
132
133 int Value;
134 // Constant value of the piece, e.g. PawnValue.
135
136 int State;
137 // Only for king and rook: SF_CanCastle = never moved.
138
139 Piece * N[16];
140 // Next piece for each direction (0 = right, 4 = bottom...).
141 };
142
143 Piece Pieces[32];
144 // 0-15 white, 16-31 black. Type=0 if no longer on board.
145
146 Piece * Board[8*8];
147 // (origin is at upper-left)
148
149 int SearchDepth;
150
151 int HumanSide;
152 // TF_White or TF_Black
153
154 int Turn;
155 // How is on: TF_White or TF_Black
156
157 enum { MAX_MOVE_COUNT = 2048 };
158 Move Moves[MAX_MOVE_COUNT];
159 int MoveCount;
160
161 bool CachedInfoValid;
162 bool CachedIsCheck,CachedIsMate,CachedIsDraw;
163 int CachedValue;
164
165 struct SearchStackEntry {
166 int Depth,Alpha,Beta,Count,Index,Found;
167 Move Moves[512];
168 };
169 SearchStackEntry SearchStack[MAX_SEARCH_DEPTH+1];
170 SearchStackEntry * SearchStackTop;
171 int FoundVals[512];
172 SilChessMachine * SearchMachine;
173
174 enum ValueFactorIndex {
175 VFI_Piece = 0,
176 VFI_PayingTurn = 1,
177 VFI_PayingTurnOppo = 2,
178 VFI_Threats = 3,
179 VFI_Mobility = 4,
180 VFI_Ties = 5,
181 VFI_Center = 6,
182 VFI_KingCover = 7,
183 VFI_KingMobility = 8,
184 VFI_KingNotCentered= 9,
185 VFI_KingCheck = 10,
186 VFI_PawnBeside = 11,
187 VFI_PawnOnward = 12,
188 VFI_PawnHeaven = 13,
189 VFI_Count = 14
190 };
191 int ValFac[VFI_Count];
192 // Factors for valuation.
193
194 int ValRangeForRandom;
195
196 struct TBIntEntry {
197 int * Ptr; // NULL for start-mark
198 int Val;
199 };
200 struct TBPtrEntry {
201 Piece * * Ptr; // NULL for start-mark
202 Piece * Val;
203 };
204 enum {
205 MAX_TB_INT_ENTRIES = 11*(MAX_SEARCH_DEPTH+10),
206 MAX_TB_PTR_ENTRIES = 118*(MAX_SEARCH_DEPTH+10)
207 };
208 TBIntEntry TBIntBuf[MAX_TB_INT_ENTRIES];
209 TBPtrEntry TBPtrBuf[MAX_TB_PTR_ENTRIES];
210 TBIntEntry * TBIntTop;
211 TBPtrEntry * TBPtrTop;
212
213 void UpdateCachedInfo();
214
215 void SortMoves(Move * m, int count) const;
216
217 int Value() const;
218
219 int ValuePiece(const Piece & p) const;
220 int ValuePayingHit(const Piece & p) const;
221 int ValueThreats(const Piece & p) const;
222 int ValueMobility(const Piece & p) const;
223 int ValueTies(const Piece & p) const;
224 int ValueCenter(const Piece & p) const;
225 int ValueKing(const Piece & P) const;
226 int ValuePawn(const Piece & p) const;
227
228 bool IsAnyLegalMove() const;
229 bool IsCheck(bool invertTurn) const;
230 int EnumeratePossibleMoves(Move * buf) const;
231 bool IsThreatened(int x, int y, int tside) const;
232
233 void TBDoMove(const Move & m);
234 // Perform a move while adding all changes to the take-back
235 // buffer.
236
237 void TBLinkPiece(Piece & p);
238 void TBUnlinkPiece(Piece & p);
239 // Link or unlink a piece while adding all changes to the
240 // take-back buffer.
241
242 void TBClear();
243 // Clear the take-back buffer.
244
245 void TBStart();
246 // Add a start-mark to the take-back buffer.
247
248 void TBSetInt(int & rInt, int val);
249 void TBSetPtr(Piece * & rPtr, Piece * val);
250 // Set an integer or a pointer while adding the change to the
251 // take-back buffer.
252
253 void TakeBack();
254 // Take back changes until start-mark.
255
256 void CalcNeighbours(int x, int y, Piece * * n) const;
257
258 static int Random(int min, int max);
259
260 void PrintASCII(bool flipped, const char * lastMove) const;
261 void PrintASCII2(bool flipped, const char * lastMove) const;
262 void PrintANSI(bool flipped, const char * lastMove) const;
263 void PrintDOS(bool flipped, const char * lastMove) const;
264 void PrintMINI(bool flipped, const char * lastMove) const;
265 };
266
GetSearchDepth()267 inline int SilChessMachine::GetSearchDepth() const
268 {
269 return SearchDepth;
270 }
271
IsHumanWhite()272 inline bool SilChessMachine::IsHumanWhite() const
273 {
274 return HumanSide==TF_White;
275 }
276
SetHumanWhite(bool humanWhite)277 inline void SilChessMachine::SetHumanWhite(bool humanWhite)
278 {
279 HumanSide = humanWhite ? TF_White : TF_Black;
280 }
281
IsWhiteOn()282 inline bool SilChessMachine::IsWhiteOn() const
283 {
284 return Turn==TF_White;
285 }
286
IsHumanOn()287 inline bool SilChessMachine::IsHumanOn() const
288 {
289 return Turn==HumanSide;
290 }
291
GetMoveCount()292 inline int SilChessMachine::GetMoveCount() const
293 {
294 return MoveCount;
295 }
296
GetMove(int index)297 inline const SilChessMachine::Move & SilChessMachine::GetMove(int index) const
298 {
299 return Moves[index];
300 }
301
IsSearching()302 inline bool SilChessMachine::IsSearching() const
303 {
304 return SearchStackTop!=NULL;
305 }
306
TBClear()307 inline void SilChessMachine::TBClear()
308 {
309 TBIntTop=TBIntBuf;
310 TBPtrTop=TBPtrBuf;
311 }
312
TBStart()313 inline void SilChessMachine::TBStart()
314 {
315 TBIntTop->Ptr=NULL;
316 TBIntTop++;
317 TBPtrTop->Ptr=NULL;
318 TBPtrTop++;
319 }
320
TBSetInt(int & rInt,int val)321 inline void SilChessMachine::TBSetInt(int & rInt, int val)
322 {
323 TBIntTop->Ptr=&rInt;
324 TBIntTop->Val=rInt;
325 TBIntTop++;
326 rInt=val;
327 }
328
TBSetPtr(Piece * & rPtr,Piece * val)329 inline void SilChessMachine::TBSetPtr(Piece * & rPtr, Piece * val)
330 {
331 TBPtrTop->Ptr=&rPtr;
332 TBPtrTop->Val=rPtr;
333 TBPtrTop++;
334 rPtr=val;
335 }
336
337
338 #endif
339