1 #ifndef WINCE
2
3 #include <string.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 #if !defined (DEBUG) && !defined(EBUG)
7 #define NDEBUG 1
8 #endif
9 #include <assert.h>
10
11 #if defined (_WIN32)
12 #include <windows.h>
13 #endif
14
15
16 // SMP stuff
17
18 #if defined (SMP)
19 static lock_t LockLRU;
20 #else
21 #define LockInit(x)
22 #define Lock(x)
23 #define UnLock(x)
24 #endif
25
26 // Declarations
27
28 typedef unsigned char BYTE;
29 typedef unsigned long ULONG;
30 typedef signed char tb_t;
31
32 #if !defined (COLOR_DECLARED)
33 typedef int color;
34 #define x_colorWhite 0
35 #define x_colorBlack 1
36 #define x_colorNeutral 2
37 #define COLOR_DECLARED
38 #endif
39
40 #if !defined (PIECES_DECLARED)
41 typedef int piece;
42 #define x_pieceNone 0
43 #define x_piecePawn 1
44 #define x_pieceKnight 2
45 #define x_pieceBishop 3
46 #define x_pieceRook 4
47 #define x_pieceQueen 5
48 #define x_pieceKing 6
49 #define PIECES_DECLARED
50 #endif
51
52 #if !defined (SqFind2)
53 #define SqFind2(psq,pi1,sq1,pi2,sq2) sq1=SqFindFirst(psq,pi1);sq2=SqFindFirst(psq,pi2);
54 #endif
55
56 // Machine and compiler-specific declarations
57
58 #if defined (_MSC_VER)
59
60 #undef TB_CDECL
61 #define TB_CDECL __cdecl
62 #define TB_FASTCALL __fastcall
63 #if _MSC_VER >= 1200
64 #define INLINE __forceinline
65 #endif
66
67 #else
68
69 #define TB_CDECL
70 #define TB_FASTCALL
71
72 #endif
73
74 #if !defined (INLINE)
75 #define INLINE inline
76 #endif
77
78 // Some constants from SJE program
79
80 #define pageL 256
81
82 /* tablebase byte entry semispan length */
83
84 #define tbbe_ssL ((pageL - 4) / 2)
85
86 /* tablebase signed byte entry values */
87
88 #define bev_broken (tbbe_ssL + 1) /* illegal or busted */
89
90 #define bev_mi1 tbbe_ssL /* mate in 1 move */
91 #define bev_mimin 1 /* mate in 126 moves */
92
93 #define bev_draw 0 /* draw */
94
95 #define bev_limax (-1) /* mated in 125 moves */
96 #define bev_li0 (-tbbe_ssL) /* mated in 0 moves */
97
98 #define bev_limaxx (-tbbe_ssL - 1) /* mated in 126 moves */
99 #define bev_miminx (-tbbe_ssL - 2) /* mate in 127 moves */
100
101 // Some constants for 16-bit tables
102
103 #define L_pageL 65536
104
105 /* tablebase short entry semispan length */
106
107 #define L_tbbe_ssL ((L_pageL - 4) / 2)
108
109 /* tablebase signed short entry values */
110
111 #define L_bev_broken (L_tbbe_ssL + 1) /* illegal or busted */
112
113 #define L_bev_mi1 L_tbbe_ssL /* mate in 1 move */
114 #define L_bev_mimin 1 /* mate in 32766 moves */
115
116 #define L_bev_draw 0 /* draw */
117
118 #define L_bev_limax (-1) /* mated in 32765 moves */
119 #define L_bev_li0 (-L_tbbe_ssL) /* mated in 0 moves */
120
121 #define L_bev_limaxx (-L_tbbe_ssL - 1) /* mated in 32766 moves */
122 #define L_bev_miminx (-L_tbbe_ssL - 2) /* mate in 32767 moves */
123
124 // Conversion from 8-bit to 16-bit score
125 // UNDONE: Maybe implement via lookup table?
126
127 #define S_to_L(tbt)\
128 (\
129 (0 == tbt) ? 0:\
130 (tbt > 0) ? (bev_broken != tbt ? tbt + 32640 : L_bev_broken):\
131 (tbt >= bev_li0) ? tbt - 32640:\
132 (bev_limaxx == tbt) ? -32640:\
133 /*bev_miminx == tbt*/ 32640\
134 )
135
136 // Constants
137
138 #define i8 ((INDEX) 8)
139 #define i14 ((INDEX) 14)
140 #define i44 ((INDEX) 44)
141 #define i46 ((INDEX) 46)
142 #define i47 ((INDEX) 47)
143 #define i48 ((INDEX) 48)
144 #define i58 ((INDEX) 58)
145 #define i60 ((INDEX) 60)
146 #define i61 ((INDEX) 61)
147 #define i62 ((INDEX) 62)
148 #define i63 ((INDEX) 63)
149 #define i64 ((INDEX) 64)
150
151 #define x_row_1 0
152 #define x_row_2 1
153 #define x_row_3 2
154 #define x_row_4 3
155 #define x_row_5 4
156 #define x_row_6 5
157 #define x_row_7 6
158 #define x_row_8 7
159
160 #define x_column_a 0
161 #define x_column_b 1
162 #define x_column_c 2
163 #define x_column_d 3
164 #define x_column_e 4
165 #define x_column_f 5
166 #define x_column_g 6
167 #define x_column_h 7
168
169 /* reflection macros */
170
171 #define reflect_x(sq) ((sq) ^ 0x38)
172 #define reflect_y(sq) ((sq) ^ 0x07)
173 #define reflect_xy(sq) rgsqReflectXY[sq]
174
175 static const square rgsqReflectXY [] =
176 {
177 0, 8, 16, 24, 32, 40, 48, 56,
178 1, 9, 17, 25, 33, 41, 49, 57,
179 2, 10, 18, 26, 34, 42, 50, 58,
180 3, 11, 19, 27, 35, 43, 51, 59,
181 4, 12, 20, 28, 36, 44, 52, 60,
182 5, 13, 21, 29, 37, 45, 53, 61,
183 6, 14, 22, 30, 38, 46, 54, 62,
184 7, 15, 23, 31, 39, 47, 55, 63,
185 };
186
187 static const square rgsqReflectMaskY [] =
188 {
189 0, 0, 0, 0, 7, 7, 7, 7,
190 0, 0, 0, 0, 7, 7, 7, 7,
191 0, 0, 0, 0, 7, 7, 7, 7,
192 0, 0, 0, 0, 7, 7, 7, 7,
193 0, 0, 0, 0, 7, 7, 7, 7,
194 0, 0, 0, 0, 7, 7, 7, 7,
195 0, 0, 0, 0, 7, 7, 7, 7,
196 0, 0, 0, 0, 7, 7, 7, 7,
197 };
198
199 static const square rgsqReflectMaskYandX [] =
200 {
201 0, 0, 0, 0, 7, 7, 7, 7,
202 0, 0, 0, 0, 7, 7, 7, 7,
203 0, 0, 0, 0, 7, 7, 7, 7,
204 0, 0, 0, 0, 7, 7, 7, 7,
205 0x38, 0x38, 0x38, 0x38, 0x38+7, 0x38+7, 0x38+7, 0x38+7,
206 0x38, 0x38, 0x38, 0x38, 0x38+7, 0x38+7, 0x38+7, 0x38+7,
207 0x38, 0x38, 0x38, 0x38, 0x38+7, 0x38+7, 0x38+7, 0x38+7,
208 0x38, 0x38, 0x38, 0x38, 0x38+7, 0x38+7, 0x38+7, 0x38+7,
209 };
210
211 static const square rgsqReflectInvertMask[] = { 0, 0x38 };
212
213 /* useful macros */
214
215 #define TbRow(sq) ((sq) >> 3)
216 #define TbColumn(sq) ((sq) & 7)
217
218 #if defined (NEW)
219 #define PchExt(side) ((x_colorWhite == side) ? ".nbw" : ".nbb")
220 #else
221 #define PchExt(side) ((x_colorWhite == side) ? ".tbw" : ".tbb")
222 #endif
223
224 // Verbose levels
225
226 static bool fPrint = false; // Print some technical statistics
227 static bool fVerbose = false; // Print additional information
228
229 // Malloc that checks for out-of-memory condition
230
231 static unsigned long cbAllocated;
232
PvMalloc(unsigned long cb)233 static void* PvMalloc
234 (
235 unsigned long cb
236 )
237 {
238 void *pv;
239
240 #ifdef WINCE
241 pv = my_Tcl_Alloc (cb);
242 #else
243 pv = malloc (cb);
244 #endif
245 if (NULL == pv)
246 {
247 printf("*** Cannot allocate %lu bytes of memory\n", cb);
248 exit (1);
249 }
250 cbAllocated += cb;
251 return pv;
252 }
253
254 #if defined (NEW) // New index schema ----------------------------------------
255
256 // 'Invalid' value have to be large, so index
257 // of invalid position will be very large, too.
258
259 #define INF 4000
260
261 // Enumeration: valid positions with 2 kings on board; white king restricted to
262 // a1-d1-d4 triangle; also, if it's at a1-d4 half-diagonal, then black king
263 // must be in a1-h1-h8 triangle
264
265 static const short rgsTriKings [64 * 64] =
266 {
267 INF, INF, 0, 1, 2, 3, 4, 5, INF, INF, 6, 7, 8, 9, 10, 11,
268 INF, INF, 12, 13, 14, 15, 16, 17, INF, INF, INF, 18, 19, 20, 21, 22,
269 INF, INF, INF, INF, 23, 24, 25, 26, INF, INF, INF, INF, INF, 27, 28, 29,
270 INF, INF, INF, INF, INF, INF, 30, 31, INF, INF, INF, INF, INF, INF, INF, 32,
271 INF, INF, INF, 33, 34, 35, 36, 37, INF, INF, INF, 38, 39, 40, 41, 42,
272 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
273 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
274 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
275 91, INF, INF, INF, 92, 93, 94, 95, 96, INF, INF, INF, 97, 98, 99, 100,
276 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
277 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,
278 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,
279 149, 150, INF, INF, INF, 151, 152, 153, 154, 155, INF, INF, INF, 156, 157, 158,
280 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174,
281 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190,
282 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206,
283 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
284 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
285 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
286 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
287 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
288 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
289 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
290 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
291 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
292 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
293 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
294 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
295 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
296 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
297 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
298 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
299 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
300 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
301 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
302 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
303 INF, INF, INF, 207, 208, 209, 210, 211, INF, INF, INF, 212, 213, 214, 215, 216,
304 INF, INF, INF, 217, 218, 219, 220, 221, INF, INF, INF, 222, 223, 224, 225, 226,
305 INF, INF, INF, INF, 227, 228, 229, 230, INF, INF, INF, INF, INF, 231, 232, 233,
306 INF, INF, INF, INF, INF, INF, 234, 235, INF, INF, INF, INF, INF, INF, INF, 236,
307 237, INF, INF, INF, 238, 239, 240, 241, 242, INF, INF, INF, 243, 244, 245, 246,
308 247, INF, INF, INF, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259,
309 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275,
310 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291,
311 292, 293, INF, INF, INF, 294, 295, 296, 297, 298, INF, INF, INF, 299, 300, 301,
312 302, 303, INF, INF, INF, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
313 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330,
314 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346,
315 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
316 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
317 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
318 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
319 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
320 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
321 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
322 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
323 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
324 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
325 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
326 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
327 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
328 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
329 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
330 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
331 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
332 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
333 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
334 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
335 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
336 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
337 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
338 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
339 347, 348, 349, 350, 351, 352, 353, 354, INF, INF, INF, INF, 355, 356, 357, 358,
340 INF, INF, INF, INF, 359, 360, 361, 362, INF, INF, INF, INF, 363, 364, 365, 366,
341 INF, INF, INF, INF, 367, 368, 369, 370, INF, INF, INF, INF, INF, 371, 372, 373,
342 INF, INF, INF, INF, INF, INF, 374, 375, INF, INF, INF, INF, INF, INF, INF, 376,
343 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, INF, INF, INF, 387, 388, 389,
344 390, 391, INF, INF, INF, 392, 393, 394, 395, 396, INF, INF, INF, 397, 398, 399,
345 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415,
346 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431,
347 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
348 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
349 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
350 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
351 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
352 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
353 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
354 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
355 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
356 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
357 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
358 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
359 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
360 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
361 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
362 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
363 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
364 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
365 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
366 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
367 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
368 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
369 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
370 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
371 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
372 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
373 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
374 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
375 432, 433, 434, 435, 436, 437, 438, 439, INF, 440, 441, 442, 443, 444, 445, 446,
376 INF, INF, INF, INF, INF, 447, 448, 449, INF, INF, INF, INF, INF, 450, 451, 452,
377 INF, INF, INF, INF, INF, 453, 454, 455, INF, INF, INF, INF, INF, 456, 457, 458,
378 INF, INF, INF, INF, INF, INF, 459, 460, INF, INF, INF, INF, INF, INF, INF, 461,
379 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
380 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
381 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
382 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
383 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
384 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
385 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
386 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
387 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
388 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
389 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
390 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
391 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
392 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
393 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
394 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
395 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
396 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
397 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
398 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
399 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
400 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
401 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
402 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
403 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
404 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
405 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
406 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
407 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
408 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
409 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
410 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
411 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
412 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
413 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
414 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
415 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
416 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
417 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
418 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
419 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
420 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
421 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
422 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
423 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
424 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
425 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
426 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
427 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
428 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
429 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
430 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
431 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
432 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
433 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
434 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
435 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
436 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
437 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
438 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
439 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
440 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
441 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
442 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
443 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
444 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
445 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
446 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
447 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
448 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
449 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
450 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
451 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
452 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
453 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
454 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
455 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
456 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
457 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
458 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
459 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
460 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
461 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
462 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
463 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
464 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
465 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
466 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
467 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
468 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
469 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
470 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
471 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
472 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
473 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
474 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
475 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
476 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
477 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
478 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
479 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
480 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
481 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
482 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
483 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
484 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
485 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
486 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
487 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
488 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
489 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
490 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
491 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
492 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
493 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
494 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
495 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
496 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
497 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
498 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
499 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
500 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
501 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
502 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
503 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
504 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
505 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
506 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
507 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
508 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
509 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
510 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
511 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
512 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
513 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
514 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
515 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
516 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
517 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
518 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
519 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
520 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
521 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
522 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
523 };
524
525 // Enumeration: all valid positions with 2 kings on board when white king
526 // restricted to left half of the board
527
528 static const short rgsHalfKings [64 * 64] =
529 {
530 INF, INF, 0, 1, 2, 3, 4, 5, INF, INF, 6, 7, 8, 9, 10, 11,
531 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
532 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
533 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
534 INF, INF, INF, 60, 61, 62, 63, 64, INF, INF, INF, 65, 66, 67, 68, 69,
535 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
536 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
537 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
538 118, INF, INF, INF, 119, 120, 121, 122, 123, INF, INF, INF, 124, 125, 126, 127,
539 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
540 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
541 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
542 176, 177, INF, INF, INF, 178, 179, 180, 181, 182, INF, INF, INF, 183, 184, 185,
543 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201,
544 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217,
545 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233,
546 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
547 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
548 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
549 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
550 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
551 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
552 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
553 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
554 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
555 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
556 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
557 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
558 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
559 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
560 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
561 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
562 INF, INF, 234, 235, 236, 237, 238, 239, INF, INF, 240, 241, 242, 243, 244, 245,
563 INF, INF, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259,
564 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275,
565 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291,
566 INF, INF, INF, 292, 293, 294, 295, 296, INF, INF, INF, 297, 298, 299, 300, 301,
567 INF, INF, INF, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
568 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330,
569 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346,
570 347, INF, INF, INF, 348, 349, 350, 351, 352, INF, INF, INF, 353, 354, 355, 356,
571 357, INF, INF, INF, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369,
572 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385,
573 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401,
574 402, 403, INF, INF, INF, 404, 405, 406, 407, 408, INF, INF, INF, 409, 410, 411,
575 412, 413, INF, INF, INF, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424,
576 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440,
577 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456,
578 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
579 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
580 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
581 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
582 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
583 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
584 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
585 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
586 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
587 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
588 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
589 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
590 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
591 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
592 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
593 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
594 457, 458, 459, 460, 461, 462, 463, 464, INF, INF, 465, 466, 467, 468, 469, 470,
595 INF, INF, 471, 472, 473, 474, 475, 476, INF, INF, 477, 478, 479, 480, 481, 482,
596 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498,
597 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514,
598 515, 516, 517, 518, 519, 520, 521, 522, INF, INF, INF, 523, 524, 525, 526, 527,
599 INF, INF, INF, 528, 529, 530, 531, 532, INF, INF, INF, 533, 534, 535, 536, 537,
600 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553,
601 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569,
602 570, 571, 572, 573, 574, 575, 576, 577, 578, INF, INF, INF, 579, 580, 581, 582,
603 583, INF, INF, INF, 584, 585, 586, 587, 588, INF, INF, INF, 589, 590, 591, 592,
604 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608,
605 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624,
606 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, INF, INF, INF, 635, 636, 637,
607 638, 639, INF, INF, INF, 640, 641, 642, 643, 644, INF, INF, INF, 645, 646, 647,
608 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663,
609 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679,
610 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
611 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
612 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
613 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
614 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
615 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
616 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
617 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
618 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
619 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
620 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
621 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
622 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
623 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
624 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
625 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
626 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695,
627 INF, INF, 696, 697, 698, 699, 700, 701, INF, INF, 702, 703, 704, 705, 706, 707,
628 INF, INF, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721,
629 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737,
630 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753,
631 INF, INF, INF, 754, 755, 756, 757, 758, INF, INF, INF, 759, 760, 761, 762, 763,
632 INF, INF, INF, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776,
633 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792,
634 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808,
635 809, INF, INF, INF, 810, 811, 812, 813, 814, INF, INF, INF, 815, 816, 817, 818,
636 819, INF, INF, INF, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831,
637 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847,
638 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863,
639 864, 865, INF, INF, INF, 866, 867, 868, 869, 870, INF, INF, INF, 871, 872, 873,
640 874, 875, INF, INF, INF, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886,
641 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902,
642 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
643 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
644 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
645 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
646 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
647 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
648 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
649 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
650 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
651 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
652 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
653 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
654 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
655 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
656 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
657 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
658 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918,
659 919, 920, 921, 922, 923, 924, 925, 926, INF, INF, 927, 928, 929, 930, 931, 932,
660 INF, INF, 933, 934, 935, 936, 937, 938, INF, INF, 939, 940, 941, 942, 943, 944,
661 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960,
662 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976,
663 977, 978, 979, 980, 981, 982, 983, 984, INF, INF, INF, 985, 986, 987, 988, 989,
664 INF, INF, INF, 990, 991, 992, 993, 994, INF, INF, INF, 995, 996, 997, 998, 999,
665 1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,
666 1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,
667 1032,1033,1034,1035,1036,1037,1038,1039,1040, INF, INF, INF,1041,1042,1043,1044,
668 1045, INF, INF, INF,1046,1047,1048,1049,1050, INF, INF, INF,1051,1052,1053,1054,
669 1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,
670 1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,
671 1087,1088,1089,1090,1091,1092,1093,1094,1095,1096, INF, INF, INF,1097,1098,1099,
672 1100,1101, INF, INF, INF,1102,1103,1104,1105,1106, INF, INF, INF,1107,1108,1109,
673 1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,
674 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
675 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
676 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
677 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
678 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
679 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
680 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
681 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
682 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
683 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
684 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
685 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
686 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
687 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
688 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
689 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
690 1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,
691 1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,
692 INF, INF,1158,1159,1160,1161,1162,1163, INF, INF,1164,1165,1166,1167,1168,1169,
693 INF, INF,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,
694 1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,
695 1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215,
696 INF, INF, INF,1216,1217,1218,1219,1220, INF, INF, INF,1221,1222,1223,1224,1225,
697 INF, INF, INF,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,1238,
698 1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,
699 1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,
700 1271, INF, INF, INF,1272,1273,1274,1275,1276, INF, INF, INF,1277,1278,1279,1280,
701 1281, INF, INF, INF,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,
702 1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,
703 1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,
704 1326,1327, INF, INF, INF,1328,1329,1330,1331,1332, INF, INF, INF,1333,1334,1335,
705 1336,1337, INF, INF, INF,1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,
706 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
707 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
708 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
709 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
710 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
711 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
712 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
713 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
714 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
715 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
716 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
717 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
718 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
719 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
720 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
721 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
722 1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1364,
723 1365,1366,1367,1368,1369,1370,1371,1372,1373,1374,1375,1376,1377,1378,1379,1380,
724 1381,1382,1383,1384,1385,1386,1387,1388, INF, INF,1389,1390,1391,1392,1393,1394,
725 INF, INF,1395,1396,1397,1398,1399,1400, INF, INF,1401,1402,1403,1404,1405,1406,
726 1407,1408,1409,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,
727 1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,
728 1439,1440,1441,1442,1443,1444,1445,1446, INF, INF, INF,1447,1448,1449,1450,1451,
729 INF, INF, INF,1452,1453,1454,1455,1456, INF, INF, INF,1457,1458,1459,1460,1461,
730 1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,
731 1478,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,
732 1494,1495,1496,1497,1498,1499,1500,1501,1502, INF, INF, INF,1503,1504,1505,1506,
733 1507, INF, INF, INF,1508,1509,1510,1511,1512, INF, INF, INF,1513,1514,1515,1516,
734 1517,1518,1519,1520,1521,1522,1523,1524,1525,1526,1527,1528,1529,1530,1531,1532,
735 1533,1534,1535,1536,1537,1538,1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,
736 1549,1550,1551,1552,1553,1554,1555,1556,1557,1558, INF, INF, INF,1559,1560,1561,
737 1562,1563, INF, INF, INF,1564,1565,1566,1567,1568, INF, INF, INF,1569,1570,1571,
738 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
739 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
740 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
741 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
742 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
743 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
744 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
745 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
746 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
747 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
748 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
749 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
750 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
751 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
752 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
753 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
754 1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,
755 1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600,1601,1602,1603,
756 1604,1605,1606,1607,1608,1609,1610,1611,1612,1613,1614,1615,1616,1617,1618,1619,
757 INF, INF,1620,1621,1622,1623,1624,1625, INF, INF,1626,1627,1628,1629,1630,1631,
758 1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1642,1643,1644,1645,1646,1647,
759 1648,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,1659,1660,1661,1662,1663,
760 1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,1674,1675,1676,1677,1678,1679,
761 INF, INF, INF,1680,1681,1682,1683,1684, INF, INF, INF,1685,1686,1687,1688,1689,
762 1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,
763 1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721,
764 1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,1734,1735,1736,1737,
765 1738, INF, INF, INF,1739,1740,1741,1742,1743, INF, INF, INF,1744,1745,1746,1747,
766 1748,1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,
767 1764,1765,1766,1767,1768,1769,1770,1771,1772,1773,1774,1775,1776,1777,1778,1779,
768 1780,1781,1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793,1794,1795,
769 1796,1797, INF, INF, INF,1798,1799,1800,1801,1802, INF, INF, INF,1803,1804,1805,
770 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
771 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
772 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
773 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
774 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
775 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
776 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
777 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
778 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
779 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
780 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
781 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
782 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
783 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
784 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
785 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
786 };
787
788 // Useful macro and enumeration tables
789
790 #define IndTriKings(sqk1,sqk2) ((INDEX) rgsTriKings[sqk1*64+sqk2])
791 #define IndHalfKings(sqk1,sqk2) ((INDEX) rgsHalfKings[sqk1*64+sqk2])
792
793 static const bool rgfTriangle[64] =
794 {
795 true, true, true, true, false, false, false, false,
796 false, true, true, true, false, false, false, false,
797 false, false, true, true, false, false, false, false,
798 false, false, false, true, false, false, false, false,
799 false, false, false, false, false, false, false, false,
800 false, false, false, false, false, false, false, false,
801 false, false, false, false, false, false, false, false,
802 false, false, false, false, false, false, false, false,
803 };
804
805 static const bool rgfNotDiagonal[64] =
806 {
807 false, true, true, true, true, true, true, true,
808 true, false, true, true, true, true, true, true,
809 true, true, false, true, true, true, true, true,
810 true, true, true, false, true, true, true, true,
811 true, true, true, true, false, true, true, true,
812 true, true, true, true, true, false, true, true,
813 true, true, true, true, true, true, false, true,
814 true, true, true, true, true, true, true, false,
815 };
816
817 static const bool rgfInLargeTriangle[64] =
818 {
819 true, true, true, true, true, true, true, true,
820 false, true, true, true, true, true, true, true,
821 false, false, true, true, true, true, true, true,
822 false, false, false, true, true, true, true, true,
823 false, false, false, false, true, true, true, true,
824 false, false, false, false, false, true, true, true,
825 false, false, false, false, false, false, true, true,
826 false, false, false, false, false, false, false, true,
827 };
828
829 #define FInTriangle(sqwk,sqbk) (rgfTriangle[sqwk] & (rgfNotDiagonal[sqwk]|rgfInLargeTriangle[sqbk]))
830
831 // Sort pieces
832
833 #define SORT(sq1,sq2) if (sq1>sq2) { square sqTmp; sqTmp=sq1; sq1=sq2; sq2=sqTmp; }
834
835 // Exclude occupied squares
836
837 #define EXCLUDE1(sq,sq1) (sq-(sq>sq1))
838 #define EXCLUDE2(sq,sq1,sq2) (sq-((sq>sq1)+(sq>sq2)))
839 #define EXCLUDE3(sq,sq1,sq2,sq3) (sq-((sq>sq1)+(sq>sq2)+(sq>sq3)))
840 #define EXCLUDE4(sq,sq1,sq2,sq3,sq4) (sq-((sq>sq1)+(sq>sq2)+(sq>sq3)+(sq>sq4)))
841 #define EXCLUDE6(sq,sq1,sq2,sq3,sq4,sq5,sq6) (sq-((sq>sq1)+(sq>sq2)+(sq>sq3)+(sq>sq4)+(sq>sq5)+(sq>sq6)))
842
843 // Calculate index - a lot of functions...
844
845 // Enumeration tables
846
847 static BYTE *rgprgsqPiece[6]; // Enumeration for each piece (0 - black pawn)
848 // For each position of the King, all legal squares
849 // of the opposite piece enumerated
850 static BYTE rgcLegal[6][64]; // # of enumerated positions for each piece and each
851 // location of enemy king
852
853 // Enumerations - indexed by [piece] and [kings enumeration].
854 // In each table for each [piece] and [king enumeration] we store # of preceding positions.
855
856 static ULONG *rgprgulSinglePawnless[6];
857 static ULONG *rgprgulPairPawnless[6][6];
858 #if defined (T41_INCLUDE)
859 static ULONG *rgprgulTriplePawnless[6][6][6];
860 #endif
861 static ULONG *rgprgulSinglePawnPresent[6];
862 static ULONG *rgprgulPairPawnPresent[6][6];
863 #if defined (T41_INCLUDE)
864 static ULONG *rgprgulTriplePawnPresent[6][6][6];
865 #endif
866
867 // Total # of enumerated positions
868
869 static ULONG rgcSinglePawnPresent[6];
870 static ULONG rgcSinglePawnless[6];
871 static ULONG rgcPairPawnPresent[6][6];
872 static ULONG rgcPairPawnless[6][6];
873 #if defined (T41_INCLUDE)
874 static ULONG rgcTriplePawnPresent[6][6][6];
875 static ULONG rgcTriplePawnless[6][6][6];
876 #endif
877
878 // Infinities. Have to be larger than any legal enumeration yet small enough
879 // so there will be no overflow when combining them with remaining pieces.
880
881 #define INF_SINGLE (110000)
882 #define INF_PAIR (6500000)
883 #define INF_TRIPLE (300000000)
884
885 // Initialize squares and counters table for one piece.
886 // Piece can be x_pieceNone - that means 'pawn of the wrong color', e.g. KPK BTM.
887
VInitSquaresTable(piece pi,BYTE * prgsqPiece,BYTE * prgcLegal)888 static void VInitSquaresTable
889 (
890 piece pi,
891 BYTE *prgsqPiece,
892 BYTE *prgcLegal
893 )
894 {
895 int sqLo, sqHi;
896
897 memset (prgsqPiece, -1, 64*64);
898 sqLo = 0;
899 sqHi = 64;
900 if (pi <= x_piecePawn)
901 {
902 sqLo = 8;
903 sqHi = 56;
904 }
905 for (int sqKing = 0; sqKing < 64; sqKing ++)
906 {
907 int iPiece;
908
909 iPiece = 0;
910 for (int sq = sqLo; sq < sqHi; sq ++)
911 {
912 if (sq == sqKing)
913 continue;
914 switch (pi)
915 {
916 case x_piecePawn:
917 if (
918 ( 0 != TbColumn (sq) && sqKing == sq+7 ) ||
919 ( 7 != TbColumn (sq) && sqKing == sq+9 )
920 )
921 continue;
922 break;
923 case x_pieceKnight:
924 if (
925 ( TbRow (sq) >= 2 && TbColumn (sq) >= 1 && sqKing == sq-17 ) ||
926 ( TbRow (sq) >= 2 && TbColumn (sq) <= 6 && sqKing == sq-15 ) ||
927 ( TbRow (sq) >= 1 && TbColumn (sq) >= 2 && sqKing == sq-10 ) ||
928 ( TbRow (sq) >= 1 && TbColumn (sq) <= 5 && sqKing == sq-6 ) ||
929 ( TbRow (sq) <= 6 && TbColumn (sq) >= 2 && sqKing == sq+6 ) ||
930 ( TbRow (sq) <= 6 && TbColumn (sq) <= 5 && sqKing == sq+10 ) ||
931 ( TbRow (sq) <= 5 && TbColumn (sq) >= 1 && sqKing == sq+15 ) ||
932 ( TbRow (sq) <= 5 && TbColumn (sq) <= 6 && sqKing == sq+17 )
933 )
934 continue;
935 break;
936 case x_pieceBishop:
937 if (
938 ( 0 != TbRow (sq) && 0 != TbColumn (sq) && sqKing == sq-9 ) ||
939 ( 0 != TbRow (sq) && 7 != TbColumn (sq) && sqKing == sq-7 ) ||
940 ( 7 != TbRow (sq) && 0 != TbColumn (sq) && sqKing == sq+7 ) ||
941 ( 7 != TbRow (sq) && 7 != TbColumn (sq) && sqKing == sq+9 )
942 )
943 continue;
944 break;
945 case x_pieceRook:
946 if (
947 ( 0 != TbColumn (sq) && sqKing == sq-1 ) ||
948 ( 7 != TbColumn (sq) && sqKing == sq+1 ) ||
949 ( 0 != TbRow (sq) && sqKing == sq-8 ) ||
950 ( 7 != TbRow (sq) && sqKing == sq+8 )
951 )
952 continue;
953 break;
954 case x_pieceQueen:
955 if (
956 ( 0 != TbColumn (sq) && sqKing == sq-1 ) ||
957 ( 7 != TbColumn (sq) && sqKing == sq+1 ) ||
958 ( 0 != TbRow (sq) && sqKing == sq-8 ) ||
959 ( 7 != TbRow (sq) && sqKing == sq+8 ) ||
960 ( 0 != TbRow (sq) && 0 != TbColumn (sq) && sqKing == sq-9 ) ||
961 ( 0 != TbRow (sq) && 7 != TbColumn (sq) && sqKing == sq-7 ) ||
962 ( 7 != TbRow (sq) && 0 != TbColumn (sq) && sqKing == sq+7 ) ||
963 ( 7 != TbRow (sq) && 7 != TbColumn (sq) && sqKing == sq+9 )
964 )
965 continue;
966 break;
967 }
968 prgsqPiece[sqKing*64+sq] = (BYTE) iPiece;
969 iPiece ++;
970 }
971 prgcLegal[sqKing] = (BYTE) iPiece;
972 }
973 }
974
975 // Initialize enumeration table for single piece
976
VInitSingle(ULONG * prgIndex,const short * prgsKings,const BYTE * prgcLegal,const BYTE * prgsqPiece,ULONG * pcEnumeration)977 static void VInitSingle
978 (
979 ULONG *prgIndex,
980 const short *prgsKings,
981 const BYTE *prgcLegal,
982 const BYTE *prgsqPiece,
983 ULONG *pcEnumeration
984 )
985 {
986 ULONG iIndex;
987
988 iIndex = 0;
989 for (int sqKing1 = 0; sqKing1 < 64; sqKing1 ++)
990 for (int sqKing2 = 0; sqKing2 < 64; sqKing2 ++)
991 {
992 if (INF != prgsKings[sqKing1*64+sqKing2])
993 {
994 prgIndex[prgsKings[sqKing1*64+sqKing2]] = iIndex;
995 iIndex += prgcLegal[sqKing2] - ((BYTE) -1 != prgsqPiece[sqKing2*64+sqKing1]);
996 }
997 }
998 *pcEnumeration = iIndex;
999 }
1000
1001 // Initialize enumeration table for pair of pieces
1002
VInitPair(ULONG * prgIndex,const short * prgsKings,const BYTE * prgcLegal1,const BYTE * prgsqPiece1,const BYTE * prgcLegal2,const BYTE * prgsqPiece2,ULONG * pcEnumeration)1003 static void VInitPair
1004 (
1005 ULONG *prgIndex,
1006 const short *prgsKings,
1007 const BYTE *prgcLegal1,
1008 const BYTE *prgsqPiece1,
1009 const BYTE *prgcLegal2,
1010 const BYTE *prgsqPiece2,
1011 ULONG *pcEnumeration
1012 )
1013 {
1014 ULONG iIndex;
1015 ULONG cPositions1, cPositions2;
1016
1017 iIndex = 0;
1018 for (int sqKing1 = 0; sqKing1 < 64; sqKing1 ++)
1019 for (int sqKing2 = 0; sqKing2 < 64; sqKing2 ++)
1020 {
1021 if (INF != prgsKings[sqKing1*64+sqKing2])
1022 {
1023 prgIndex[prgsKings[sqKing1*64+sqKing2]] = iIndex;
1024 cPositions1 = prgcLegal1[sqKing2] - ((BYTE) -1 != prgsqPiece1[sqKing2*64+sqKing1]);
1025 if (prgcLegal1 == prgcLegal2)
1026 iIndex += cPositions1*(cPositions1-1)/2;
1027 else
1028 {
1029 cPositions2 = prgcLegal2[sqKing2] - ((BYTE) -1 != prgsqPiece2[sqKing2*64+sqKing1]);
1030 iIndex += cPositions1*cPositions2;
1031 }
1032 }
1033 }
1034 *pcEnumeration = iIndex;
1035 }
1036
1037 #if defined (T41_INCLUDE)
1038
1039 // Initialize enumeration table for triple piece
1040
VInitTriple(ULONG * prgIndex,const short * prgsKings,const BYTE * prgcLegal1,const BYTE * prgsqPiece1,const BYTE * prgcLegal2,const BYTE * prgsqPiece2,const BYTE * prgcLegal3,const BYTE * prgsqPiece3,ULONG * pcEnumeration)1041 static void VInitTriple
1042 (
1043 ULONG *prgIndex,
1044 const short *prgsKings,
1045 const BYTE *prgcLegal1,
1046 const BYTE *prgsqPiece1,
1047 const BYTE *prgcLegal2,
1048 const BYTE *prgsqPiece2,
1049 const BYTE *prgcLegal3,
1050 const BYTE *prgsqPiece3,
1051 ULONG *pcEnumeration
1052 )
1053 {
1054 ULONG iIndex;
1055 ULONG cPositions1, cPositions2, cPositions3;
1056
1057 iIndex = 0;
1058 for (int sqKing1 = 0; sqKing1 < 64; sqKing1 ++)
1059 for (int sqKing2 = 0; sqKing2 < 64; sqKing2 ++)
1060 {
1061 if (INF != prgsKings[sqKing1*64+sqKing2])
1062 {
1063 prgIndex[prgsKings[sqKing1*64+sqKing2]] = iIndex;
1064 cPositions1 = prgcLegal1[sqKing2] - ((BYTE) -1 != prgsqPiece1[sqKing2*64+sqKing1]);
1065 if (prgcLegal1 == prgcLegal2 && prgcLegal2 == prgcLegal3)
1066 iIndex += cPositions1*(cPositions1-1)*(cPositions1-2)/6;
1067 else if (prgcLegal1 == prgcLegal2)
1068 {
1069 cPositions3 = prgcLegal3[sqKing2] - ((BYTE) -1 != prgsqPiece3[sqKing2*64+sqKing1]);
1070 iIndex += cPositions1*(cPositions1-1)/2*cPositions3;
1071 }
1072 else if (prgcLegal2 == prgcLegal3)
1073 {
1074 cPositions2 = prgcLegal2[sqKing2] - ((BYTE) -1 != prgsqPiece2[sqKing2*64+sqKing1]);
1075 iIndex += cPositions1*cPositions2*(cPositions2-1)/2;
1076 }
1077 else
1078 {
1079 cPositions2 = prgcLegal2[sqKing2] - ((BYTE) -1 != prgsqPiece2[sqKing2*64+sqKing1]);
1080 cPositions3 = prgcLegal3[sqKing2] - ((BYTE) -1 != prgsqPiece3[sqKing2*64+sqKing1]);
1081 iIndex += cPositions1*cPositions2*cPositions3;
1082 }
1083 }
1084 }
1085 *pcEnumeration = iIndex;
1086 }
1087
1088 #endif
1089
1090 // Initialize all enumeration tables
1091
1092 static bool fEnumerationInitted = false;
1093
VInitEnumerations(void)1094 static void VInitEnumerations (void)
1095 {
1096 piece pi1;
1097 piece pi2;
1098 #if defined (T41_INCLUDE)
1099 piece pi3;
1100 #endif
1101
1102 if (fEnumerationInitted)
1103 return;
1104 fEnumerationInitted = true;
1105 // Initialize square tables
1106 for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
1107 {
1108 rgprgsqPiece[pi1] = (BYTE *) PvMalloc (64*64);
1109 VInitSquaresTable (pi1, rgprgsqPiece[pi1], rgcLegal[pi1]);
1110 }
1111
1112 for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
1113 {
1114 // Initialize enumeration tables for single piece
1115 rgprgulSinglePawnPresent[pi1] = (ULONG *) PvMalloc (1806*sizeof (ULONG));
1116 VInitSingle (rgprgulSinglePawnPresent[pi1], rgsHalfKings,
1117 rgcLegal[pi1], rgprgsqPiece[pi1], &rgcSinglePawnPresent[pi1]);
1118 if (pi1 > x_piecePawn)
1119 {
1120 rgprgulSinglePawnless[pi1] = (ULONG *) PvMalloc (462*sizeof (ULONG));
1121 VInitSingle (rgprgulSinglePawnless[pi1], rgsTriKings,
1122 rgcLegal[pi1], rgprgsqPiece[pi1], &rgcSinglePawnless[pi1]);
1123 }
1124 // Initialize enumeration tables for pair of pieces
1125 for (pi2 = (x_pieceNone == pi1 ? x_pieceNone : x_piecePawn); pi2 <= pi1; pi2 = (piece) (pi2 + 1))
1126 {
1127 rgprgulPairPawnPresent[pi1][pi2] = (ULONG *) PvMalloc (1806*sizeof (ULONG));
1128 VInitPair (rgprgulPairPawnPresent[pi1][pi2], rgsHalfKings,
1129 rgcLegal[pi1], rgprgsqPiece[pi1], rgcLegal[pi2], rgprgsqPiece[pi2],
1130 &rgcPairPawnPresent[pi1][pi2]);
1131 if (pi1 > x_piecePawn && pi2 > x_piecePawn)
1132 {
1133 rgprgulPairPawnless[pi1][pi2] = (ULONG *) PvMalloc (462*sizeof (ULONG));
1134 VInitPair (rgprgulPairPawnless[pi1][pi2], rgsTriKings,
1135 rgcLegal[pi1], rgprgsqPiece[pi1], rgcLegal[pi2], rgprgsqPiece[pi2],
1136 &rgcPairPawnless[pi1][pi2]);
1137 }
1138 #if defined (T41_INCLUDE)
1139 // Initialize enumeration tables for three pieces
1140 for (pi3 = (x_pieceNone == pi1 ? x_pieceNone : x_piecePawn); pi3 <= pi2; pi3 = (piece) (pi3 + 1))
1141 {
1142 if (pi1 <= x_piecePawn || pi2 <= x_piecePawn || pi3 <= x_piecePawn)
1143 {
1144 rgprgulTriplePawnPresent[pi1][pi2][pi3] = (ULONG *) PvMalloc (1806*sizeof (ULONG));
1145 VInitTriple (rgprgulTriplePawnPresent[pi1][pi2][pi3], rgsHalfKings,
1146 rgcLegal[pi1], rgprgsqPiece[pi1],
1147 rgcLegal[pi2], rgprgsqPiece[pi2],
1148 rgcLegal[pi3], rgprgsqPiece[pi3],
1149 &rgcTriplePawnPresent[pi1][pi2][pi3]);
1150 }
1151 else
1152 {
1153 rgprgulTriplePawnless[pi1][pi2][pi3] = (ULONG *) PvMalloc (462*sizeof (ULONG));
1154 VInitTriple (rgprgulTriplePawnless[pi1][pi2][pi3], rgsTriKings,
1155 rgcLegal[pi1], rgprgsqPiece[pi1],
1156 rgcLegal[pi2], rgprgsqPiece[pi2],
1157 rgcLegal[pi3], rgprgsqPiece[pi3],
1158 &rgcTriplePawnless[pi1][pi2][pi3]);
1159 }
1160 }
1161 #endif
1162 }
1163 }
1164
1165 // All done!
1166 if (fPrint)
1167 {
1168 for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
1169 printf ("%c - %ld enumerated positions\n", "pPNBRQ"[pi1], rgcSinglePawnPresent[pi1]);
1170 for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
1171 {
1172 if (0 != rgcSinglePawnless[pi1])
1173 printf ("pawnless %c - %ld enumerated positions\n", "pPNBRQ"[pi1], rgcSinglePawnless[pi1]);
1174 }
1175 for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
1176 for (pi2 = x_pieceNone; pi2 <= pi1; pi2 = (piece) (pi2 + 1))
1177 {
1178 if (0 != rgcPairPawnPresent[pi1][pi2])
1179 printf ("%c%c - %ld enumerated positions\n", "pPNBRQ"[pi1], "pPNBRQ"[pi2],
1180 rgcPairPawnPresent[pi1][pi2]);
1181 }
1182 for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
1183 for (pi2 = x_pieceNone; pi2 <= pi1; pi2 = (piece) (pi2 + 1))
1184 {
1185 if (0 != rgcPairPawnless[pi1][pi2])
1186 printf ("pawnless %c%c - %ld enumerated positions\n", "pPNBRQ"[pi1], "pPNBRQ"[pi2],
1187 rgcPairPawnless[pi1][pi2]);
1188 }
1189 #if defined (T41_INCLUDE)
1190 for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
1191 for (pi2 = x_pieceNone; pi2 <= pi1; pi2 = (piece) (pi2 + 1))
1192 for (pi3 = x_pieceNone; pi3 <= pi2; pi3 = (piece) (pi3 + 1))
1193 {
1194 if (0 != rgcTriplePawnPresent[pi1][pi2][pi3])
1195 printf ("%c%c%c - %ld enumerated positions\n",
1196 "pPNBRQ"[pi1], "pPNBRQ"[pi2], "pPNBRQ"[pi3],
1197 rgcTriplePawnPresent[pi1][pi2][pi3]);
1198 }
1199 for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
1200 for (pi2 = x_pieceNone; pi2 <= pi1; pi2 = (piece) (pi2 + 1))
1201 for (pi3 = x_pieceNone; pi3 <= pi2; pi3 = (piece) (pi3 + 1))
1202 {
1203 if (0 != rgcTriplePawnless[pi1][pi2][pi3])
1204 printf ("pawnless %c%c%c - %ld enumerated positions\n",
1205 "pPNBRQ"[pi1], "pPNBRQ"[pi2], "pPNBRQ"[pi3],
1206 rgcTriplePawnless[pi1][pi2][pi3]);
1207 }
1208 #endif
1209 printf ("\nAllocated %luk\n\n", (cbAllocated + 1023)/1024);
1210 }
1211 }
1212
1213 // Return enumeration of 2 kings and single piece
1214
1215 template <int piw1, bool fPawns, bool fInvert> class TEnumerate1
1216 {
1217 public:
Index(square sqwk,square sqw1,square sqbk)1218 static INLINE INDEX TB_FASTCALL Index
1219 (
1220 square sqwk,
1221 square sqw1,
1222 square sqbk
1223 )
1224 {
1225 INDEX ind;
1226 ULONG ulKings;
1227
1228 // For black pawn invert the board
1229 if (piw1 <= x_piecePawn && fInvert)
1230 {
1231 sqwk = reflect_x(sqwk);
1232 sqw1 = reflect_x(sqw1);
1233 sqbk = reflect_x(sqbk);
1234 }
1235
1236 // Get enumerated square
1237 ind = rgprgsqPiece[piw1][sqbk*64+sqw1];
1238 #if defined (ILLEGAL_POSSIBLE)
1239 if ((BYTE) -1 == ind)
1240 return INF_SINGLE;
1241 #endif
1242 // Get enumerated position of both kings
1243 if (fPawns)
1244 ulKings = rgsHalfKings[sqwk*64+sqbk]; // 0..1805
1245 else
1246 ulKings = rgsTriKings[sqwk*64+sqbk]; // 0..461
1247 #if defined (ILLEGAL_POSSIBLE)
1248 if (INF == ulKings)
1249 return INF_SINGLE;
1250 #endif
1251 // Can we remove one extra square?
1252 if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
1253 ind -= (sqw1 > sqwk);
1254 // Add enumerated square to the # of the preceding positions
1255 return ind + (fPawns ? rgprgulSinglePawnPresent[piw1][ulKings] : rgprgulSinglePawnless[piw1][ulKings]);
1256 }
1257 };
1258
1259 // Return enumeration of 2 kings and 2 pieces
1260
1261 template <int piw1, int piw2, bool fPawns, bool fInvert> class TEnumerate2
1262 {
1263 public:
Index(square sqwk,square sqw1,square sqw2,square sqbk)1264 static INLINE INDEX TB_FASTCALL Index
1265 (
1266 square sqwk,
1267 square sqw1,
1268 square sqw2,
1269 square sqbk
1270 )
1271 {
1272 INDEX ind1, ind2, cInd2;
1273 ULONG ulKings;
1274
1275 // For black pawn invert the board
1276 if (piw2 <= x_piecePawn && fInvert)
1277 {
1278 sqwk = reflect_x(sqwk);
1279 sqw1 = reflect_x(sqw1);
1280 sqw2 = reflect_x(sqw2);
1281 sqbk = reflect_x(sqbk);
1282 }
1283
1284 // Get enumerated squares for both pieces
1285 if (piw1 == piw2)
1286 SORT (sqw1, sqw2);
1287 ind1 = rgprgsqPiece[piw1][sqbk*64+sqw1];
1288 ind2 = rgprgsqPiece[piw2][sqbk*64+sqw2];
1289 #if defined (ILLEGAL_POSSIBLE)
1290 if ((BYTE) -1 == ind1 || (BYTE) -1 == ind2)
1291 return INF_PAIR;
1292 #endif
1293 // Get enumerated position of both kings
1294 if (fPawns)
1295 ulKings = rgsHalfKings[sqwk*64+sqbk]; // 0..1805
1296 else
1297 ulKings = rgsTriKings[sqwk*64+sqbk]; // 0..461
1298 #if defined (ILLEGAL_POSSIBLE)
1299 if (INF == ulKings)
1300 return INF_PAIR;
1301 #endif
1302 if (piw1 == piw2)
1303 {
1304 // Can we remove one extra square?
1305 if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
1306 {
1307 ind1 -= (sqw1 > sqwk);
1308 ind2 -= (sqw2 > sqwk);
1309 }
1310 // Add enumerated squares to the # of the preceding positions
1311 return ind2*(ind2-1)/2 + ind1 +
1312 (fPawns ? rgprgulPairPawnPresent[piw1][piw2][ulKings] : rgprgulPairPawnless[piw1][piw2][ulKings]);
1313 }
1314 else
1315 {
1316 // Can we remove WK square from 1st piece enumeration?
1317 if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
1318 ind1 -= (sqw1 > sqwk);
1319 // Get # of enumerated positions of 2nd piece
1320 cInd2 = rgcLegal[piw2][sqbk];
1321 // Can we remove WK square from 2nd piece enumeration?
1322 if ((piw2>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw2][sqbk*64+sqwk]))
1323 {
1324 cInd2 --;
1325 ind2 -= (sqw2 > sqwk);
1326 }
1327 // Add enumerated square to the # of the preceding positions
1328 return cInd2*ind1 + ind2 + (fPawns ? rgprgulPairPawnPresent[piw1][piw2][ulKings] : rgprgulPairPawnless[piw1][piw2][ulKings]);
1329 }
1330 }
1331 };
1332
1333 #if defined (T41_INCLUDE)
1334
1335 // Return enumeration of 2 kings and 3 pieces
1336
1337 template <int piw1, int piw2, int piw3, bool fPawns, bool fInvert> class TEnumerate3
1338 {
1339 public:
Index(square sqwk,square sqw1,square sqw2,square sqw3,square sqbk)1340 static INLINE INDEX TB_FASTCALL Index
1341 (
1342 square sqwk,
1343 square sqw1,
1344 square sqw2,
1345 square sqw3,
1346 square sqbk
1347 )
1348 {
1349 INDEX ind1, ind2, ind3, cInd1, cInd2, cInd3;
1350 ULONG ulKings;
1351
1352 // For black pawn invert the board
1353 if (piw3 <= x_piecePawn && fInvert)
1354 {
1355 sqwk = reflect_x(sqwk);
1356 sqw1 = reflect_x(sqw1);
1357 sqw2 = reflect_x(sqw2);
1358 sqw3 = reflect_x(sqw3);
1359 sqbk = reflect_x(sqbk);
1360 }
1361
1362 // Get enumerated squares for all pieces
1363 if (piw1 == piw2 && piw1 == piw3)
1364 {
1365 SORT (sqw1, sqw2);
1366 SORT (sqw2, sqw3);
1367 SORT (sqw1, sqw2);
1368 }
1369 else if (piw1 == piw2)
1370 {
1371 SORT (sqw1, sqw2);
1372 }
1373 else if (piw2 == piw3)
1374 {
1375 SORT (sqw2, sqw3);
1376 }
1377 ind1 = rgprgsqPiece[piw1][sqbk*64+sqw1];
1378 ind2 = rgprgsqPiece[piw2][sqbk*64+sqw2];
1379 ind3 = rgprgsqPiece[piw3][sqbk*64+sqw3];
1380 #if defined (ILLEGAL_POSSIBLE)
1381 if ((BYTE) -1 == ind1 || (BYTE) -1 == ind2 || (BYTE) -1 == ind3)
1382 return INF_TRIPLE;
1383 #endif
1384 // Get enumerated position of both kings
1385 if (fPawns)
1386 ulKings = rgsHalfKings[sqwk*64+sqbk]; // 0..1805
1387 else
1388 ulKings = rgsTriKings[sqwk*64+sqbk]; // 0..461
1389 #if defined (ILLEGAL_POSSIBLE)
1390 if (INF == ulKings)
1391 return INF_TRIPLE;
1392 #endif
1393 if (piw1 == piw2 && piw2 == piw3)
1394 {
1395 // Can we remove one extra square?
1396 if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
1397 {
1398 ind1 -= (sqw1 > sqwk);
1399 ind2 -= (sqw2 > sqwk);
1400 ind3 -= (sqw3 > sqwk);
1401 }
1402 // Add enumerated squares to the # of the preceding positions
1403 return ind3*(ind3-1)*(ind3-2)/6 + ind2*(ind2-1)/2 + ind1 +
1404 (fPawns ? rgprgulTriplePawnPresent[piw1][piw2][piw3][ulKings] :
1405 rgprgulTriplePawnless[piw1][piw2][piw3][ulKings]);
1406 }
1407 else if (piw1 == piw2)
1408 {
1409 // Can we remove one extra square?
1410 if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
1411 {
1412 ind1 -= (sqw1 > sqwk);
1413 ind2 -= (sqw2 > sqwk);
1414 }
1415 // Get # of enumerated positions of 3rd piece
1416 cInd3 = rgcLegal[piw3][sqbk];
1417 // Can we remove WK square from 3rd piece enumeration?
1418 if ((piw3>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw3][sqbk*64+sqwk]))
1419 {
1420 cInd3 --;
1421 ind3 -= (sqw3 > sqwk);
1422 }
1423 // Add enumerated squares to the # of the preceding positions
1424 return (ind2*(ind2-1)/2 + ind1)*cInd3 + ind3 +
1425 (fPawns ? rgprgulTriplePawnPresent[piw1][piw2][piw3][ulKings] :
1426 rgprgulTriplePawnless[piw1][piw2][piw3][ulKings]);
1427 }
1428 else if (piw2 == piw3)
1429 {
1430 // Can we remove one extra square?
1431 if ((piw2>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw2][sqbk*64+sqwk]))
1432 {
1433 ind2 -= (sqw2 > sqwk);
1434 ind3 -= (sqw3 > sqwk);
1435 }
1436 // Get # of enumerated positions of 1st piece
1437 cInd1 = rgcLegal[piw1][sqbk];
1438 // Can we remove WK square from 3rd piece enumeration?
1439 if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
1440 {
1441 cInd1 --;
1442 ind1 -= (sqw1 > sqwk);
1443 }
1444 // Add enumerated squares to the # of the preceding positions
1445 return (ind3*(ind3-1)/2 + ind2)*cInd1 + ind1 +
1446 (fPawns ? rgprgulTriplePawnPresent[piw1][piw2][piw3][ulKings] :
1447 rgprgulTriplePawnless[piw1][piw2][piw3][ulKings]);
1448 }
1449 else
1450 {
1451 // Can we remove WK square from 1st piece enumeration?
1452 if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
1453 ind1 -= (sqw1 > sqwk);
1454 // Get # of enumerated positions of 2nd piece
1455 cInd2 = rgcLegal[piw2][sqbk];
1456 // Can we remove WK square from 2nd piece enumeration?
1457 if ((piw2>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw2][sqbk*64+sqwk]))
1458 {
1459 cInd2 --;
1460 ind2 -= (sqw2 > sqwk);
1461 }
1462 // Get # of enumerated positions of 3rd piece
1463 cInd3 = rgcLegal[piw3][sqbk];
1464 // Can we remove WK square from 3rd piece enumeration?
1465 if ((piw3>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw3][sqbk*64+sqwk]))
1466 {
1467 cInd3 --;
1468 ind3 -= (sqw3 > sqwk);
1469 }
1470 // Add enumerated square to the # of the preceding positions
1471 return cInd3*(cInd2*ind1 + ind2) + ind3 +
1472 (fPawns ? rgprgulTriplePawnPresent[piw1][piw2][piw3][ulKings] :
1473 rgprgulTriplePawnless[piw1][piw2][piw3][ulKings]);
1474 }
1475 }
1476 };
1477
1478 #endif
1479
1480 // Enumerate en passant captures
1481
IndEnPassant11W(square sqw,square sqb,square sqEnP)1482 static INLINE INDEX TB_FASTCALL IndEnPassant11W
1483 (
1484 square sqw,
1485 square sqb,
1486 square sqEnP
1487 )
1488 {
1489 assert (sqb+8 == sqEnP);
1490 if (sqw+7 == sqEnP)
1491 // Capture to the left
1492 return (sqw&7)-1;
1493 else
1494 {
1495 // Capture to the right
1496 assert (sqw+9 == sqEnP);
1497 return (sqw&7)+7;
1498 }
1499 }
1500
IndEnPassant11B(square sqw,square sqb,square sqEnP)1501 static INLINE INDEX TB_FASTCALL IndEnPassant11B
1502 (
1503 square sqw,
1504 square sqb,
1505 square sqEnP
1506 )
1507 {
1508 assert (sqw-8 == sqEnP);
1509 if (sqb-9 == sqEnP)
1510 // Capture to the left
1511 return (sqb&7)-1;
1512 else
1513 {
1514 // Capture to the right
1515 assert (sqb-7 == sqEnP);
1516 return (sqb&7)+7;
1517 }
1518 }
1519
IndEnPassant21W(square sqw1,square sqw2,square sqb,square sqEnP)1520 static INLINE INDEX TB_FASTCALL IndEnPassant21W
1521 (
1522 square sqw1,
1523 square sqw2,
1524 square sqb,
1525 square sqEnP
1526 )
1527 {
1528 assert (sqb+8 == sqEnP);
1529 SORT (sqw1, sqw2);
1530 if (sqw1+7 == sqEnP && 0 != TbColumn(sqw1))
1531 // Capture to the left
1532 return (sqw1&7)-1+(EXCLUDE3(sqw2,sqb,sqEnP,sqEnP+8)-i8-1)*i14;
1533 else if (sqw1+9 == sqEnP && 7 != TbColumn(sqw1))
1534 // Capture to the right
1535 return (sqw1&7)+7+(EXCLUDE3(sqw2,sqb,sqEnP,sqEnP+8)-i8-1)*i14;
1536 else if (sqw2+7 == sqEnP && 0 != TbColumn(sqw2))
1537 // Capture to the left
1538 return (sqw2&7)-1+(EXCLUDE3(sqw1,sqb,sqEnP,sqEnP+8)-i8)*i14;
1539 else
1540 {
1541 // Capture to the right
1542 assert (sqw2+9 == sqEnP && 7 != TbColumn(sqw2));
1543 return (sqw2&7)+7+(EXCLUDE3(sqw1,sqb,sqEnP,sqEnP+8)-i8)*i14;
1544 }
1545 }
1546
IndEnPassant21B(square sqw1,square sqw2,square sqb,square sqEnP)1547 static INLINE INDEX TB_FASTCALL IndEnPassant21B
1548 (
1549 square sqw1,
1550 square sqw2,
1551 square sqb,
1552 square sqEnP
1553 )
1554 {
1555 assert (sqw1 < sqw2); // Must be already sorted
1556 if (sqb-9 == sqEnP && 0 != TbColumn(sqb))
1557 // Capture to the left
1558 if (sqw1-8 == sqEnP)
1559 return (sqb&7)-1+(EXCLUDE3(sqw2,sqb,sqEnP,sqEnP-8)-i8-1)*i14;
1560 else
1561 {
1562 assert (sqw2-8 == sqEnP);
1563 return (sqb&7)-1+(EXCLUDE3(sqw1,sqb,sqEnP,sqEnP-8)-i8)*i14;
1564 }
1565 else
1566 {
1567 // Capture to the right
1568 assert (sqb-7 == sqEnP && 7 != TbColumn(sqb));
1569 if (sqw1-8 == sqEnP)
1570 return (sqb&7)+7+(EXCLUDE3(sqw2,sqb,sqEnP,sqEnP-8)-i8-1)*i14;
1571 else
1572 {
1573 assert (sqw2-8 == sqEnP);
1574 return (sqb&7)+7+(EXCLUDE3(sqw1,sqb,sqEnP,sqEnP-8)-i8)*i14;
1575 }
1576 }
1577 }
1578
1579 // Index calculation functions for different endgame classes
1580
1581 template <int piw1> class T21
1582 {
1583 public:
IndCalcW(square * psqW,square * psqB,square sqEnP,int fInvert)1584 static INDEX TB_FASTCALL IndCalcW
1585 (
1586 square *psqW,
1587 square *psqB,
1588 square sqEnP,
1589 int fInvert
1590 )
1591 {
1592 square sqwk, sqw1, sqbk, sqMask;
1593
1594 sqwk = SqFindKing (psqW);
1595 sqw1 = SqFindOne (psqW, piw1);
1596 sqbk = SqFindKing (psqB);
1597
1598 if (x_piecePawn == piw1)
1599 sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
1600 else
1601 sqMask = rgsqReflectMaskYandX [sqwk];
1602 sqwk ^= sqMask;
1603 sqbk ^= sqMask;
1604 sqw1 ^= sqMask;
1605
1606 if (x_piecePawn != piw1)
1607 {
1608 // No pawn
1609 if (! FInTriangle (sqwk, sqbk))
1610 {
1611 sqwk = reflect_xy(sqwk);
1612 sqbk = reflect_xy(sqbk);
1613 sqw1 = reflect_xy(sqw1);
1614 };
1615 }
1616 return TEnumerate1<piw1,x_piecePawn==piw1 ? true : false,false>::Index(sqwk,sqw1,sqbk);
1617 }
1618
IndCalcB(square * psqW,square * psqB,square sqEnP,int fInvert)1619 static INDEX TB_FASTCALL IndCalcB
1620 (
1621 square *psqW,
1622 square *psqB,
1623 square sqEnP,
1624 int fInvert
1625 )
1626 {
1627 square sqwk, sqw1, sqbk, sqMask;
1628
1629 sqwk = SqFindKing (psqW);
1630 sqw1 = SqFindOne (psqW, piw1);
1631 sqbk = SqFindKing (psqB);
1632
1633 if (x_piecePawn == piw1)
1634 sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
1635 else
1636 sqMask = rgsqReflectMaskYandX [sqbk];
1637 sqwk ^= sqMask;
1638 sqbk ^= sqMask;
1639 sqw1 ^= sqMask;
1640
1641 if (x_piecePawn == piw1)
1642 return TEnumerate1<x_pieceNone,true,true>::Index(sqbk,sqw1,sqwk);
1643 else
1644 {
1645 // No pawn
1646 if (! FInTriangle (sqbk, sqwk))
1647 {
1648 sqwk = reflect_xy(sqwk);
1649 sqbk = reflect_xy(sqbk);
1650 sqw1 = reflect_xy(sqw1);
1651 };
1652 return IndTriKings(sqbk,sqwk)*i62 + EXCLUDE2(sqw1,sqwk,sqbk);
1653 }
1654 }
1655 };
1656
1657 template <int piw1, int pib1> class T22
1658 {
1659 public:
IndCalcW(square * psqW,square * psqB,square sqEnP,int fInvert)1660 static INDEX TB_FASTCALL IndCalcW
1661 (
1662 square *psqW,
1663 square *psqB,
1664 square sqEnP,
1665 int fInvert
1666 )
1667 {
1668 square sqwk, sqw1, sqbk, sqb1, sqMask;
1669
1670 sqwk = SqFindKing (psqW);
1671 sqw1 = SqFindOne (psqW, piw1);
1672 sqbk = SqFindKing (psqB);
1673 sqb1 = SqFindOne (psqB, pib1);
1674
1675 if (x_piecePawn == pib1)
1676 sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
1677 else
1678 sqMask = rgsqReflectMaskYandX [sqwk];
1679 sqwk ^= sqMask;
1680 sqbk ^= sqMask;
1681 sqw1 ^= sqMask;
1682 sqb1 ^= sqMask;
1683
1684 if (x_piecePawn == pib1)
1685 {
1686 // There are pawns on the board
1687 if (x_piecePawn == piw1)
1688 {
1689 // One white and one black pawn
1690 if (XX == sqEnP)
1691 return TEnumerate1<x_piecePawn,true,false>::Index(sqwk,sqw1,sqbk)*i47 +
1692 EXCLUDE1(sqb1,sqw1)-i8; // 47
1693 else
1694 return rgcSinglePawnPresent[x_piecePawn]*i47 +
1695 IndHalfKings(sqwk,sqbk)*i14 +
1696 IndEnPassant11W (sqw1, sqb1, sqEnP ^ sqMask);
1697 }
1698 else
1699 // Only black pawn
1700 return TEnumerate1<piw1,true,false>::Index(sqwk,sqw1,sqbk)*i48 + sqb1-i8;
1701 }
1702 else
1703 {
1704 // No pawns at all
1705 if (!FInTriangle (sqwk, sqbk))
1706 {
1707 sqwk = reflect_xy(sqwk);
1708 sqbk = reflect_xy(sqbk);
1709 sqw1 = reflect_xy(sqw1);
1710 sqb1 = reflect_xy(sqb1);
1711 };
1712 return TEnumerate1<piw1,false,false>::Index(sqwk,sqw1,sqbk)*i61 +
1713 EXCLUDE3(sqb1,sqwk,sqbk,sqw1); // 61
1714 }
1715 }
1716
IndCalcB(square * psqW,square * psqB,square sqEnP,int fInvert)1717 static INDEX TB_FASTCALL IndCalcB
1718 (
1719 square *psqW,
1720 square *psqB,
1721 square sqEnP,
1722 int fInvert
1723 )
1724 {
1725 square sqwk, sqw1, sqbk, sqb1, sqMask;
1726
1727 sqwk = SqFindKing (psqW);
1728 sqw1 = SqFindOne (psqW, piw1);
1729 sqbk = SqFindKing (psqB);
1730 sqb1 = SqFindOne (psqB, pib1);
1731
1732 if (x_piecePawn == pib1)
1733 sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
1734 else
1735 sqMask = rgsqReflectMaskYandX [sqbk];
1736 sqwk ^= sqMask;
1737 sqbk ^= sqMask;
1738 sqw1 ^= sqMask;
1739 sqb1 ^= sqMask;
1740
1741 if (x_piecePawn == pib1)
1742 {
1743 // There are pawns on the board
1744 if (x_piecePawn == piw1)
1745 {
1746 // One white and one black pawn
1747 if (XX == sqEnP)
1748 return TEnumerate1<x_piecePawn,true,true>::Index(sqbk,sqb1,sqwk)*i47 +
1749 EXCLUDE1(sqw1,sqb1)-i8; // 47
1750 else
1751 return rgcSinglePawnPresent[x_piecePawn]*i47 +
1752 IndHalfKings(sqbk,sqwk)*i14 +
1753 IndEnPassant11B (sqw1, sqb1, sqEnP ^ sqMask);
1754 }
1755 }
1756 else
1757 {
1758 // No pawns at all
1759 if (!FInTriangle (sqbk, sqwk))
1760 {
1761 sqwk = reflect_xy(sqwk);
1762 sqbk = reflect_xy(sqbk);
1763 sqw1 = reflect_xy(sqw1);
1764 sqb1 = reflect_xy(sqb1);
1765 };
1766 }
1767 return (x_piecePawn == pib1 ? TEnumerate1<pib1,true,true>::Index(sqbk,sqb1,sqwk) :
1768 TEnumerate1<pib1,false,false>::Index(sqbk,sqb1,sqwk))*i61 +
1769 EXCLUDE3(sqw1,sqwk,sqbk,sqb1); // 61
1770 }
1771 };
1772
1773 template <int piw1, int piw2> class T31
1774 {
1775 public:
IndCalcW(square * psqW,square * psqB,square sqEnP,int fInvert)1776 static INDEX TB_FASTCALL IndCalcW
1777 (
1778 square *psqW,
1779 square *psqB,
1780 square sqEnP,
1781 int fInvert
1782 )
1783 {
1784 square sqwk, sqw1, sqw2, sqbk, sqMask;
1785
1786 sqwk = SqFindKing (psqW);
1787 if (piw1 == piw2)
1788 {
1789 sqw1 = SqFindFirst (psqW, piw1);
1790 sqw2 = SqFindSecond (psqW, piw2);
1791 }
1792 else
1793 {
1794 SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
1795 }
1796 sqbk = SqFindKing (psqB);
1797
1798 if (x_piecePawn == piw2)
1799 sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
1800 else
1801 sqMask = rgsqReflectMaskYandX [sqwk];
1802 sqwk ^= sqMask;
1803 sqbk ^= sqMask;
1804 sqw1 ^= sqMask;
1805 sqw2 ^= sqMask;
1806
1807 if (x_piecePawn != piw2)
1808 {
1809 // There are no pawns on the board
1810 if (!FInTriangle (sqwk, sqbk))
1811 {
1812 sqwk = reflect_xy(sqwk);
1813 sqw1 = reflect_xy(sqw1);
1814 sqw2 = reflect_xy(sqw2);
1815 sqbk = reflect_xy(sqbk);
1816 };
1817 }
1818 return TEnumerate2<piw1, piw2, x_piecePawn==piw2 ? true : false, false>::Index(sqwk, sqw1, sqw2, sqbk);
1819 }
1820
IndCalcB(square * psqW,square * psqB,square sqEnP,int fInvert)1821 static INDEX TB_FASTCALL IndCalcB
1822 (
1823 square *psqW,
1824 square *psqB,
1825 square sqEnP,
1826 int fInvert
1827 )
1828 {
1829 square sqwk, sqw1, sqw2, sqbk, sqMask;
1830
1831 sqwk = SqFindKing (psqW);
1832 if (piw1 == piw2)
1833 {
1834 sqw1 = SqFindFirst (psqW, piw1);
1835 sqw2 = SqFindSecond (psqW, piw2);
1836 }
1837 else
1838 {
1839 SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
1840 }
1841 sqbk = SqFindKing (psqB);
1842
1843 if (x_piecePawn == piw2)
1844 sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
1845 else
1846 sqMask = rgsqReflectMaskYandX [sqbk];
1847 sqwk ^= sqMask;
1848 sqbk ^= sqMask;
1849 sqw1 ^= sqMask;
1850 sqw2 ^= sqMask;
1851
1852 if (x_piecePawn == piw2)
1853 {
1854 // There are pawns on the board
1855 if (x_piecePawn == piw1)
1856 // Two white pawns
1857 return TEnumerate2<x_pieceNone,x_pieceNone,true,true>::Index(sqbk,sqw1,sqw2,sqwk);
1858 else
1859 // Only one white pawn
1860 return TEnumerate1<x_pieceNone,true,true>::Index(sqbk,sqw2,sqwk)*i61 +
1861 EXCLUDE3(sqw1,sqwk,sqbk,sqw2); // 61
1862 }
1863 else
1864 {
1865 // No pawns
1866 if (!FInTriangle (sqbk, sqwk))
1867 {
1868 sqwk = reflect_xy(sqwk);
1869 sqw1 = reflect_xy(sqw1);
1870 sqw2 = reflect_xy(sqw2);
1871 sqbk = reflect_xy(sqbk);
1872 };
1873 if (piw1 == piw2)
1874 {
1875 SORT (sqw1, sqw2);
1876 sqw2 = EXCLUDE2(sqw2,sqwk,sqbk); // 62
1877 return IndTriKings(sqbk,sqwk)*(i62*i61/2) +
1878 sqw2*(sqw2-1)/2+EXCLUDE2(sqw1,sqwk,sqbk); // 62*61/2
1879 }
1880 else
1881 return IndTriKings(sqbk,sqwk)*(i62*i61) +
1882 EXCLUDE2(sqw1,sqwk,sqbk)*i61 + // 62
1883 EXCLUDE3(sqw2,sqwk,sqbk,sqw1); // 61
1884 }
1885 }
1886 };
1887
1888 template <int piw1, int piw2, int pib1> class T32
1889 {
1890 public:
IndCalcW(square * psqW,square * psqB,square sqEnP,int fInvert)1891 static INDEX TB_FASTCALL IndCalcW
1892 (
1893 square *psqW,
1894 square *psqB,
1895 square sqEnP,
1896 int fInvert
1897 )
1898 {
1899 square sqwk, sqw1, sqw2, sqbk, sqb1, sqMask;
1900
1901 sqwk = SqFindKing (psqW);
1902 if (piw1 == piw2)
1903 {
1904 sqw1 = SqFindFirst (psqW, piw1);
1905 sqw2 = SqFindSecond (psqW, piw2);
1906 }
1907 else
1908 {
1909 SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
1910 }
1911 sqbk = SqFindKing (psqB);
1912 sqb1 = SqFindOne (psqB, pib1);
1913
1914 if (x_piecePawn == piw2 || x_piecePawn == pib1)
1915 sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
1916 else
1917 sqMask = rgsqReflectMaskYandX [sqwk];
1918 sqwk ^= sqMask;
1919 sqbk ^= sqMask;
1920 sqw1 ^= sqMask;
1921 sqw2 ^= sqMask;
1922 sqb1 ^= sqMask;
1923
1924 if (x_piecePawn == piw2 || x_piecePawn == pib1)
1925 {
1926 // There are pawns on the board
1927 if (x_piecePawn == pib1)
1928 {
1929 // Black pawn
1930 if (x_piecePawn == piw1 && x_piecePawn == piw2)
1931 {
1932 // All 3 pieces are pawns
1933 if (XX == sqEnP)
1934 return TEnumerate2<x_piecePawn,x_piecePawn,true,false>::
1935 Index(sqwk,sqw1,sqw2,sqbk)*i46+
1936 EXCLUDE2(sqb1,sqw1,sqw2)-i8; // 46
1937 else
1938 // En passant capture
1939 return rgcPairPawnPresent[x_piecePawn][x_piecePawn]*i46 +
1940 IndHalfKings(sqwk,sqbk)*(i14*i44) +
1941 IndEnPassant21W (sqw1, sqw2, sqb1, sqEnP ^ sqMask);
1942 }
1943 else if (x_piecePawn == piw2)
1944 {
1945 // One white pawn, one black pawn
1946 if (XX == sqEnP)
1947 return TEnumerate2<piw1,x_piecePawn,true,false>::
1948 Index(sqwk,sqw1,sqw2,sqbk)*i47 +
1949 EXCLUDE1(sqb1,sqw2)-i8; // 47
1950 else
1951 // En passant capture
1952 return rgcPairPawnPresent[piw1][x_piecePawn]*i47 +
1953 TEnumerate1<piw1,true,false>::Index(sqwk,sqw1,sqbk)*i14 +
1954 IndEnPassant11W (sqw2, sqb1, sqEnP ^ sqMask);
1955 }
1956 else
1957 // Only black pawn
1958 return TEnumerate2<piw1,piw2,true,false>::
1959 Index(sqwk,sqw1,sqw2,sqbk)*i48 +
1960 sqb1-i8; // 48
1961 }
1962 }
1963 else
1964 {
1965 // No pawns
1966 if (!FInTriangle (sqwk, sqbk))
1967 {
1968 sqwk = reflect_xy(sqwk);
1969 sqw1 = reflect_xy(sqw1);
1970 sqw2 = reflect_xy(sqw2);
1971 sqbk = reflect_xy(sqbk);
1972 sqb1 = reflect_xy(sqb1);
1973 };
1974 }
1975 return TEnumerate2<piw1,piw2,(x_piecePawn==piw2||x_piecePawn==pib1) ? true : false,false>::
1976 Index(sqwk,sqw1,sqw2,sqbk)*i60 +
1977 EXCLUDE4(sqb1,sqwk,sqbk,sqw1,sqw2); // 60
1978 }
1979
IndCalcB(square * psqW,square * psqB,square sqEnP,int fInvert)1980 static INDEX TB_FASTCALL IndCalcB
1981 (
1982 square *psqW,
1983 square *psqB,
1984 square sqEnP,
1985 int fInvert
1986 )
1987 {
1988 square sqwk, sqw1, sqw2, sqbk, sqb1, sqMask;
1989
1990 sqwk = SqFindKing (psqW);
1991 if (piw1 == piw2)
1992 {
1993 sqw1 = SqFindFirst (psqW, piw1);
1994 sqw2 = SqFindSecond (psqW, piw2);
1995 }
1996 else
1997 {
1998 SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
1999 }
2000 sqbk = SqFindKing (psqB);
2001 sqb1 = SqFindOne (psqB, pib1);
2002
2003 if (x_piecePawn == piw2 || x_piecePawn == pib1)
2004 sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
2005 else
2006 sqMask = rgsqReflectMaskYandX [sqbk];
2007 sqwk ^= sqMask;
2008 sqbk ^= sqMask;
2009 sqw1 ^= sqMask;
2010 sqw2 ^= sqMask;
2011 sqb1 ^= sqMask;
2012
2013 if (x_piecePawn == piw2 || x_piecePawn == pib1)
2014 {
2015 // There are pawns on the board
2016 if (x_piecePawn == pib1)
2017 {
2018 // Black pawn
2019 if (x_piecePawn == piw1 && x_piecePawn == piw2)
2020 {
2021 // All 3 pieces are pawns
2022 SORT (sqw1, sqw2);
2023 if (XX == sqEnP)
2024 {
2025 sqw2 = EXCLUDE1(sqw2,sqb1)-i8; // 47
2026 return TEnumerate1<x_piecePawn,true,true>::
2027 Index(sqbk,sqb1,sqwk)*(i47*i46/2) +
2028 sqw2*(sqw2-1)/2+EXCLUDE1(sqw1,sqb1)-i8; // 47*46/2
2029 }
2030 else
2031 // En passant capture
2032 return rgcSinglePawnPresent[x_piecePawn]*(i47*i46/2) +
2033 IndHalfKings(sqbk,sqwk)*(i44*i14) +
2034 IndEnPassant21B (sqw1, sqw2, sqb1, sqEnP ^ sqMask);
2035 }
2036 else if (x_piecePawn == piw2)
2037 {
2038 // One white pawn, one black pawn
2039 if (XX == sqEnP)
2040 return TEnumerate1<x_piecePawn,true,true>::
2041 Index(sqbk,sqb1,sqwk)*(i60*i47) +
2042 EXCLUDE4(sqw1,sqwk,sqbk,sqw2,sqb1)*i47 + // 60
2043 EXCLUDE1(sqw2,sqb1)-i8; // 47
2044 else
2045 {
2046 // En passant capture
2047 sqEnP ^= sqMask;
2048 return rgcSinglePawnPresent[x_piecePawn]*(i60*i47) +
2049 IndHalfKings(sqbk,sqwk)*(i58*i14) +
2050 EXCLUDE6(sqw1,sqwk,sqbk,sqw2,sqb1,sqEnP,sqEnP-8)*i14 + // 58
2051 IndEnPassant11B (sqw2, sqb1, sqEnP);
2052 }
2053 }
2054 else
2055 {
2056 // Only black pawn
2057 if (piw1 == piw2)
2058 {
2059 // 2 identical white pieces
2060 SORT (sqw1, sqw2);
2061 sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1); // 61
2062 return TEnumerate1<x_piecePawn,true,true>::
2063 Index(sqbk,sqb1,sqwk)*(i61*i60/2) +
2064 sqw2*(sqw2-1)/2 + EXCLUDE3(sqw1,sqwk,sqbk,sqb1); // 61*60/2
2065 }
2066 return TEnumerate1<x_piecePawn,true,true>::
2067 Index(sqbk,sqb1,sqwk)*(i61*i60) +
2068 EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*i60 + // 61
2069 EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1); // 60
2070 }
2071 }
2072 else
2073 {
2074 // No black pawn
2075 if (x_piecePawn == piw1)
2076 {
2077 // Only 2 white pawns
2078 SORT (sqw1, sqw2);
2079 sqw2 -= i8;
2080 return TEnumerate1<pib1,true,true>::
2081 Index(sqbk,sqb1,sqwk)*(i48*47/2) +
2082 sqw2*(sqw2-1)/2+sqw1-i8; // 48*47/2
2083 }
2084 else
2085 // Only one white pawn
2086 return TEnumerate1<pib1,true,true>::
2087 Index(sqbk,sqb1,sqwk)*(i60*i48) +
2088 EXCLUDE4(sqw1,sqwk,sqbk,sqw2,sqb1)*i48 + // 60
2089 sqw2-i8; // 48
2090 }
2091 }
2092 else
2093 {
2094 // No pawns
2095 if (!FInTriangle (sqbk, sqwk))
2096 {
2097 sqwk = reflect_xy(sqwk);
2098 sqw1 = reflect_xy(sqw1);
2099 sqw2 = reflect_xy(sqw2);
2100 sqbk = reflect_xy(sqbk);
2101 sqb1 = reflect_xy(sqb1);
2102 };
2103 if (piw1 == piw2)
2104 {
2105 // 2 identical white pieces
2106 SORT (sqw1, sqw2);
2107 sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1); // 61
2108 return TEnumerate1<pib1,false,false>::
2109 Index(sqbk,sqb1,sqwk)*(i61*i60/2) +
2110 sqw2*(sqw2-1)/2+EXCLUDE3(sqw1,sqwk,sqbk,sqb1); // 61*60/2
2111 }
2112 else
2113 return TEnumerate1<pib1,false,false>::
2114 Index(sqbk,sqb1,sqwk)*(i61*i60) +
2115 EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*i60 + // 61
2116 EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1); // 60
2117 }
2118 }
2119 };
2120
2121 #if defined (T41_INCLUDE)
2122
2123 template <int piw1, int piw2, int piw3> class T41
2124 {
2125 public:
IndCalcW(square * psqW,square * psqB,square sqEnP,int fInvert)2126 static INDEX TB_FASTCALL IndCalcW
2127 (
2128 square *psqW,
2129 square *psqB,
2130 square sqEnP,
2131 int fInvert
2132 )
2133 {
2134 square sqwk, sqw1, sqw2, sqw3, sqbk, sqMask;
2135
2136 sqwk = SqFindKing (psqW);
2137 sqw1 = SqFindFirst (psqW, piw1);
2138 if (piw1 == piw2 && piw2 == piw3)
2139 {
2140 sqw2 = SqFindSecond (psqW, piw2);
2141 sqw3 = SqFindThird (psqW, piw3);
2142 }
2143 else if (piw1 == piw2)
2144 {
2145 sqw2 = SqFindSecond (psqW, piw2);
2146 sqw3 = SqFindFirst (psqW, piw3);
2147 }
2148 else if (piw2 == piw3)
2149 {
2150 sqw2 = SqFindFirst (psqW, piw2);
2151 sqw3 = SqFindSecond (psqW, piw3);
2152 }
2153 else
2154 {
2155 sqw2 = SqFindFirst (psqW, piw2);
2156 sqw3 = SqFindFirst (psqW, piw3);
2157 }
2158 sqbk = SqFindKing (psqB);
2159
2160 if (x_piecePawn == piw3)
2161 sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
2162 else
2163 sqMask = rgsqReflectMaskYandX [sqwk];
2164 sqwk ^= sqMask;
2165 sqbk ^= sqMask;
2166 sqw1 ^= sqMask;
2167 sqw2 ^= sqMask;
2168 sqw3 ^= sqMask;
2169
2170 if (x_piecePawn != piw3)
2171 {
2172 // No pawns
2173 if (!FInTriangle (sqwk, sqbk))
2174 {
2175 sqwk = reflect_xy(sqwk);
2176 sqw1 = reflect_xy(sqw1);
2177 sqw2 = reflect_xy(sqw2);
2178 sqw3 = reflect_xy(sqw3);
2179 sqbk = reflect_xy(sqbk);
2180 };
2181 }
2182 return TEnumerate3<piw1,piw2,piw3,x_piecePawn == piw3,false>::Index(sqwk,sqw1,sqw2,sqw3,sqbk);
2183 }
2184
IndCalcB(square * psqW,square * psqB,square sqEnP,int fInvert)2185 static INDEX TB_FASTCALL IndCalcB
2186 (
2187 square *psqW,
2188 square *psqB,
2189 square sqEnP,
2190 int fInvert
2191 )
2192 {
2193 square sqwk, sqw1, sqw2, sqw3, sqbk, sqMask;
2194
2195 sqwk = SqFindKing (psqW);
2196 sqw1 = SqFindFirst (psqW, piw1);
2197 if (piw1 == piw2 && piw2 == piw3)
2198 {
2199 sqw2 = SqFindSecond (psqW, piw2);
2200 sqw3 = SqFindThird (psqW, piw3);
2201 }
2202 else if (piw1 == piw2)
2203 {
2204 sqw2 = SqFindSecond (psqW, piw2);
2205 sqw3 = SqFindFirst (psqW, piw3);
2206 }
2207 else if (piw2 == piw3)
2208 {
2209 sqw2 = SqFindFirst (psqW, piw2);
2210 sqw3 = SqFindSecond (psqW, piw3);
2211 }
2212 else
2213 {
2214 sqw2 = SqFindFirst (psqW, piw2);
2215 sqw3 = SqFindFirst (psqW, piw3);
2216 }
2217 sqbk = SqFindKing (psqB);
2218
2219 if (x_piecePawn == piw3)
2220 sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
2221 else
2222 sqMask = rgsqReflectMaskYandX [sqbk];
2223 sqwk ^= sqMask;
2224 sqbk ^= sqMask;
2225 sqw1 ^= sqMask;
2226 sqw2 ^= sqMask;
2227 sqw3 ^= sqMask;
2228
2229 if (x_piecePawn == piw3)
2230 {
2231 // There are pawns on the board
2232 if (x_piecePawn == piw1)
2233 // 3 white pawns
2234 return TEnumerate3<x_pieceNone,x_pieceNone,x_pieceNone,true,true>::
2235 Index(sqbk,sqw1,sqw2,sqw3,sqwk);
2236 else if (x_piecePawn == piw2)
2237 // 2 white pawns
2238 return TEnumerate2<x_pieceNone,x_pieceNone,true,true>::
2239 Index(sqbk,sqw2,sqw3,sqwk)*i60 +
2240 EXCLUDE4(sqw1,sqwk,sqbk,sqw2,sqw3); // 60
2241 else if (piw1 == piw2)
2242 {
2243 // 1 pawn, 2 pieces equal
2244 SORT (sqw1, sqw2);
2245 sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqw3); // 61
2246 return TEnumerate1<x_pieceNone,true,true>::
2247 Index(sqbk,sqw3,sqwk)*(i61*i60/2) +
2248 sqw2*(sqw2-1)/2+EXCLUDE3(sqw1,sqwk,sqbk,sqw3); // 61*60/2
2249 }
2250 else
2251 // Only one white pawn
2252 return TEnumerate1<x_pieceNone,true,true>::Index(sqbk,sqw3,sqwk)*i61*i60 +
2253 EXCLUDE3(sqw1,sqwk,sqbk,sqw3)*i60 + // 61
2254 EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqw3); // 60
2255 }
2256 else
2257 {
2258 // No pawns
2259 if (!FInTriangle (sqbk, sqwk))
2260 {
2261 sqwk = reflect_xy(sqwk);
2262 sqw1 = reflect_xy(sqw1);
2263 sqw2 = reflect_xy(sqw2);
2264 sqw3 = reflect_xy(sqw3);
2265 sqbk = reflect_xy(sqbk);
2266 };
2267 if (piw1 == piw2 && piw2 == piw3)
2268 {
2269 // All 3 pieces equal
2270 SORT (sqw1, sqw2);
2271 SORT (sqw2, sqw3);
2272 SORT (sqw1, sqw2);
2273 sqw3 = EXCLUDE2(sqw3,sqwk,sqbk); // 62
2274 sqw2 = EXCLUDE2(sqw2,sqwk,sqbk);
2275 return IndTriKings(sqbk,sqwk)*(i62*i61*i60/6) +
2276 sqw3*(sqw3-1)*(sqw3-2)/6+
2277 sqw2*(sqw2-1)/2+
2278 EXCLUDE2(sqw1,sqwk,sqbk); // 62*61*60/6
2279 }
2280 else if (piw1 == piw2)
2281 {
2282 // 2 major pieces equal
2283 SORT (sqw1, sqw2);
2284 sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqw3); // 61
2285 return IndTriKings(sqbk,sqwk)*(i61*i60/2*i62) +
2286 (sqw2*(sqw2-1)/2+EXCLUDE3(sqw1,sqwk,sqbk,sqw3))*i62 + // 61*60/2
2287 EXCLUDE2(sqw3,sqwk,sqbk); // 62
2288 }
2289 else if (piw2 == piw3)
2290 {
2291 // 2 minor pieces equal
2292 SORT (sqw2, sqw3);
2293 sqw3 = EXCLUDE3(sqw3,sqwk,sqbk,sqw1); // 61
2294 return IndTriKings(sqbk,sqwk)*(i62*i61*i60/2) +
2295 EXCLUDE2(sqw1,sqwk,sqbk)*(i61*i60/2) + // 62
2296 sqw3*(sqw3-1)/2+EXCLUDE3(sqw2,sqwk,sqbk,sqw1); // 61*60/2
2297 }
2298 else
2299 return IndTriKings(sqbk,sqwk)*(i62*i61*i60) +
2300 EXCLUDE2(sqw1,sqwk,sqbk)*(i61*i60) + // 62
2301 EXCLUDE3(sqw2,sqwk,sqbk,sqw1)*i60 + // 61
2302 EXCLUDE4(sqw3,sqwk,sqbk,sqw1,sqw2); // 60
2303 }
2304 }
2305 };
2306
2307 #endif // T41
2308
2309 #else // Old SJE schema ------------------------------------------------------
2310
2311 /* scanning pattern: triangle encoding */
2312
2313 static const INDEX sptriv[] =
2314 {
2315 0, 1, 2, 3, -1, -1, -1, -1,
2316 -1, 4, 5, 6, -1, -1, -1, -1,
2317 -1, -1, 7, 8, -1, -1, -1, -1,
2318 -1, -1, -1, 9, -1, -1, -1, -1,
2319 -1, -1, -1, -1, -1, -1, -1, -1,
2320 -1, -1, -1, -1, -1, -1, -1, -1,
2321 -1, -1, -1, -1, -1, -1, -1, -1,
2322 -1, -1, -1, -1, -1, -1, -1, -1,
2323 };
2324
2325 /* scanning pattern: queenside flank encoding */
2326
2327 static const INDEX spqsfv[] =
2328 {
2329 0, 1, 2, 3, -1, -1, -1, -1,
2330 4, 5, 6, 7, -1, -1, -1, -1,
2331 8, 9, 10, 11, -1, -1, -1, -1,
2332 12, 13, 14, 15, -1, -1, -1, -1,
2333 16, 17, 18, 19, -1, -1, -1, -1,
2334 20, 21, 22, 23, -1, -1, -1, -1,
2335 24, 25, 26, 27, -1, -1, -1, -1,
2336 28, 29, 30, 31, -1, -1, -1, -1,
2337 };
2338
2339 /*--> CalcIndex3A: calculate index, mode 3A */
CalcIndex3A(square sq0,square sq1,square sq2)2340 INLINE INDEX CalcIndex3A
2341 (
2342 square sq0,
2343 square sq1,
2344 square sq2
2345 )
2346 {
2347 INDEX index;
2348
2349 if (TbRow(sq2) > x_row_4)
2350 {
2351 sq0 = reflect_x(sq0);
2352 sq1 = reflect_x(sq1);
2353 sq2 = reflect_x(sq2);
2354 };
2355
2356 if (TbColumn(sq2) > x_column_d)
2357 {
2358 sq0 = reflect_y(sq0);
2359 sq1 = reflect_y(sq1);
2360 sq2 = reflect_y(sq2);
2361 };
2362
2363 if (TbRow(sq2) > TbColumn(sq2))
2364 {
2365 sq0 = reflect_xy(sq0);
2366 sq1 = reflect_xy(sq1);
2367 sq2 = reflect_xy(sq2);
2368 };
2369
2370 index =
2371 sq0 +
2372 sq1 * i64 +
2373 sptriv [sq2] * i64 * i64;
2374
2375 return (index);
2376 }
2377
2378 /*--> CalcIndex3B: calculate index, mode 3B */
CalcIndex3B(square sq0,square sq1,square sq2)2379 INLINE INDEX CalcIndex3B
2380 (
2381 square sq0,
2382 square sq1,
2383 square sq2
2384 )
2385 {
2386 INDEX index;
2387
2388 if (TbColumn(sq1) > x_column_d)
2389 {
2390 sq0 = reflect_y(sq0);
2391 sq1 = reflect_y(sq1);
2392 sq2 = reflect_y(sq2);
2393 };
2394
2395 index =
2396 sq0 +
2397 spqsfv [sq1] * i64 +
2398 sq2 * (i64 / 2) * i64;
2399
2400 return (index);
2401 }
2402
2403 /*--> CalcIndex4A: calculate index, mode 4A */
CalcIndex4A(square sq0,square sq1,square sq2,square sq3)2404 INLINE INDEX CalcIndex4A
2405 (
2406 square sq0,
2407 square sq1,
2408 square sq2,
2409 square sq3
2410 )
2411 {
2412 INDEX index;
2413
2414 if (TbRow(sq3) > x_row_4)
2415 {
2416 sq0 = reflect_x(sq0);
2417 sq1 = reflect_x(sq1);
2418 sq2 = reflect_x(sq2);
2419 sq3 = reflect_x(sq3);
2420 };
2421
2422 if (TbColumn(sq3) > x_column_d)
2423 {
2424 sq0 = reflect_y(sq0);
2425 sq1 = reflect_y(sq1);
2426 sq2 = reflect_y(sq2);
2427 sq3 = reflect_y(sq3);
2428 };
2429
2430 if (TbRow(sq3) > TbColumn(sq3))
2431 {
2432 sq0 = reflect_xy(sq0);
2433 sq1 = reflect_xy(sq1);
2434 sq2 = reflect_xy(sq2);
2435 sq3 = reflect_xy(sq3);
2436 };
2437
2438 index =
2439 sq0 +
2440 sq1 * i64 +
2441 sq2 * i64 * i64 +
2442 sptriv [sq3] * i64 * i64 * i64;
2443
2444 return (index);
2445 }
2446
2447 /*--> CalcIndex4B: calculate index, mode 4B */
CalcIndex4B(square sq0,square sq1,square sq2,square sq3)2448 INLINE INDEX CalcIndex4B
2449 (
2450 square sq0,
2451 square sq1,
2452 square sq2,
2453 square sq3
2454 )
2455 {
2456 INDEX index;
2457
2458 if (TbColumn(sq3) > x_column_d)
2459 {
2460 sq0 = reflect_y(sq0);
2461 sq1 = reflect_y(sq1);
2462 sq2 = reflect_y(sq2);
2463 sq3 = reflect_y(sq3);
2464 };
2465
2466 index =
2467 sq0 +
2468 sq1 * i64 +
2469 sq2 * i64 * i64 +
2470 spqsfv [sq3] * i64 * i64 * i64;
2471
2472 return (index);
2473 }
2474
2475 /*--> CalcIndex4C: calculate index, mode 4C */
CalcIndex4C(square sq0,square sq1,square sq2,square sq3)2476 INLINE INDEX CalcIndex4C
2477 (
2478 square sq0,
2479 square sq1,
2480 square sq2,
2481 square sq3
2482 )
2483 {
2484 INDEX index;
2485
2486 if (TbColumn(sq2) > x_column_d)
2487 {
2488 sq0 = reflect_y(sq0);
2489 sq1 = reflect_y(sq1);
2490 sq2 = reflect_y(sq2);
2491 sq3 = reflect_y(sq3);
2492 };
2493
2494 index =
2495 sq0 +
2496 sq1 * i64 +
2497 spqsfv [sq2] * i64 * i64 +
2498 sq3 * (i64 / 2) * i64 * i64;
2499
2500 return (index);
2501 }
2502
2503 /*--> CalcIndex5A: calculate index, mode 5A */
CalcIndex5A(square sq0,square sq1,square sq2,square sq3,square sq4)2504 INLINE INDEX CalcIndex5A
2505 (
2506 square sq0,
2507 square sq1,
2508 square sq2,
2509 square sq3,
2510 square sq4
2511 )
2512 {
2513 INDEX index;
2514
2515 if (TbRow(sq4) > x_row_4)
2516 {
2517 sq0 = reflect_x(sq0);
2518 sq1 = reflect_x(sq1);
2519 sq2 = reflect_x(sq2);
2520 sq3 = reflect_x(sq3);
2521 sq4 = reflect_x(sq4);
2522 };
2523
2524 if (TbColumn(sq4) > x_column_d)
2525 {
2526 sq0 = reflect_y(sq0);
2527 sq1 = reflect_y(sq1);
2528 sq2 = reflect_y(sq2);
2529 sq3 = reflect_y(sq3);
2530 sq4 = reflect_y(sq4);
2531 };
2532
2533 if (TbRow(sq4) > TbColumn(sq4))
2534 {
2535 sq0 = reflect_xy(sq0);
2536 sq1 = reflect_xy(sq1);
2537 sq2 = reflect_xy(sq2);
2538 sq3 = reflect_xy(sq3);
2539 sq4 = reflect_xy(sq4);
2540 };
2541
2542 index =
2543 sq0 +
2544 sq1 * i64 +
2545 sq2 * i64 * i64 +
2546 sq3 * i64 * i64 * i64 +
2547 sptriv [sq4] * i64 * i64 * i64 * i64;
2548
2549 return (index);
2550 }
2551
2552 /*--> CalcIndex5B: calculate index, mode 5B */
CalcIndex5B(square sq0,square sq1,square sq2,square sq3,square sq4)2553 INLINE INDEX CalcIndex5B
2554 (
2555 square sq0,
2556 square sq1,
2557 square sq2,
2558 square sq3,
2559 square sq4
2560 )
2561 {
2562 INDEX index;
2563
2564 if (TbColumn(sq4) > x_column_d)
2565 {
2566 sq0 = reflect_y(sq0);
2567 sq1 = reflect_y(sq1);
2568 sq2 = reflect_y(sq2);
2569 sq3 = reflect_y(sq3);
2570 sq4 = reflect_y(sq4);
2571 };
2572
2573 index =
2574 sq0 +
2575 sq1 * i64 +
2576 sq2 * i64 * i64 +
2577 sq3 * i64 * i64 * i64 +
2578 spqsfv [sq4] * i64 * i64 * i64 * i64;
2579
2580 return (index);
2581 }
2582
2583 /*--> CalcIndex5C: calculate index, mode 5C */
CalcIndex5C(square sq0,square sq1,square sq2,square sq3,square sq4)2584 INLINE INDEX CalcIndex5C
2585 (
2586 square sq0,
2587 square sq1,
2588 square sq2,
2589 square sq3,
2590 square sq4
2591 )
2592 {
2593 INDEX index;
2594
2595 if (TbColumn(sq3) > x_column_d)
2596 {
2597 sq0 = reflect_y(sq0);
2598 sq1 = reflect_y(sq1);
2599 sq2 = reflect_y(sq2);
2600 sq3 = reflect_y(sq3);
2601 sq4 = reflect_y(sq4);
2602 };
2603
2604 index =
2605 sq0 +
2606 sq1 * i64 +
2607 sq2 * i64 * i64 +
2608 spqsfv [sq3] * i64 * i64 * i64 +
2609 sq4 * (i64 / 2) * i64 * i64 * i64;
2610
2611 return (index);
2612 }
2613
2614 /*--> CalcIndex5D: calculate index, mode 5D */
CalcIndex5D(square sq0,square sq1,square sq2,square sq3,square sq4)2615 INLINE INDEX CalcIndex5D
2616 (
2617 square sq0,
2618 square sq1,
2619 square sq2,
2620 square sq3,
2621 square sq4
2622 )
2623 {
2624 INDEX index;
2625
2626 if (TbColumn(sq2) > x_column_d)
2627 {
2628 sq0 = reflect_y(sq0);
2629 sq1 = reflect_y(sq1);
2630 sq2 = reflect_y(sq2);
2631 sq3 = reflect_y(sq3);
2632 sq4 = reflect_y(sq4);
2633 };
2634
2635 index =
2636 sq0 +
2637 sq1 * i64 +
2638 spqsfv [sq2] * i64 * i64 +
2639 sq3 * (i64 / 2) * i64 * i64 +
2640 sq4 * (i64 / 2) * i64 * i64 * i64;
2641
2642 return (index);
2643 }
2644
2645 // Calculate index - a lot of functions...
2646
2647 #define IndCalcW IndCalc
2648 #define IndCalcB IndCalc
2649
2650 template <int pi> class T21
2651 {
2652 public:
IndCalc(square * psqW,square * psqB,square sqEnP,int fInvert)2653 static INDEX TB_FASTCALL IndCalc
2654 (
2655 square *psqW,
2656 square *psqB,
2657 square sqEnP,
2658 int fInvert
2659 )
2660 {
2661 square sq0, sq1, sq2;
2662
2663 sq0 = SqFindKing (psqW);
2664 sq1 = SqFindOne (psqW, pi);
2665 sq2 = SqFindKing (psqB);
2666
2667 if (x_piecePawn == pi)
2668 {
2669 if (fInvert)
2670 {
2671 sq0 = reflect_x (sq0);
2672 sq1 = reflect_x (sq1);
2673 sq2 = reflect_x (sq2);
2674 }
2675 return CalcIndex3B (sq0, sq1, sq2);
2676 }
2677 else
2678 return CalcIndex3A (sq0, sq1, sq2);
2679 }
2680 };
2681
2682 template <int pi1, int pi2> class T22
2683 {
2684 public:
IndCalc(square * psqW,square * psqB,square sqEnP,int fInvert)2685 static INDEX TB_FASTCALL IndCalc
2686 (
2687 square *psqW,
2688 square *psqB,
2689 square sqEnP,
2690 int fInvert
2691 )
2692 {
2693 square sq0, sq1, sq2, sq3;
2694
2695 sq0 = SqFindKing (psqW);
2696 sq1 = SqFindOne (psqW, pi1);
2697 sq2 = SqFindKing (psqB);
2698 sq3 = SqFindOne (psqB, pi2);
2699
2700 if (x_piecePawn == pi1 || x_piecePawn == pi2)
2701 {
2702 if (fInvert)
2703 {
2704 sq0 = reflect_x (sq0);
2705 sq1 = reflect_x (sq1);
2706 sq2 = reflect_x (sq2);
2707 sq3 = reflect_x (sq3);
2708 }
2709 return CalcIndex4B (sq0, sq1, sq2, sq3);
2710 }
2711 else
2712 return CalcIndex4A (sq0, sq1, sq2, sq3);
2713 }
2714 };
2715
2716 template <int pi1, int pi2> class T31
2717 {
2718 public:
IndCalc(square * psqW,square * psqB,square sqEnP,int fInvert)2719 static INDEX TB_FASTCALL IndCalc
2720 (
2721 square *psqW,
2722 square *psqB,
2723 square sqEnP,
2724 int fInvert
2725 )
2726 {
2727 square sq0, sq1, sq2, sq3;
2728
2729 sq0 = SqFindKing (psqW);
2730 sq1 = SqFindFirst (psqW, pi1);
2731 if (pi1 == pi2)
2732 sq2 = SqFindSecond (psqW, pi2);
2733 else
2734 sq2 = SqFindFirst (psqW, pi2);
2735 sq3 = SqFindKing (psqB);
2736
2737 if (x_piecePawn == pi1 || x_piecePawn == pi2)
2738 {
2739 if (fInvert)
2740 {
2741 sq0 = reflect_x (sq0);
2742 sq1 = reflect_x (sq1);
2743 sq2 = reflect_x (sq2);
2744 sq3 = reflect_x (sq3);
2745 }
2746 return CalcIndex4C (sq0, sq1, sq2, sq3);
2747 }
2748 else
2749 return CalcIndex4A (sq0, sq1, sq2, sq3);
2750 }
2751 };
2752
2753 template <int pi1, int pi2, int pi3> class T32
2754 {
2755 public:
IndCalc(square * psqW,square * psqB,square sqEnP,int fInvert)2756 static INDEX TB_FASTCALL IndCalc
2757 (
2758 square *psqW,
2759 square *psqB,
2760 square sqEnP,
2761 int fInvert
2762 )
2763 {
2764 square sq0, sq1, sq2, sq3, sq4;
2765
2766 sq0 = SqFindKing (psqW);
2767 sq1 = SqFindFirst (psqW, pi1);
2768 if (pi1 == pi2)
2769 sq2 = SqFindSecond (psqW, pi2);
2770 else
2771 sq2 = SqFindFirst (psqW, pi2);
2772 sq3 = SqFindKing (psqB);
2773 sq4 = SqFindOne (psqB, pi3);
2774
2775 if (x_piecePawn == pi1 || x_piecePawn == pi2 || x_piecePawn == pi3)
2776 {
2777 if (fInvert)
2778 {
2779 sq0 = reflect_x (sq0);
2780 sq1 = reflect_x (sq1);
2781 sq2 = reflect_x (sq2);
2782 sq3 = reflect_x (sq3);
2783 sq4 = reflect_x (sq4);
2784 }
2785 if (x_piecePawn == pi3)
2786 return CalcIndex5B (sq0, sq1, sq2, sq3, sq4);
2787 else
2788 return CalcIndex5D (sq0, sq1, sq2, sq3, sq4);
2789 }
2790 else
2791 return CalcIndex5A (sq0, sq1, sq2, sq3, sq4);
2792 }
2793 };
2794
2795 #if defined (T41_INCLUDE)
2796
2797 template <int pi1, int pi2, int pi3> class T41
2798 {
2799 public:
IndCalc(square * psqW,square * psqB,square sqEnP,int fInvert)2800 static INDEX TB_FASTCALL IndCalc
2801 (
2802 square *psqW,
2803 square *psqB,
2804 square sqEnP,
2805 int fInvert
2806 )
2807 {
2808 square sq0, sq1, sq2, sq3, sq4;
2809
2810 sq0 = SqFindKing (psqW);
2811 sq1 = SqFindFirst (psqW, pi1);
2812 sq2 = SqFindFirst (psqW, pi2);
2813 sq3 = SqFindFirst (psqW, pi3);
2814 sq4 = SqFindKing (psqB);
2815
2816 if (x_piecePawn == pi1 || x_piecePawn == pi2 || x_piecePawn == pi3)
2817 {
2818 // There are pawns on the board
2819 if (fInvert)
2820 {
2821 sq0 = reflect_x (sq0);
2822 sq1 = reflect_x (sq1);
2823 sq2 = reflect_x (sq2);
2824 sq3 = reflect_x (sq3);
2825 sq4 = reflect_x (sq4);
2826 }
2827 return CalcIndex5C (sq0, sq1, sq2, sq3, sq4);
2828 }
2829 else // No pawns
2830 return CalcIndex5A (sq0, sq1, sq2, sq3, sq4);
2831 }
2832 };
2833
2834 #endif
2835
2836 #endif //----------------------------------------------------------------------
2837
2838 // All tablebase enumerated
2839
2840 #if defined (T41_INCLUDE)
2841 #define cTb 146
2842 #else
2843 #define cTb 111
2844 #endif
2845
2846 #define tbid_kk 0
2847 #define tbid_kpk 1
2848 #define tbid_knk 2
2849 #define tbid_kbk 3
2850 #define tbid_krk 4
2851 #define tbid_kqk 5
2852 #define tbid_kpkp 6
2853 #define tbid_knkp 7
2854 #define tbid_knkn 8
2855 #define tbid_kbkp 9
2856 #define tbid_kbkn 10
2857 #define tbid_kbkb 11
2858 #define tbid_krkp 12
2859 #define tbid_krkn 13
2860 #define tbid_krkb 14
2861 #define tbid_krkr 15
2862 #define tbid_kqkp 16
2863 #define tbid_kqkn 17
2864 #define tbid_kqkb 18
2865 #define tbid_kqkr 19
2866 #define tbid_kqkq 20
2867 #define tbid_kppk 21
2868 #define tbid_knpk 22
2869 #define tbid_knnk 23
2870 #define tbid_kbpk 24
2871 #define tbid_kbnk 25
2872 #define tbid_kbbk 26
2873 #define tbid_krpk 27
2874 #define tbid_krnk 28
2875 #define tbid_krbk 29
2876 #define tbid_krrk 30
2877 #define tbid_kqpk 31
2878 #define tbid_kqnk 32
2879 #define tbid_kqbk 33
2880 #define tbid_kqrk 34
2881 #define tbid_kqqk 35
2882 #define tbid_kppkp 36
2883 #define tbid_kppkn 37
2884 #define tbid_kppkb 38
2885 #define tbid_kppkr 39
2886 #define tbid_kppkq 40
2887 #define tbid_knpkp 41
2888 #define tbid_knpkn 42
2889 #define tbid_knpkb 43
2890 #define tbid_knpkr 44
2891 #define tbid_knpkq 45
2892 #define tbid_knnkp 46
2893 #define tbid_knnkn 47
2894 #define tbid_knnkb 48
2895 #define tbid_knnkr 49
2896 #define tbid_knnkq 50
2897 #define tbid_kbpkp 51
2898 #define tbid_kbpkn 52
2899 #define tbid_kbpkb 53
2900 #define tbid_kbpkr 54
2901 #define tbid_kbpkq 55
2902 #define tbid_kbnkp 56
2903 #define tbid_kbnkn 57
2904 #define tbid_kbnkb 58
2905 #define tbid_kbnkr 59
2906 #define tbid_kbnkq 60
2907 #define tbid_kbbkp 61
2908 #define tbid_kbbkn 62
2909 #define tbid_kbbkb 63
2910 #define tbid_kbbkr 64
2911 #define tbid_kbbkq 65
2912 #define tbid_krpkp 66
2913 #define tbid_krpkn 67
2914 #define tbid_krpkb 68
2915 #define tbid_krpkr 69
2916 #define tbid_krpkq 70
2917 #define tbid_krnkp 71
2918 #define tbid_krnkn 72
2919 #define tbid_krnkb 73
2920 #define tbid_krnkr 74
2921 #define tbid_krnkq 75
2922 #define tbid_krbkp 76
2923 #define tbid_krbkn 77
2924 #define tbid_krbkb 78
2925 #define tbid_krbkr 79
2926 #define tbid_krbkq 80
2927 #define tbid_krrkp 81
2928 #define tbid_krrkn 82
2929 #define tbid_krrkb 83
2930 #define tbid_krrkr 84
2931 #define tbid_krrkq 85
2932 #define tbid_kqpkp 86
2933 #define tbid_kqpkn 87
2934 #define tbid_kqpkb 88
2935 #define tbid_kqpkr 89
2936 #define tbid_kqpkq 90
2937 #define tbid_kqnkp 91
2938 #define tbid_kqnkn 92
2939 #define tbid_kqnkb 93
2940 #define tbid_kqnkr 94
2941 #define tbid_kqnkq 95
2942 #define tbid_kqbkp 96
2943 #define tbid_kqbkn 97
2944 #define tbid_kqbkb 98
2945 #define tbid_kqbkr 99
2946 #define tbid_kqbkq 100
2947 #define tbid_kqrkp 101
2948 #define tbid_kqrkn 102
2949 #define tbid_kqrkb 103
2950 #define tbid_kqrkr 104
2951 #define tbid_kqrkq 105
2952 #define tbid_kqqkp 106
2953 #define tbid_kqqkn 107
2954 #define tbid_kqqkb 108
2955 #define tbid_kqqkr 109
2956 #define tbid_kqqkq 110
2957
2958 #if defined (T41_INCLUDE)
2959 #define tbid_kpppk 111
2960 #define tbid_knppk 112
2961 #define tbid_knnpk 113
2962 #define tbid_knnnk 114
2963 #define tbid_kbppk 115
2964 #define tbid_kbnpk 116
2965 #define tbid_kbnnk 117
2966 #define tbid_kbbpk 118
2967 #define tbid_kbbnk 119
2968 #define tbid_kbbbk 120
2969 #define tbid_krppk 121
2970 #define tbid_krnpk 122
2971 #define tbid_krnnk 123
2972 #define tbid_krbpk 124
2973 #define tbid_krbnk 125
2974 #define tbid_krbbk 126
2975 #define tbid_krrpk 127
2976 #define tbid_krrnk 128
2977 #define tbid_krrbk 129
2978 #define tbid_krrrk 130
2979 #define tbid_kqppk 131
2980 #define tbid_kqnpk 132
2981 #define tbid_kqnnk 133
2982 #define tbid_kqbpk 134
2983 #define tbid_kqbnk 135
2984 #define tbid_kqbbk 136
2985 #define tbid_kqrpk 137
2986 #define tbid_kqrnk 138
2987 #define tbid_kqrbk 139
2988 #define tbid_kqrrk 140
2989 #define tbid_kqqpk 141
2990 #define tbid_kqqnk 142
2991 #define tbid_kqqbk 143
2992 #define tbid_kqqrk 144
2993 #define tbid_kqqqk 145
2994 #endif
2995
2996 // Compression
2997
2998 #include "tbdecode.c"
2999
3000 #if !defined (CPUS)
3001 #define CPUS 1
3002 #endif
3003
3004 #if defined (SMP)
3005 static lock_t LockDecode;
3006 #endif
3007 extern "C" { int TB_CRC_CHECK = 0; }
3008 static int cCompressed = 0;
3009 static decode_block *rgpdbDecodeBlocks[CPUS];
3010
3011 // Information about tablebases
3012
3013 #define MAX_TOTAL_PIECES 5 /* Maximum # of pieces on the board */
3014 #define MAX_NON_KINGS (MAX_TOTAL_PIECES - 2)
3015
3016 #if !defined (TB_DIRECTORY_SIZE)
3017 #define TB_DIRECTORY_SIZE 32 /* # of cache buckets */
3018 #endif
3019
3020 typedef INDEX (TB_FASTCALL * PfnCalcIndex) (square *psqW, square *psqB,
3021 square sqEnP, int fInverse);
3022 struct CTbCache;
3023
3024 typedef struct // Hungarian: tbcb
3025 {
3026 #if defined (SMP)
3027 lock_t m_lock; // Lock on this cache bucket list
3028 #endif
3029 volatile CTbCache *m_ptbcFirst; // Cached file chunks in LRU order
3030 }
3031 CTbCacheBucket;
3032
3033 typedef struct // Hungarian: tbd
3034 {
3035 int m_iTbId;
3036 PfnCalcIndex m_rgpfnCalcIndex[2];
3037 char m_rgchName[MAX_TOTAL_PIECES+1];
3038 INDEX m_rgcbLength[2];
3039 char *m_rgpchFileName[2];
3040 #if defined (SMP)
3041 lock_t m_rglockFiles[2];
3042 #endif
3043 FILE *m_rgfpFiles[2];
3044 decode_info *m_rgpdiDecodeInfo[2];
3045 CTbCacheBucket *m_prgtbcbBuckets[2]; // Cached file chunks in LRU order
3046 BYTE *m_rgpbRead[2];
3047 }
3048 CTbDesc;
3049
3050 #define TB(name, funW, funB, cbW, cbB) { tbid_##name, { funW, funB }, #name, { cbW, cbB } },
3051
3052 #define P x_piecePawn
3053 #define N x_pieceKnight
3054 #define B x_pieceBishop
3055 #define R x_pieceRook
3056 #define Q x_pieceQueen
3057
3058 CTbDesc rgtbdDesc[cTb] =
3059 {
3060 TB (kk, NULL, NULL, 0, 0)
3061 TB (kpk, (T21<P>::IndCalcW), (T21<P>::IndCalcB), 81664, 84012)
3062 TB (knk, (T21<N>::IndCalcW), (T21<N>::IndCalcB), 26282, 28644)
3063 TB (kbk, (T21<B>::IndCalcW), (T21<B>::IndCalcB), 27243, 28644)
3064 TB (krk, (T21<R>::IndCalcW), (T21<R>::IndCalcB), 27030, 28644)
3065 TB (kqk, (T21<Q>::IndCalcW), (T21<Q>::IndCalcB), 25629, 28644)
3066
3067 TB (kpkp, (T22<P, P>::IndCalcW), (T22<P, P>::IndCalcB), 3863492, 3863492)
3068 TB (knkp, (T22<N, P>::IndCalcW), (T22<N, P>::IndCalcB), 4931904, 4981504)
3069 TB (knkn, (T22<N, N>::IndCalcW), (T22<N, N>::IndCalcB), 1603202, 1603202)
3070 TB (kbkp, (T22<B, P>::IndCalcW), (T22<B, P>::IndCalcB), 5112000, 4981504)
3071 TB (kbkn, (T22<B, N>::IndCalcW), (T22<B, N>::IndCalcB), 1661823, 1603202)
3072 TB (kbkb, (T22<B, B>::IndCalcW), (T22<B, B>::IndCalcB), 1661823, 1661823)
3073 TB (krkp, (T22<R, P>::IndCalcW), (T22<R, P>::IndCalcB), 5072736, 4981504)
3074 TB (krkn, (T22<R, N>::IndCalcW), (T22<R, N>::IndCalcB), 1649196, 1603202)
3075 TB (krkb, (T22<R, B>::IndCalcW), (T22<R, B>::IndCalcB), 1649196, 1661823)
3076 TB (krkr, (T22<R, R>::IndCalcW), (T22<R, R>::IndCalcB), 1649196, 1649196)
3077 TB (kqkp, (T22<Q, P>::IndCalcW), (T22<Q, P>::IndCalcB), 4810080, 4981504)
3078 TB (kqkn, (T22<Q, N>::IndCalcW), (T22<Q, N>::IndCalcB), 1563735, 1603202)
3079 TB (kqkb, (T22<Q, B>::IndCalcW), (T22<Q, B>::IndCalcB), 1563735, 1661823)
3080 TB (kqkr, (T22<Q, R>::IndCalcW), (T22<Q, R>::IndCalcB), 1563735, 1649196)
3081 TB (kqkq, (T22<Q, Q>::IndCalcW), (T22<Q, Q>::IndCalcB), 1563735, 1563735)
3082 TB (kppk, (T31<P, P>::IndCalcW), (T31<P, P>::IndCalcB), 1806671, 1912372)
3083 TB (knpk, (T31<N, P>::IndCalcW), (T31<N, P>::IndCalcB), 4648581, 5124732)
3084 TB (knnk, (T31<N, N>::IndCalcW), (T31<N, N>::IndCalcB), 735304, 873642)
3085 TB (kbpk, (T31<B, P>::IndCalcW), (T31<B, P>::IndCalcB), 4817128, 5124732)
3086 TB (kbnk, (T31<B, N>::IndCalcW), (T31<B, N>::IndCalcB), 1550620, 1747284)
3087 TB (kbbk, (T31<B, B>::IndCalcW), (T31<B, B>::IndCalcB), 789885, 873642)
3088 TB (krpk, (T31<R, P>::IndCalcW), (T31<R, P>::IndCalcB), 4779530, 5124732)
3089 TB (krnk, (T31<R, N>::IndCalcW), (T31<R, N>::IndCalcB), 1538479, 1747284)
3090 TB (krbk, (T31<R, B>::IndCalcW), (T31<R, B>::IndCalcB), 1594560, 1747284)
3091 TB (krrk, (T31<R, R>::IndCalcW), (T31<R, R>::IndCalcB), 777300, 873642)
3092 TB (kqpk, (T31<Q, P>::IndCalcW), (T31<Q, P>::IndCalcB), 4533490, 5124732)
3093 TB (kqnk, (T31<Q, N>::IndCalcW), (T31<Q, N>::IndCalcB), 1459616, 1747284)
3094 TB (kqbk, (T31<Q, B>::IndCalcW), (T31<Q, B>::IndCalcB), 1512507, 1747284)
3095 TB (kqrk, (T31<Q, R>::IndCalcW), (T31<Q, R>::IndCalcB), 1500276, 1747284)
3096 TB (kqqk, (T31<Q, Q>::IndCalcW), (T31<Q, Q>::IndCalcB), 698739, 873642)
3097
3098 #if !defined (KPPKP_16BIT)
3099 TB (kppkp, (T32<P, P, P>::IndCalcW), (T32<P, P, P>::IndCalcB), 84219361, 89391280)
3100 #else
3101 TB (kppkp, (T32<P, P, P>::IndCalcW), (T32<P, P, P>::IndCalcB), 2*84219361, 2*89391280)
3102 #endif
3103 TB (kppkn, (T32<P, P, N>::IndCalcW), (T32<P, P, N>::IndCalcB), 108400260, 115899744)
3104 TB (kppkb, (T32<P, P, B>::IndCalcW), (T32<P, P, B>::IndCalcB), 108400260, 120132000)
3105 TB (kppkr, (T32<P, P, R>::IndCalcW), (T32<P, P, R>::IndCalcB), 108400260, 119209296)
3106 TB (kppkq, (T32<P, P, Q>::IndCalcW), (T32<P, P, Q>::IndCalcB), 108400260, 113036880)
3107 TB (knpkp, (T32<N, P, P>::IndCalcW), (T32<N, P, P>::IndCalcB), 219921779, 231758952)
3108 TB (knpkn, (T32<N, P, N>::IndCalcW), (T32<N, P, N>::IndCalcB), 278914860, 295914240)
3109 TB (knpkb, (T32<N, P, B>::IndCalcW), (T32<N, P, B>::IndCalcB), 278914860, 306720000)
3110 TB (knpkr, (T32<N, P, R>::IndCalcW), (T32<N, P, R>::IndCalcB), 278914860, 304369920)
3111 TB (knpkq, (T32<N, P, Q>::IndCalcW), (T32<N, P, Q>::IndCalcB), 278914860, 288610560)
3112 TB (knnkp, (T32<N, N, P>::IndCalcW), (T32<N, N, P>::IndCalcB), 137991648, 149445120)
3113 TB (knnkn, (T32<N, N, N>::IndCalcW), (T32<N, N, N>::IndCalcB), 44118240, 48096060)
3114 TB (knnkb, (T32<N, N, B>::IndCalcW), (T32<N, N, B>::IndCalcB), 44118240, 49854690)
3115 TB (knnkr, (T32<N, N, R>::IndCalcW), (T32<N, N, R>::IndCalcB), 44118240, 49475880)
3116 TB (knnkq, (T32<N, N, Q>::IndCalcW), (T32<N, N, Q>::IndCalcB), 44118240, 46912050)
3117 TB (kbpkp, (T32<B, P, P>::IndCalcW), (T32<B, P, P>::IndCalcB), 227896016, 231758952)
3118 TB (kbpkn, (T32<B, P, N>::IndCalcW), (T32<B, P, N>::IndCalcB), 289027680, 295914240)
3119 TB (kbpkb, (T32<B, P, B>::IndCalcW), (T32<B, P, B>::IndCalcB), 289027680, 306720000)
3120 TB (kbpkr, (T32<B, P, R>::IndCalcW), (T32<B, P, R>::IndCalcB), 289027680, 304369920)
3121 TB (kbpkq, (T32<B, P, Q>::IndCalcW), (T32<B, P, Q>::IndCalcB), 289027680, 288610560)
3122 TB (kbnkp, (T32<B, N, P>::IndCalcW), (T32<B, N, P>::IndCalcB), 290989584, 298890240)
3123 TB (kbnkn, (T32<B, N, N>::IndCalcW), (T32<B, N, N>::IndCalcB), 93037200, 96192120)
3124 TB (kbnkb, (T32<B, N, B>::IndCalcW), (T32<B, N, B>::IndCalcB), 93037200, 99709380)
3125 TB (kbnkr, (T32<B, N, R>::IndCalcW), (T32<B, N, R>::IndCalcB), 93037200, 98951760)
3126 TB (kbnkq, (T32<B, N, Q>::IndCalcW), (T32<B, N, Q>::IndCalcB), 93037200, 93824100)
3127 TB (kbbkp, (T32<B, B, P>::IndCalcW), (T32<B, B, P>::IndCalcB), 148223520, 149445120)
3128 TB (kbbkn, (T32<B, B, N>::IndCalcW), (T32<B, B, N>::IndCalcB), 47393100, 48096060)
3129 TB (kbbkb, (T32<B, B, B>::IndCalcW), (T32<B, B, B>::IndCalcB), 47393100, 49854690)
3130 TB (kbbkr, (T32<B, B, R>::IndCalcW), (T32<B, B, R>::IndCalcB), 47393100, 49475880)
3131 TB (kbbkq, (T32<B, B, Q>::IndCalcW), (T32<B, B, Q>::IndCalcB), 47393100, 46912050)
3132 TB (krpkp, (T32<R, P, P>::IndCalcW), (T32<R, P, P>::IndCalcB), 226121876, 231758952)
3133 TB (krpkn, (T32<R, P, N>::IndCalcW), (T32<R, P, N>::IndCalcB), 286777440, 295914240)
3134 TB (krpkb, (T32<R, P, B>::IndCalcW), (T32<R, P, B>::IndCalcB), 286777440, 306720000)
3135 TB (krpkr, (T32<R, P, R>::IndCalcW), (T32<R, P, R>::IndCalcB), 286777440, 304369920)
3136 TB (krpkq, (T32<R, P, Q>::IndCalcW), (T32<R, P, Q>::IndCalcB), 286777440, 288610560)
3137 TB (krnkp, (T32<R, N, P>::IndCalcW), (T32<R, N, P>::IndCalcB), 288692928, 298890240)
3138 TB (krnkn, (T32<R, N, N>::IndCalcW), (T32<R, N, N>::IndCalcB), 92308740, 96192120)
3139 TB (krnkb, (T32<R, N, B>::IndCalcW), (T32<R, N, B>::IndCalcB), 92308740, 99709380)
3140 TB (krnkr, (T32<R, N, R>::IndCalcW), (T32<R, N, R>::IndCalcB), 92308740, 98951760)
3141 TB (krnkq, (T32<R, N, Q>::IndCalcW), (T32<R, N, Q>::IndCalcB), 92308740, 93824100)
3142 TB (krbkp, (T32<R, B, P>::IndCalcW), (T32<R, B, P>::IndCalcB), 299203200, 298890240)
3143 TB (krbkn, (T32<R, B, N>::IndCalcW), (T32<R, B, N>::IndCalcB), 95673600, 96192120)
3144 TB (krbkb, (T32<R, B, B>::IndCalcW), (T32<R, B, B>::IndCalcB), 95673600, 99709380)
3145 TB (krbkr, (T32<R, B, R>::IndCalcW), (T32<R, B, R>::IndCalcB), 95673600, 98951760)
3146 TB (krbkq, (T32<R, B, Q>::IndCalcW), (T32<R, B, Q>::IndCalcB), 95673600, 93824100)
3147 TB (krrkp, (T32<R, R, P>::IndCalcW), (T32<R, R, P>::IndCalcB), 145901232, 149445120)
3148 TB (krrkn, (T32<R, R, N>::IndCalcW), (T32<R, R, N>::IndCalcB), 46658340, 48096060)
3149 TB (krrkb, (T32<R, R, B>::IndCalcW), (T32<R, R, B>::IndCalcB), 46658340, 49854690)
3150 TB (krrkr, (T32<R, R, R>::IndCalcW), (T32<R, R, R>::IndCalcB), 46658340, 49475880)
3151 TB (krrkq, (T32<R, R, Q>::IndCalcW), (T32<R, R, Q>::IndCalcB), 46658340, 46912050)
3152 TB (kqpkp, (T32<Q, P, P>::IndCalcW), (T32<Q, P, P>::IndCalcB), 214481388, 231758952)
3153 TB (kqpkn, (T32<Q, P, N>::IndCalcW), (T32<Q, P, N>::IndCalcB), 272015040, 295914240)
3154 TB (kqpkb, (T32<Q, P, B>::IndCalcW), (T32<Q, P, B>::IndCalcB), 272015040, 306720000)
3155 TB (kqpkr, (T32<Q, P, R>::IndCalcW), (T32<Q, P, R>::IndCalcB), 272015040, 304369920)
3156 TB (kqpkq, (T32<Q, P, Q>::IndCalcW), (T32<Q, P, Q>::IndCalcB), 272015040, 288610560)
3157 TB (kqnkp, (T32<Q, N, P>::IndCalcW), (T32<Q, N, P>::IndCalcB), 273904512, 298890240)
3158 TB (kqnkn, (T32<Q, N, N>::IndCalcW), (T32<Q, N, N>::IndCalcB), 87576960, 96192120)
3159 TB (kqnkb, (T32<Q, N, B>::IndCalcW), (T32<Q, N, B>::IndCalcB), 87576960, 99709380)
3160 TB (kqnkr, (T32<Q, N, R>::IndCalcW), (T32<Q, N, R>::IndCalcB), 87576960, 98951760)
3161 TB (kqnkq, (T32<Q, N, Q>::IndCalcW), (T32<Q, N, Q>::IndCalcB), 87576960, 93824100)
3162 TB (kqbkp, (T32<Q, B, P>::IndCalcW), (T32<Q, B, P>::IndCalcB), 283818240, 298890240)
3163 TB (kqbkn, (T32<Q, B, N>::IndCalcW), (T32<Q, B, N>::IndCalcB), 90750420, 96192120)
3164 TB (kqbkb, (T32<Q, B, B>::IndCalcW), (T32<Q, B, B>::IndCalcB), 90750420, 99709380)
3165 TB (kqbkr, (T32<Q, B, R>::IndCalcW), (T32<Q, B, R>::IndCalcB), 90750420, 98951760)
3166 TB (kqbkq, (T32<Q, B, Q>::IndCalcW), (T32<Q, B, Q>::IndCalcB), 90750420, 93824100)
3167 TB (kqrkp, (T32<Q, R, P>::IndCalcW), (T32<Q, R, P>::IndCalcB), 281568240, 298890240)
3168 TB (kqrkn, (T32<Q, R, N>::IndCalcW), (T32<Q, R, N>::IndCalcB), 90038460, 96192120)
3169 TB (kqrkb, (T32<Q, R, B>::IndCalcW), (T32<Q, R, B>::IndCalcB), 90038460, 99709380)
3170 TB (kqrkr, (T32<Q, R, R>::IndCalcW), (T32<Q, R, R>::IndCalcB), 90038460, 98951760)
3171 TB (kqrkq, (T32<Q, R, Q>::IndCalcW), (T32<Q, R, Q>::IndCalcB), 90038460, 93824100)
3172 TB (kqqkp, (T32<Q, Q, P>::IndCalcW), (T32<Q, Q, P>::IndCalcB), 131170128, 149445120)
3173 TB (kqqkn, (T32<Q, Q, N>::IndCalcW), (T32<Q, Q, N>::IndCalcB), 41944320, 48096060)
3174 TB (kqqkb, (T32<Q, Q, B>::IndCalcW), (T32<Q, Q, B>::IndCalcB), 41944320, 49854690)
3175 TB (kqqkr, (T32<Q, Q, R>::IndCalcW), (T32<Q, Q, R>::IndCalcB), 41944320, 49475880)
3176 TB (kqqkq, (T32<Q, Q, Q>::IndCalcW), (T32<Q, Q, Q>::IndCalcB), 41944320, 46912050)
3177
3178 #if defined (T41_INCLUDE)
3179 TB (kpppk, (T41<P, P, P>::IndCalcW), (T41<P, P, P>::IndCalcB), 26061704, 28388716)
3180 TB (knppk, (T41<N, P, P>::IndCalcW), (T41<N, P, P>::IndCalcB), 102898651, 114742320)
3181 TB (knnpk, (T41<N, N, P>::IndCalcW), (T41<N, N, P>::IndCalcB), 130135501, 153741960)
3182 TB (knnnk, (T41<N, N, N>::IndCalcW), (T41<N, N, N>::IndCalcB), 13486227, 17472840)
3183 TB (kbppk, (T41<B, P, P>::IndCalcW), (T41<B, P, P>::IndCalcB), 106602156, 114742320)
3184 TB (kbnpk, (T41<B, N, P>::IndCalcW), (T41<B, N, P>::IndCalcB), 274352939, 307483920)
3185 TB (kbnnk, (T41<B, N, N>::IndCalcW), (T41<B, N, N>::IndCalcB), 43406294, 52418520)
3186 TB (kbbpk, (T41<B, B, P>::IndCalcW), (T41<B, B, P>::IndCalcB), 139715040, 153741960)
3187 TB (kbbnk, (T41<B, B, N>::IndCalcW), (T41<B, B, N>::IndCalcB), 44983618, 52418520)
3188 TB (kbbbk, (T41<B, B, B>::IndCalcW), (T41<B, B, B>::IndCalcB), 15010230, 17472840)
3189 TB (krppk, (T41<R, P, P>::IndCalcW), (T41<R, P, P>::IndCalcB), 105758666, 114742320)
3190 TB (krnpk, (T41<R, N, P>::IndCalcW), (T41<R, N, P>::IndCalcB), 272153675, 307483920)
3191 TB (krnnk, (T41<R, N, N>::IndCalcW), (T41<R, N, N>::IndCalcB), 43056198, 52418520)
3192 TB (krbpk, (T41<R, B, P>::IndCalcW), (T41<R, B, P>::IndCalcB), 281991360, 307483920)
3193 TB (krbnk, (T41<R, B, N>::IndCalcW), (T41<R, B, N>::IndCalcB), 90787358, 104837040)
3194 TB (krbbk, (T41<R, B, B>::IndCalcW), (T41<R, B, B>::IndCalcB), 46242089, 52418520)
3195 TB (krrpk, (T41<R, R, P>::IndCalcW), (T41<R, R, P>::IndCalcB), 137491197, 153741960)
3196 TB (krrnk, (T41<R, R, N>::IndCalcW), (T41<R, R, N>::IndCalcB), 44265261, 52418520)
3197 TB (krrbk, (T41<R, R, B>::IndCalcW), (T41<R, R, B>::IndCalcB), 45873720, 52418520)
3198 TB (krrrk, (T41<R, R, R>::IndCalcW), (T41<R, R, R>::IndCalcB), 14644690, 17472840)
3199 TB (kqppk, (T41<Q, P, P>::IndCalcW), (T41<Q, P, P>::IndCalcB), 100347220, 114742320)
3200 TB (kqnpk, (T41<Q, N, P>::IndCalcW), (T41<Q, N, P>::IndCalcB), 258294639, 307483920)
3201 TB (kqnnk, (T41<Q, N, N>::IndCalcW), (T41<Q, N, N>::IndCalcB), 40873646, 52418520)
3202 TB (kqbpk, (T41<Q, B, P>::IndCalcW), (T41<Q, B, P>::IndCalcB), 267576632, 307483920)
3203 TB (kqbnk, (T41<Q, B, N>::IndCalcW), (T41<Q, B, N>::IndCalcB), 86166717, 104837040)
3204 TB (kqbbk, (T41<Q, B, B>::IndCalcW), (T41<Q, B, B>::IndCalcB), 43879679, 52418520)
3205 TB (kqrpk, (T41<Q, R, P>::IndCalcW), (T41<Q, R, P>::IndCalcB), 265421907, 307483920)
3206 TB (kqrnk, (T41<Q, R, N>::IndCalcW), (T41<Q, R, N>::IndCalcB), 85470603, 104837040)
3207 TB (kqrbk, (T41<Q, R, B>::IndCalcW), (T41<Q, R, B>::IndCalcB), 88557959, 104837040)
3208 TB (kqrrk, (T41<Q, R, R>::IndCalcW), (T41<Q, R, R>::IndCalcB), 43157690, 52418520)
3209 TB (kqqpk, (T41<Q, Q, P>::IndCalcW), (T41<Q, Q, P>::IndCalcB), 123688859, 153741960)
3210 TB (kqqnk, (T41<Q, Q, N>::IndCalcW), (T41<Q, Q, N>::IndCalcB), 39840787, 52418520)
3211 TB (kqqbk, (T41<Q, Q, B>::IndCalcW), (T41<Q, Q, B>::IndCalcB), 41270973, 52418520)
3212 TB (kqqrk, (T41<Q, Q, R>::IndCalcW), (T41<Q, Q, R>::IndCalcB), 40916820, 52418520)
3213 TB (kqqqk, (T41<Q, Q, Q>::IndCalcW), (T41<Q, Q, Q>::IndCalcB), 12479974, 17472840)
3214 #endif
3215 };
3216
3217 #undef P
3218 #undef N
3219 #undef B
3220 #undef R
3221 #undef Q
3222
3223 // Helper structure
3224 // Used to classify on-board position
3225
3226 union CUTbReference // Hungarian: utbr
3227 {
3228 int m_iDesc; // Negative if have to inverse
3229 int m_cPieces;
3230 CUTbReference *m_utbReference;
3231 };
3232
3233 // Root of the search tree
3234
3235 static CUTbReference rgutbReference [MAX_NON_KINGS + 2];
3236
3237 // Convert TB name (e.g. KQKR) into set of counters
3238
PchSetHalfCounters(int * piCounters,const char * pch)3239 static const char *PchSetHalfCounters
3240 (
3241 int *piCounters,
3242 const char *pch
3243 )
3244 {
3245 memset (piCounters, 0, 5 * sizeof (int));
3246 while ('\0' != *pch && 'k' != *pch)
3247 {
3248 piece pi;
3249
3250 pi = x_piecePawn; // To make compiler happy
3251 switch (*pch)
3252 {
3253 case 'p':
3254 pi = x_piecePawn;
3255 break;
3256 case 'n':
3257 pi = x_pieceKnight;
3258 break;
3259 case 'b':
3260 pi = x_pieceBishop;
3261 break;
3262 case 'r':
3263 pi = x_pieceRook;
3264 break;
3265 case 'q':
3266 pi = x_pieceQueen;
3267 break;
3268 default:
3269 assert (0);
3270 }
3271 piCounters [pi-1] ++;
3272 pch ++;
3273 }
3274 return pch;
3275 };
3276
VSetCounters(int * piCounters,const char * pch)3277 static void VSetCounters
3278 (
3279 int *piCounters,
3280 const char *pch
3281 )
3282 {
3283 assert ('k' == *pch);
3284 pch = PchSetHalfCounters (piCounters, pch+1);
3285 assert ('k' == *pch);
3286 pch = PchSetHalfCounters (piCounters+5, pch+1);
3287 assert ('\0' == *pch);
3288 }
3289
3290 // Following functions return TB index
3291 // They differ by input arguments
3292
IDescFindFromCounters(int * piCount)3293 extern "C" int IDescFindFromCounters
3294 (
3295 int *piCount
3296 )
3297 {
3298 CUTbReference *putbr = rgutbReference;
3299
3300 if (piCount[0] > putbr->m_cPieces)
3301 goto not_found;
3302 putbr = putbr[1 + piCount[0]].m_utbReference;
3303 if (piCount[1] > putbr->m_cPieces)
3304 goto not_found;
3305 putbr = putbr[1 + piCount[1]].m_utbReference;
3306 if (piCount[2] > putbr->m_cPieces)
3307 goto not_found;
3308 putbr = putbr[1 + piCount[2]].m_utbReference;
3309 if (piCount[3] > putbr->m_cPieces)
3310 goto not_found;
3311 putbr = putbr[1 + piCount[3]].m_utbReference;
3312 if (piCount[4] > putbr->m_cPieces)
3313 goto not_found;
3314 putbr = putbr[1 + piCount[4]].m_utbReference;
3315 if (piCount[5] > putbr->m_cPieces)
3316 goto not_found;
3317 putbr = putbr[1 + piCount[5]].m_utbReference;
3318 if (piCount[6] > putbr->m_cPieces)
3319 goto not_found;
3320 putbr = putbr[1 + piCount[6]].m_utbReference;
3321 if (piCount[7] > putbr->m_cPieces)
3322 goto not_found;
3323 putbr = putbr[1 + piCount[7]].m_utbReference;
3324 if (piCount[8] > putbr->m_cPieces)
3325 goto not_found;
3326 putbr = putbr[1 + piCount[8]].m_utbReference;
3327 if (piCount[9] <= putbr->m_cPieces)
3328 return putbr[1 + piCount[9]].m_iDesc;
3329 not_found:
3330 return 0;
3331 }
3332
IDescFind(square * p_piW,square * p_piB,int cWhite,int cBlack)3333 int IDescFind
3334 (
3335 square *p_piW, // IN | Pointer to array of white pieces (king excluded)
3336 square *p_piB, // IN | Pointer to array of black pieces (king excluded)
3337 int cWhite, // IN | Counter of white pieces (king excluded)
3338 int cBlack // IN | Counter of black pieces (king excluded)
3339 )
3340 {
3341 int rgiCount[10];
3342
3343 // Set pieces counters
3344 rgiCount[0] =
3345 rgiCount[1] =
3346 rgiCount[2] =
3347 rgiCount[3] =
3348 rgiCount[4] =
3349 rgiCount[5] =
3350 rgiCount[6] =
3351 rgiCount[7] =
3352 rgiCount[8] =
3353 rgiCount[9] = 0;
3354 while (cWhite)
3355 {
3356 rgiCount[(*p_piW)-1] ++;
3357 p_piW ++;
3358 cWhite --;
3359 }
3360 while (cBlack)
3361 {
3362 rgiCount[5-1+(*p_piB)] ++;
3363 p_piB ++;
3364 cBlack --;
3365 }
3366 return IDescFindFromCounters (rgiCount);
3367 }
3368
IDescFindByName(char * pchName)3369 int IDescFindByName
3370 (
3371 char *pchName
3372 )
3373 {
3374 int rgiCount[10];
3375
3376 VSetCounters (rgiCount, pchName);
3377 return IDescFindFromCounters (rgiCount);
3378 }
3379
3380 //-----------------------------------------------------------------------------
3381 //
3382 // Function used during initialization
3383
3384 // Set of functions to create search table
3385
PutbrCreateSubtable(int cPieces,int iDepth)3386 static CUTbReference *PutbrCreateSubtable
3387 (
3388 int cPieces, // IN | # of pieces remaining on board
3389 int iDepth // IN | Recursion depth (# of piece classes left)
3390 )
3391 {
3392 CUTbReference *putbr;
3393
3394 putbr = (CUTbReference *) PvMalloc ((cPieces + 2) * sizeof (CUTbReference));
3395 putbr[0].m_cPieces = cPieces;
3396 if (0 == iDepth)
3397 {
3398 for (int i = 0; i <= cPieces; i ++)
3399 putbr[i+1].m_iDesc = 0;
3400 }
3401 else
3402 {
3403 for (int i = 0; i <= cPieces; i ++)
3404 putbr[i+1].m_utbReference = PutbrCreateSubtable (cPieces-i, iDepth-1);
3405 }
3406 return putbr;
3407 }
3408
3409 static bool fTbTableCreated = false;
3410
VCreateEmptyTbTable(void)3411 static void VCreateEmptyTbTable (void)
3412 {
3413 if (fTbTableCreated)
3414 return;
3415 fTbTableCreated = true;
3416 rgutbReference[0].m_cPieces = MAX_NON_KINGS;
3417 for (int i = 0; i <= MAX_NON_KINGS; i ++)
3418 rgutbReference[i+1].m_utbReference = PutbrCreateSubtable (MAX_NON_KINGS - i, 8);
3419 }
3420
3421 // Insert TB (e.g. KQKR) into search table
3422
FRegisterHalf(int iTb,int * piCount)3423 static bool FRegisterHalf
3424 (
3425 int iTb,
3426 int *piCount
3427 )
3428 {
3429 CUTbReference *putbr;
3430
3431 putbr = rgutbReference;
3432 for (int i = 0; i < 9; i ++)
3433 {
3434 if (piCount[i] > putbr->m_cPieces)
3435 return false;
3436 putbr = putbr[1 + piCount[i]].m_utbReference;
3437 }
3438 if (piCount[9] > putbr->m_cPieces)
3439 return false;
3440 putbr[1 + piCount[9]].m_iDesc = iTb;
3441 return true;
3442 }
3443
3444 // Insert TB (both, e.g. KQKR and KRKQ) into search table
3445
FRegisterTb(CTbDesc * ptbDesc)3446 static bool FRegisterTb
3447 (
3448 CTbDesc *ptbDesc
3449 )
3450 {
3451 int rgiCount[10];
3452 bool fInserted;
3453
3454 VSetCounters (rgiCount, ptbDesc->m_rgchName);
3455 fInserted = FRegisterHalf (ptbDesc->m_iTbId, rgiCount);
3456 if (fInserted)
3457 {
3458 for (int i = 0; i < 5; i ++)
3459 {
3460 int iTemp;
3461
3462 iTemp = rgiCount[i];
3463 rgiCount[i] = rgiCount[i+5];
3464 rgiCount[i+5] = iTemp;
3465 }
3466 fInserted = FRegisterHalf (-ptbDesc->m_iTbId, rgiCount);
3467 assert (fInserted);
3468 }
3469 return fInserted;
3470 }
3471
3472 // File mapping - Win32 code only
3473
3474 #if defined (_WIN32)
3475
PbMapFileForRead(char * szName,HANDLE * phFile,HANDLE * phFileMapping)3476 static BYTE * PbMapFileForRead
3477 (
3478 char *szName,
3479 HANDLE *phFile,
3480 HANDLE *phFileMapping
3481 )
3482 {
3483 HANDLE hFile;
3484 HANDLE hFileMapping;
3485 LPVOID lpFileBase;
3486
3487 hFile = CreateFile (szName, GENERIC_READ, FILE_SHARE_READ,
3488 NULL, OPEN_EXISTING,
3489 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
3490 if (INVALID_HANDLE_VALUE == hFile)
3491 {
3492 printf("*** Couldn't open file %s with CreateFile()\n", szName);
3493 exit (1);
3494 }
3495 hFileMapping = CreateFileMapping (hFile, NULL, PAGE_READONLY, 0, 0, NULL);
3496 if (0 == hFileMapping)
3497 {
3498 CloseHandle (hFile);
3499 printf ("*** Couldn't open file %s mapping with CreateFileMapping()\n", szName);
3500 exit (1);
3501 }
3502 lpFileBase = MapViewOfFile (hFileMapping, FILE_MAP_READ, 0, 0, 0);
3503 if (0 == lpFileBase)
3504 {
3505 CloseHandle (hFileMapping);
3506 CloseHandle (hFile);
3507 printf ("*** Couldn't map view of file %s with MapViewOfFile()\n", szName);
3508 exit (1);
3509 }
3510 if (NULL != phFile)
3511 *phFile = hFile;
3512 if (NULL != phFileMapping)
3513 *phFileMapping = hFileMapping;
3514 return (BYTE*) lpFileBase;
3515 }
3516
VUnmapFile(BYTE * pbFileBase,HANDLE hFile,HANDLE hFileMapping)3517 static void VUnmapFile
3518 (
3519 BYTE *pbFileBase,
3520 HANDLE hFile,
3521 HANDLE hFileMapping
3522 )
3523 {
3524 BOOL fFailed;
3525
3526 fFailed = (0 == UnmapViewOfFile (pbFileBase)) |
3527 (0 == CloseHandle (hFileMapping)) |
3528 (0 == CloseHandle (hFile));
3529 if (fFailed)
3530 {
3531 printf ("*** Couldn't unmap file\n");
3532 exit (1);
3533 }
3534 }
3535
3536 #endif
3537
3538 //-----------------------------------------------------------------------------
3539 //
3540 // TB caching
3541
3542 #if !defined (TB_CB_CACHE_CHUNK)
3543 #define TB_CB_CACHE_CHUNK 8192 /* Must be power of 2 */
3544 #define LOG2_TB_CB_CACHE_CHUNK 13
3545 #endif
3546
3547 #define TB_DIRECTORY_ENTRY(index) (((index) >> LOG2_TB_CB_CACHE_CHUNK) % TB_DIRECTORY_SIZE)
3548
3549 struct CTbCache //Hungarian: tbc
3550 {
3551 volatile int m_iTb;
3552 volatile color m_color;
3553 INDEX m_indStart;
3554 volatile CTbCache *m_ptbcNext; // Next element in double-linked general LRU list
3555 volatile CTbCache *m_ptbcPrev; // Previous element in double-linked general LRU list
3556 volatile CTbCache *m_ptbcTbNext; // Next element in double-linked cache bucket LRU list
3557 volatile CTbCache *m_ptbcTbPrev; // Previous element in double-linked cache bucket LRU list
3558 BYTE *m_pbData;
3559 };
3560
3561 static CTbCache *ptbcTbCache; // Cache memory
3562 static ULONG ctbcTbCache; // Cache size (in entries)
3563
3564 static volatile CTbCache *ptbcHead; // Head of that list
3565 static volatile CTbCache *ptbcTail; // Last element in that list
3566 static volatile CTbCache *ptbcFree; // First free cache header
3567
VTbCloseFile(int iTb,color side)3568 static INLINE void VTbCloseFile
3569 (
3570 int iTb,
3571 color side
3572 )
3573 {
3574 if (NULL != rgtbdDesc[iTb].m_rgfpFiles[side])
3575 {
3576 Lock (rgtbdDesc[iTb].m_rglockFiles[side]);
3577 fclose (rgtbdDesc[iTb].m_rgfpFiles[side]);
3578 rgtbdDesc[iTb].m_rgfpFiles[side] = NULL;
3579 UnLock (rgtbdDesc[iTb].m_rglockFiles[side]);
3580 }
3581 }
3582
VTbCloseFiles(void)3583 extern "C" void VTbCloseFiles (void)
3584 {
3585 // Initialized?
3586 if (0 == ctbcTbCache)
3587 return;
3588
3589 // Walk through TB cache and close all opened files
3590 for (int iTb = 1; iTb < cTb; iTb ++)
3591 {
3592 VTbCloseFile (iTb, x_colorWhite);
3593 VTbCloseFile (iTb, x_colorBlack);
3594 }
3595 }
3596
VTbClearCache(void)3597 void VTbClearCache (void)
3598 {
3599 CTbCache *ptbc;
3600 BYTE *pb;
3601 ULONG i;
3602
3603 // Initialized?
3604 if (0 == ctbcTbCache)
3605 return;
3606 VTbCloseFiles();
3607
3608 // Initialize all lists
3609 pb = (BYTE *) & ptbcTbCache [ctbcTbCache];
3610 for (i = 0, ptbc = ptbcTbCache; i < ctbcTbCache; i ++, ptbc ++)
3611 {
3612 ptbc->m_pbData = pb + i*(TB_CB_CACHE_CHUNK+32+4);
3613 ptbc->m_ptbcTbPrev =
3614 ptbc->m_ptbcTbNext =
3615 ptbc->m_ptbcPrev = NULL;
3616 ptbc->m_ptbcNext = (ptbc + 1);
3617 }
3618 ptbc[-1].m_ptbcNext = NULL;
3619
3620 // Clear references from TBs
3621 for (int iTb = 1; iTb < cTb; iTb ++)
3622 {
3623 if (NULL != rgtbdDesc[iTb].m_prgtbcbBuckets[x_colorWhite])
3624 memset (rgtbdDesc[iTb].m_prgtbcbBuckets[x_colorWhite], 0,
3625 TB_DIRECTORY_SIZE * sizeof (CTbCacheBucket));
3626 if (NULL != rgtbdDesc[iTb].m_prgtbcbBuckets[x_colorBlack])
3627 memset (rgtbdDesc[iTb].m_prgtbcbBuckets[x_colorBlack], 0,
3628 TB_DIRECTORY_SIZE * sizeof (CTbCacheBucket));
3629 }
3630
3631 // Set globals
3632 ptbcHead = ptbcTail = NULL;
3633 ptbcFree = ptbcTbCache;
3634 }
3635
FTbSetCacheSize(void * pv,ULONG cbSize)3636 extern "C" int FTbSetCacheSize
3637 (
3638 void *pv,
3639 ULONG cbSize
3640 )
3641 {
3642 VTbCloseFiles();
3643 ctbcTbCache = 0;
3644 ptbcHead = NULL;
3645 if (cbSize < sizeof (CTbCache))
3646 return false;
3647 ptbcTbCache = (CTbCache*) pv;
3648 ctbcTbCache = cbSize / (sizeof (CTbCache) + TB_CB_CACHE_CHUNK+32+4);
3649 VTbClearCache();
3650 return true;
3651 }
3652
3653 // Table registered
3654
3655 #define FRegistered(iTb, side) (NULL != rgtbdDesc[iTb].m_rgpchFileName[side])
FRegisteredFun(int iTb,color side)3656 extern "C" int FRegisteredFun
3657 (
3658 int iTb,
3659 color side
3660 )
3661 {
3662 return FRegistered (iTb, side);
3663 }
3664
3665 // Return function that calculates the necessary index:
3666
3667 #define PfnIndCalc(iTb, side) (rgtbdDesc[iTb].m_rgpfnCalcIndex[side])
PfnIndCalcFun(int iTb,color side)3668 extern "C" PfnCalcIndex PfnIndCalcFun
3669 (
3670 int iTb,
3671 color side
3672 )
3673 {
3674 return PfnIndCalc (iTb, side);
3675 }
3676
3677
3678 #if defined (_WIN32)
3679
3680 // Map whole file into memory
3681
FMapTableToMemory(int iTb,color side)3682 extern "C" int FMapTableToMemory
3683 (
3684 int iTb, // IN | Tablebase
3685 color side // IN | Side to move
3686 )
3687 {
3688 char *pszName;
3689
3690 if (!FRegistered (iTb, side))
3691 return false;
3692 if (NULL != rgtbdDesc[iTb].m_rgpdiDecodeInfo[side])
3693 return false;
3694 pszName = rgtbdDesc[iTb].m_rgpchFileName[side];
3695 if (NULL == rgtbdDesc[iTb].m_rgpbRead[side])
3696 {
3697 rgtbdDesc[iTb].m_rgpbRead[side] = PbMapFileForRead (pszName, NULL, NULL);
3698 if (fVerbose)
3699 printf ("%s mapped\n", pszName);
3700 }
3701 return true;
3702 }
3703
3704 // Map whole file into memory
3705
FMapTableToMemory(int iTb,color side,HANDLE * phFile,HANDLE * phFileMapping)3706 int FMapTableToMemory
3707 (
3708 int iTb, // IN | Tablebase
3709 color side, // IN | Side to move
3710 HANDLE *phFile, // OUT | File handle will be written here
3711 HANDLE *phFileMapping // OUT | File mapping handle will be written here
3712 )
3713 {
3714 char *pszName;
3715
3716 if (!FRegistered (iTb, side))
3717 return false;
3718 pszName = rgtbdDesc[iTb].m_rgpchFileName[side];
3719 if (NULL == rgtbdDesc[iTb].m_rgpbRead[side])
3720 {
3721 rgtbdDesc[iTb].m_rgpbRead[side] = PbMapFileForRead (pszName, phFile, phFileMapping);
3722 if (fVerbose)
3723 printf ("%s mapped\n", pszName);
3724 }
3725 return true;
3726 }
3727
3728 // Unmap whole file from memory
3729
FUnMapTableFromMemory(int iTb,color side,HANDLE hFile,HANDLE hFileMapping)3730 int FUnMapTableFromMemory
3731 (
3732 int iTb, // IN | Tablebase
3733 color side, // IN | Side to move
3734 HANDLE hFile, // IN | File handle will be written here
3735 HANDLE hFileMapping // IN | File mapping handle will be written here
3736 )
3737 {
3738 char *pszName;
3739
3740 if (!FRegistered (iTb, side))
3741 return false;
3742 pszName = rgtbdDesc[iTb].m_rgpchFileName[side];
3743 if (NULL != rgtbdDesc[iTb].m_rgpbRead[side])
3744 {
3745 VUnmapFile (rgtbdDesc[iTb].m_rgpbRead[side], hFile, hFileMapping);
3746 rgtbdDesc[iTb].m_rgpbRead[side] = NULL;
3747 if (fVerbose)
3748 printf ("%s unmapped\n", pszName);
3749 }
3750 return true;
3751 }
3752
3753 #endif
3754
3755 // Probe TB
3756
TbtProbeTable(int iTb,color side,INDEX indOffset)3757 static int TB_FASTCALL TbtProbeTable
3758 (
3759 int iTb,
3760 color side,
3761 INDEX indOffset
3762 )
3763 {
3764 CTbDesc *ptbd;
3765 int iDirectory;
3766 volatile CTbCache *ptbc;
3767 volatile CTbCache *ptbcTbFirst;
3768
3769 assert (iTb > 0 && iTb < cTb);
3770 ptbd = & rgtbdDesc[iTb];
3771
3772 #if defined (NEW)
3773 // If we know TB size, it's better for offset be smaller
3774 assert (!FRegistered (iTb, side) || indOffset < ptbd->m_rgcbLength[side]);
3775 #endif
3776
3777 // Entire file read/mapped to memory?
3778 if (NULL != ptbd->m_rgpbRead[side])
3779 return (tb_t) ptbd->m_rgpbRead[side][indOffset];
3780
3781 // Cache initialized? TB registered?
3782 if (0 == ctbcTbCache || NULL == ptbd->m_prgtbcbBuckets[side])
3783 return bev_broken;
3784
3785 // Calculate cache bucket
3786 iDirectory = TB_DIRECTORY_ENTRY (indOffset);
3787
3788 // Head of the cache bucket LRU list
3789 Lock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock);
3790 ptbcTbFirst = ptbd->m_prgtbcbBuckets[side][iDirectory].m_ptbcFirst;
3791
3792 // First, search entry in the cache
3793 for (ptbc = ptbcTbFirst; NULL != ptbc; ptbc = ptbc->m_ptbcTbNext)
3794 {
3795 if ((indOffset >= ptbc->m_indStart) && (indOffset < ptbc->m_indStart + TB_CB_CACHE_CHUNK))
3796 {
3797 // Found - move cache entry to the head of the general LRU list
3798 Lock (lockLRU);
3799 if (ptbc != ptbcHead)
3800 {
3801 // Remove it from its current position
3802 ptbc->m_ptbcPrev->m_ptbcNext = ptbc->m_ptbcNext;
3803 if (NULL == ptbc->m_ptbcNext)
3804 ptbcTail = ptbc->m_ptbcPrev;
3805 else
3806 ptbc->m_ptbcNext->m_ptbcPrev = ptbc->m_ptbcPrev;
3807 // Insert it at the head
3808 ptbc->m_ptbcPrev = NULL;
3809 ptbc->m_ptbcNext = ptbcHead;
3810 ptbcHead->m_ptbcPrev = ptbc;
3811 ptbcHead = ptbc;
3812 }
3813 UnLock (lockLRU);
3814 // Move cache entry to the head of the cache bucket LRU list
3815 if (ptbc != ptbcTbFirst)
3816 {
3817 // Remove it from list
3818 ptbc->m_ptbcTbPrev->m_ptbcTbNext = ptbc->m_ptbcTbNext;
3819 if (NULL != ptbc->m_ptbcTbNext)
3820 ptbc->m_ptbcTbNext->m_ptbcTbPrev = ptbc->m_ptbcTbPrev;
3821 // Insert it at head
3822 ptbc->m_ptbcTbPrev = NULL;
3823 ptbc->m_ptbcTbNext = ptbcTbFirst;
3824 ptbcTbFirst->m_ptbcTbPrev = ptbc;
3825 ptbd->m_prgtbcbBuckets[side][iDirectory].m_ptbcFirst = ptbc;
3826 }
3827 int tb;
3828
3829 tb = (tb_t) (ptbc->m_pbData[(ULONG)(indOffset-ptbc->m_indStart)]);
3830 UnLock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock);
3831 return tb;
3832 }
3833 }
3834 // Not in the cache - have to read it from disk.
3835 // I decided to write simple code - so sometimes it's possible that
3836 // 2 threads will simultaneously read exactly the same chunk into 2
3837 // different cache entries. In that case, all subsequent cache probes
3838 // will hit the first cache entry, so the second one will 'drift' to
3839 // the end of general LRU list and will be reused.
3840
3841 // Unlock cache bucket, so other threads can continue execution
3842 UnLock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock);
3843 // First, find cache entry we can use
3844 Lock (lockLRU);
3845 // Get it either from a free list, or reuse last element of the LRU list
3846 if (NULL != ptbcFree)
3847 {
3848 ptbc = ptbcFree;
3849 ptbcFree = ptbc->m_ptbcNext;
3850 UnLock (lockLRU);
3851 }
3852 else
3853 {
3854 int iTailDirectory;
3855 int iTailTb;
3856 color colorTail;
3857
3858 assert (NULL != ptbcTail);
3859 #if defined (SMP)
3860 // "Optimistic" model - assuming that there is low content
3861 // (not hundreds of threads)
3862 for (;;)
3863 {
3864 ptbc = ptbcTail;
3865 iTailTb = ptbc->m_iTb;
3866 iTailDirectory = TB_DIRECTORY_ENTRY (ptbc->m_indStart);
3867 colorTail = ptbc->m_color;
3868 // To avoid deadlocks, have to first acquire cache buckets lock,
3869 // and only then general LRU lock. So, free general LRU lock and
3870 // acquire 2 locks in a proper order.
3871 UnLock (lockLRU);
3872 Lock (rgtbdDesc[iTailTb].m_prgtbcbBuckets[colorTail][iTailDirectory].m_lock);
3873 Lock (lockLRU);
3874 // Have structures been modified while we re-acquired locks?
3875 // (to be more precise, it's Ok, if structures were modified,
3876 // but cache entry again become the last element of the list,
3877 // and TB, color, and cache bucket did not changed, so we locked
3878 // proper locks).
3879 if (ptbc == ptbcTail && ptbc->m_iTb == iTailTb &&
3880 ptbc->m_color == colorTail &&
3881 TB_DIRECTORY_ENTRY (ptbc->m_indStart) == iTailDirectory)
3882 break;
3883 // Sorry - try once again...
3884 UnLock (rgtbdDesc[iTailTb].m_prgtbcbBuckets[colorTail][iTailDirectory].m_lock);
3885 }
3886 #else
3887 ptbc = ptbcTail;
3888 iTailTb = ptbc->m_iTb;
3889 iTailDirectory = TB_DIRECTORY_ENTRY (ptbc->m_indStart);
3890 colorTail = ptbc->m_color;
3891 #endif
3892
3893 // Remove cache entry from the general LRU list
3894 ptbcTail = ptbc->m_ptbcPrev;
3895 if (NULL == ptbcTail)
3896 ptbcHead = NULL;
3897 else
3898 ptbcTail->m_ptbcNext = NULL;
3899 UnLock (lockLRU);
3900
3901 // Remove it from cache bucket list
3902 if (NULL != ptbc->m_ptbcTbNext)
3903 ptbc->m_ptbcTbNext->m_ptbcTbPrev = ptbc->m_ptbcTbPrev;
3904 if (NULL == ptbc->m_ptbcTbPrev)
3905 rgtbdDesc[iTailTb].m_prgtbcbBuckets[colorTail][iTailDirectory].m_ptbcFirst = ptbc->m_ptbcTbNext;
3906 else
3907 ptbc->m_ptbcTbPrev->m_ptbcTbNext = ptbc->m_ptbcTbNext;
3908 UnLock (rgtbdDesc[iTailTb].m_prgtbcbBuckets[colorTail][iTailDirectory].m_lock);
3909 }
3910
3911 // Ok, now we have "orphan" cache entry - it's excluded from all lists,
3912 // so other threads will never touch it.
3913 ptbc->m_iTb = iTb;
3914 ptbc->m_color = side;
3915 ptbc->m_indStart = indOffset / (INDEX) (TB_CB_CACHE_CHUNK) * TB_CB_CACHE_CHUNK;
3916
3917 // Now read it from the disk
3918 FILE *fp;
3919 size_t cb;
3920
3921 // First, check: is necessary file opened?
3922 // As files are not thread-safe, lock file
3923 Lock (ptbd->m_rglockFiles[side]);
3924 fp = ptbd->m_rgfpFiles[side];
3925 if (NULL == fp)
3926 {
3927 // Not - try to open it
3928 fp = fopen (ptbd->m_rgpchFileName[side], "rb");
3929 if (NULL == fp)
3930 {
3931 // Failed. Close all the opened files and retry
3932 UnLock (ptbd->m_rglockFiles[side]);
3933 VTbCloseFiles ();
3934 Lock (ptbd->m_rglockFiles[side]);
3935 // Theoretically, it's possible that other threads opened a lot of
3936 // files in the interval between VTbCloseFiles() and Lock(). If
3937 // so, we'll fail - I don't like to have one more global lock
3938 // especially for file open, at least not in first version.
3939 // Problem can happen only on systems with small limit of
3940 // simultaneously open files and high number of threads - unlikely
3941 // combination.
3942 fp = ptbd->m_rgfpFiles[side];
3943 if (NULL == fp)
3944 {
3945 fp = fopen (ptbd->m_rgpchFileName[side], "rb");
3946 if (NULL == fp)
3947 goto ERROR_LABEL;
3948 }
3949 }
3950 ptbd->m_rgfpFiles[side] = fp;
3951 }
3952
3953 // File opened. Now seek and read necessary chunk
3954 if (NULL == ptbd->m_rgpdiDecodeInfo[side])
3955 {
3956 // Read uncompressed file
3957 if (fseek (fp, (long) ptbc->m_indStart, SEEK_SET))
3958 goto ERROR_LABEL;
3959 cb = fread (ptbc->m_pbData, 1, TB_CB_CACHE_CHUNK, fp);
3960 if (cb != TB_CB_CACHE_CHUNK && ferror (fp))
3961 goto ERROR_LABEL;
3962 assert (cb > (indOffset-ptbc->m_indStart));
3963 UnLock (ptbd->m_rglockFiles[side]);
3964 }
3965 else
3966 {
3967 // Read compressed file
3968 int fWasError;
3969 decode_block *block;
3970 decode_info *info = ptbd->m_rgpdiDecodeInfo[side];
3971
3972 #if defined (SMP)
3973 // Find free decode block
3974 decode_block **pBlock;
3975
3976 Lock (lockDecode);
3977 pBlock = rgpdbDecodeBlocks;
3978 while (NULL == *pBlock)
3979 pBlock ++;
3980 block = *pBlock;
3981 *pBlock = NULL;
3982 UnLock (lockDecode);
3983 #else
3984 block = rgpdbDecodeBlocks[0];
3985 #endif
3986
3987 // Initialize decode block and read chunk
3988 fWasError = 0 != comp_init_block (block, TB_CB_CACHE_CHUNK, ptbc->m_pbData) ||
3989 0 != comp_read_block (block, info, fp, indOffset / TB_CB_CACHE_CHUNK);
3990
3991 // Release lock on file, so other threads can proceed with that file
3992 UnLock (ptbd->m_rglockFiles[side]);
3993
3994 // Decompress chunk
3995 if (!fWasError)
3996 fWasError |= (0 != comp_decode_and_check_crc (block, info, block->orig.size, TB_CRC_CHECK));
3997
3998 // Release block
3999 #if defined (SMP)
4000 Lock (lockDecode);
4001 *pBlock = block;
4002 UnLock (lockDecode);
4003 #endif
4004
4005 // Read Ok?
4006 if (fWasError)
4007 goto ERROR_LABEL_2;
4008 }
4009
4010 // Read - now acquire locks and insert cache entry in both lists
4011 Lock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock);
4012 Lock (lockLRU);
4013
4014 // Insert cache entry into general LRU list
4015 ptbc->m_ptbcPrev = NULL;
4016 ptbc->m_ptbcNext = ptbcHead;
4017 if (NULL == ptbcHead)
4018 ptbcTail = ptbc;
4019 else
4020 ptbcHead->m_ptbcPrev = ptbc;
4021 ptbcHead = ptbc;
4022
4023 // Insert cache entry into cache bucket LRU list
4024 ptbc->m_ptbcTbPrev = NULL;
4025 ptbc->m_ptbcTbNext = ptbd->m_prgtbcbBuckets[side][iDirectory].m_ptbcFirst;
4026 if (NULL != ptbc->m_ptbcTbNext)
4027 ptbc->m_ptbcTbNext->m_ptbcTbPrev = ptbc;
4028 ptbd->m_prgtbcbBuckets[side][iDirectory].m_ptbcFirst = ptbc;
4029
4030 // All done
4031 int tb;
4032
4033 tb = (tb_t) (ptbc->m_pbData[(ULONG)(indOffset-ptbc->m_indStart)]);
4034 // Release locks
4035 UnLock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock);
4036 UnLock (lockLRU);
4037 return tb;
4038
4039 // I/O error. Here I don't want to halt the program, because that can
4040 // happen in the middle of the important game. Just return failure.
4041 ERROR_LABEL:
4042 UnLock (ptbd->m_rglockFiles[side]);
4043 ERROR_LABEL_2:
4044 Lock (lockLRU);
4045 ptbd->m_rgpchFileName[side] = NULL;
4046 ptbc->m_ptbcNext = ptbcFree;
4047 ptbcFree = ptbc;
4048 UnLock (lockLRU);
4049 return bev_broken;
4050 }
4051
4052 // 16-bit version (recommended)
4053
L_TbtProbeTable(int iTb,color side,INDEX indOffset)4054 extern "C" int TB_FASTCALL L_TbtProbeTable
4055 (
4056 int iTb,
4057 color side,
4058 INDEX indOffset
4059 )
4060 {
4061 int tbtScore;
4062
4063 #if !defined (KPPKP_16BIT)
4064 if (tbid_kppkp == iTb && x_colorBlack == side &&
4065 (indOffset == 0x0362BC7C || indOffset == 0x0362DE44 || indOffset == 0x03637648 ||
4066 indOffset == 0x03639810 || indOffset == 0x038D4F29 || indOffset == 0x040A2CAB ||
4067 indOffset == 0x043C778C))
4068 return -32639;
4069 tbtScore = TbtProbeTable (iTb, side, indOffset);
4070 tbtScore = S_to_L (tbtScore);
4071 #else
4072 if (tbid_kppkp != iTb)
4073 {
4074 // All tables but kppkp are 8-bit tables
4075 tbtScore = TbtProbeTable (iTb, side, indOffset);
4076 tbtScore = S_to_L (tbtScore);
4077 }
4078 else
4079 {
4080 // Special handling of kppkp - it's 16-bit table
4081 // Inefficient, but very simple, code
4082 int iLo;
4083 int iHi;
4084
4085 indOffset *= 2;
4086 iLo = TbtProbeTable (iTb, side, indOffset);
4087 iHi = TbtProbeTable (iTb, side, indOffset+1);
4088 tbtScore = (bev_broken == iHi) ? L_bev_broken : (iHi << 8) + (iLo & 0xFF);
4089 }
4090 #endif
4091 return tbtScore;
4092 }
4093
4094 //-----------------------------------------------------------------------------
4095 //
4096 // Global initialization
4097
FCheckExistence(char * pszPath,int iTb,color side)4098 int FCheckExistence
4099 (
4100 char *pszPath,
4101 int iTb,
4102 color side
4103 )
4104 {
4105 FILE *fp;
4106 char *pchCopy;
4107 const char *pchExt = PchExt (side);
4108 char rgchTbName[256];
4109 CTbCacheBucket *prgtbcbBuckets;
4110 INDEX cb;
4111 decode_info *comp_info = NULL;
4112
4113 if (FRegistered (iTb, side) || NULL != rgtbdDesc[iTb].m_rgpbRead[side])
4114 return true;
4115
4116 strcpy (rgchTbName, pszPath);
4117 if (0 != pszPath[0])
4118 {
4119 #if defined (_WIN32)
4120 strcat (rgchTbName, "\\");
4121 #elif defined (__MWERKS__)
4122 strcat (rgchTbName, ":");
4123 #else
4124 strcat (rgchTbName, "/");
4125 #endif
4126 }
4127 strcat (rgchTbName, rgtbdDesc[iTb].m_rgchName);
4128 strcat (rgchTbName, pchExt);
4129 fp = fopen (rgchTbName, "rb");
4130 #if !defined (NEW) && !defined (_WIN32)
4131 // For case-sensitive systems, have to try once more
4132 if (NULL == fp)
4133 {
4134 for (int i = strchr(rgchTbName,'.')-rgchTbName-1; i>=0 && isalpha(rgchTbName[i]); i--)
4135 rgchTbName[i] = toupper (rgchTbName[i]);
4136 fp = fopen (rgchTbName, "rb");
4137 }
4138 #endif
4139 if (NULL != fp)
4140 {
4141 // Found uncompressed table
4142 if (0 != fseek (fp, 0L, SEEK_END))
4143 {
4144 printf ("*** Seek in %s failed\n", rgchTbName);
4145 exit (1);
4146 }
4147 cb = (INDEX) ftell (fp);
4148 #if defined (NEW)
4149 if (0 != rgtbdDesc[iTb].m_rgcbLength[side] && cb != rgtbdDesc[iTb].m_rgcbLength[side])
4150 {
4151 printf ("*** %s corrupted\n", rgchTbName);
4152 exit (1);
4153 }
4154 #endif
4155 }
4156 else
4157 {
4158 // Check for compressed table.
4159 // First, check for kxykz.nb?.emd
4160 strcat (rgchTbName, ".emd");
4161 fp = fopen (rgchTbName, "rb");
4162 if (NULL == fp)
4163 {
4164 // Check for kxykznb?.emd (8+3 format)
4165 int cch;
4166
4167 cch = strlen (rgchTbName);
4168 memmove (rgchTbName+cch-8, rgchTbName+cch-7, 8);
4169 fp = fopen (rgchTbName, "rb");
4170 if (NULL == fp)
4171 return false;
4172 }
4173 cCompressed ++;
4174 int iResult = comp_open_file (&comp_info, fp, TB_CRC_CHECK);
4175 if (0 != iResult)
4176 {
4177 printf ("*** Unable to read %s - ", rgchTbName);
4178 switch (iResult & 0xFF)
4179 {
4180 case COMP_ERR_READ:
4181 printf ("read error\n");
4182 break;
4183 case COMP_ERR_NOMEM:
4184 printf ("out of memory\n");
4185 break;
4186 case COMP_ERR_BROKEN:
4187 printf ("file broken\n");
4188 break;
4189 default:
4190 printf ("error %d\n", iResult);
4191 break;
4192 }
4193 exit (1);
4194 }
4195 if (comp_info->block_size != TB_CB_CACHE_CHUNK)
4196 {
4197 printf ("*** %s: Unsupported block size %d\n", rgchTbName, comp_info->block_size);
4198 exit (1);
4199 }
4200 cb = comp_info->block_size*(comp_info->n_blk-1) + comp_info->last_block_size;
4201 #if defined (NEW)
4202 if (0 != rgtbdDesc[iTb].m_rgcbLength[side] && cb != rgtbdDesc[iTb].m_rgcbLength[side])
4203 {
4204 printf ("*** %s corrupted\n", rgchTbName);
4205 exit (1);
4206 }
4207 #endif
4208 }
4209 rgtbdDesc[iTb].m_rgcbLength[side] = cb;
4210 fclose (fp);
4211 if (FRegisterTb (& (rgtbdDesc[iTb])))
4212 {
4213 pchCopy = (char*) PvMalloc (strlen(rgchTbName)+1);
4214 strcpy (pchCopy, rgchTbName);
4215 rgtbdDesc[iTb].m_rgpchFileName[side] = pchCopy;
4216 prgtbcbBuckets = (CTbCacheBucket*) PvMalloc (TB_DIRECTORY_SIZE*sizeof(CTbCacheBucket));
4217 memset (prgtbcbBuckets, 0, TB_DIRECTORY_SIZE*sizeof(CTbCacheBucket));
4218 #if defined (SMP)
4219 for (int i = 0; i < TB_DIRECTORY_SIZE; i ++)
4220 LockInit (prgtbcbBuckets[i].m_lock);
4221 #endif
4222 rgtbdDesc[iTb].m_prgtbcbBuckets[side] = prgtbcbBuckets;
4223 rgtbdDesc[iTb].m_rgpdiDecodeInfo[side] = comp_info;
4224 if (fVerbose)
4225 printf ("%s registered\n", pchCopy);
4226 return true;
4227 }
4228 else
4229 {
4230 printf ("*** Unable to register %s\n", rgchTbName);
4231 exit (1);
4232 }
4233 return false;
4234 }
4235
IInitializeTb(char * pszPath)4236 extern "C" int IInitializeTb
4237 (
4238 char *pszPath
4239 )
4240 {
4241 char szTemp[1024];
4242 color sd;
4243 int iTb, iMaxTb, i;
4244
4245 cbAllocated = cbEGTBCompBytes = 0;
4246 // If there are open files, close those
4247 VTbCloseFiles ();
4248 #if defined (SMP)
4249 // Init all locks
4250 LockInit (lockLRU);
4251 LockInit (LockDecode);
4252 for (iTb = 1; iTb < cTb; iTb ++)
4253 {
4254 LockInit (rgtbdDesc[iTb].m_rglockFiles[x_colorWhite]);
4255 LockInit (rgtbdDesc[iTb].m_rglockFiles[x_colorBlack]);
4256 }
4257 #endif
4258 #if defined (NEW)
4259 // Create enumeration tables
4260 VInitEnumerations ();
4261 #endif
4262 // Create empty TB search table
4263 VCreateEmptyTbTable ();
4264 // Free memory from TB table
4265 for (iTb = 1; iTb < cTb; iTb ++)
4266 {
4267 for (sd = x_colorWhite; sd <= x_colorBlack; sd = (color) (sd + 1))
4268 {
4269 if (NULL != rgtbdDesc[iTb].m_prgtbcbBuckets[sd] &&
4270 NULL == rgtbdDesc[iTb].m_rgpbRead[sd])
4271 {
4272 #ifdef WINCE
4273 my_Tcl_Free ((char*)rgtbdDesc[iTb].m_prgtbcbBuckets[sd]);
4274 #else
4275 free (rgtbdDesc[iTb].m_prgtbcbBuckets[sd]);
4276 #endif
4277 rgtbdDesc[iTb].m_prgtbcbBuckets[sd] = NULL;
4278 }
4279 if (NULL != rgtbdDesc[iTb].m_rgpchFileName[sd])
4280 {
4281 #ifdef WINCE
4282 my_Tcl_Free ((char*)rgtbdDesc[iTb].m_rgpchFileName[sd]);
4283 #else
4284 free (rgtbdDesc[iTb].m_rgpchFileName[sd]);
4285 #endif
4286 rgtbdDesc[iTb].m_rgpchFileName[sd] = NULL;
4287 }
4288 if (NULL != rgtbdDesc[iTb].m_rgpdiDecodeInfo[sd])
4289 {
4290 #ifdef WINCE
4291 my_Tcl_Free ((char*)rgtbdDesc[iTb].m_rgpdiDecodeInfo[sd]);
4292 #else
4293 free (rgtbdDesc[iTb].m_rgpdiDecodeInfo[sd]);
4294 #endif
4295 rgtbdDesc[iTb].m_rgpdiDecodeInfo[sd] = NULL;
4296 }
4297 }
4298 }
4299 // Free compressed blocks
4300 for (i = 0; i < CPUS; i ++)
4301 {
4302 if (NULL != rgpdbDecodeBlocks[i])
4303 {
4304 #ifdef WINCE
4305 my_Tcl_Free ((char*)rgpdbDecodeBlocks[i]);
4306 #else
4307 free (rgpdbDecodeBlocks[i]);
4308 #endif
4309 rgpdbDecodeBlocks[i] = NULL;
4310 }
4311 }
4312 // Search for existing TBs
4313 iMaxTb = 0;
4314 for (;;)
4315 {
4316 for (i = 0; pszPath[i] != '\0' && pszPath[i] != ',' && pszPath[i] != ';'
4317 #if !defined (_WIN32) && !defined (__MWERKS__)
4318 && pszPath[i] != ':'
4319 #endif
4320 ; i ++)
4321 {
4322 szTemp[i] = pszPath[i];
4323 }
4324 szTemp[i] = '\0';
4325 for (iTb = 1; iTb < cTb; iTb ++)
4326 {
4327 if (FCheckExistence (szTemp, iTb, x_colorWhite))
4328 {
4329 if (iTb > iMaxTb)
4330 iMaxTb = iTb;
4331 }
4332 if (FCheckExistence (szTemp, iTb, x_colorBlack))
4333 {
4334 if (iTb > iMaxTb)
4335 iMaxTb = iTb;
4336 }
4337 }
4338 pszPath += i;
4339 if ('\0' == *pszPath)
4340 break;
4341 pszPath ++;
4342 }
4343
4344 // If there were compressed files, have to allocate buffer(s)
4345 if (0 != cCompressed)
4346 {
4347 for (i = 0; i < CPUS; i ++)
4348 {
4349 int iResult = comp_alloc_block (&rgpdbDecodeBlocks[i], TB_CB_CACHE_CHUNK);
4350 if (0 != iResult)
4351 {
4352 printf ("*** Cannot allocate decode block: error code %d\n", iResult);
4353 exit (1);
4354 }
4355 }
4356 if (fVerbose)
4357 printf ("Allocated %dKb for decompression tables, indices, and buffers.\n",
4358 (cbEGTBCompBytes+1023)/1024);
4359 }
4360
4361 // All done!
4362 if (iMaxTb >= tbid_kppkp)
4363 return 5;
4364 else if (iMaxTb >= tbid_kpkp)
4365 return 4;
4366 else if (iMaxTb >= tbid_kpk)
4367 return 3;
4368 return 0;
4369 }
4370
4371 #endif
4372