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