Update codebase to remove clang warnings (and a couple of legit errors
[typhoon.git] / src / egtb.cpp
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <ctype.h>
5 #if defined(_WIN32)
6 #include <windows.h>
7 #endif
8
9 #define NEW
10 #define T41_INCLUDE
11 #define T42_INCLUDE
12 #define T33_INCLUDE
13 #define T_INDEX64
14 #define  XX  127
15
16 #if !defined(SMP) && !defined(SUN)
17 #define  lock_t int
18 #endif
19
20 #if defined (T_INDEX64) && defined (_MSC_VER)
21 typedef unsigned __int64 INDEX;
22 #elif defined (T_INDEX64)
23 typedef unsigned long long INDEX;
24 #else
25 typedef unsigned long INDEX;
26 #endif
27
28 typedef unsigned int square;
29
30 typedef int color;
31
32 #define  x_colorWhite    0
33 #define  x_colorBlack    1
34 #define  x_colorNeutral  2
35
36 typedef int piece;
37
38 #define  x_pieceNone     0
39 #define  x_piecePawn     1
40 #define  x_pieceKnight   2
41 #define  x_pieceBishop   3
42 #define  x_pieceRook     4
43 #define  x_pieceQueen    5
44 #define  x_pieceKing     6
45
46 /*
47    Macro that fetches positions of pieces
48  */
49
50 #define  C_PIECES  3    /* Maximum # of pieces of one color OTB */
51
52 #define  SqFindKing(psq)       (psq[C_PIECES*(x_pieceKing-1)])
53 #define  SqFindOne(psq, pi)    (psq[C_PIECES*(pi-1)])
54 #define  SqFindFirst(psq, pi)  (psq[C_PIECES*(pi-1)])
55 #define  SqFindSecond(psq, pi) (psq[C_PIECES*(pi-1)+1])
56 #define  SqFindThird(psq, pi)  (psq[C_PIECES*(pi-1)+2])
57
58 #include "lock.h"
59
60 /*
61    All defined, now include probing code
62  */
63
64 /* -------------------------------------------------------------------- */
65 /*                                                                      */
66 /*              Probe chess endgame database ("tablebase")              */
67 /*                                                                      */
68 /*               Copyright (c) 1998--2001 Eugene Nalimov                */
69 /*                                                                      */
70 /* The code listed below should not be used in any product (software or */
71 /* hardware,  commercial or not,  and so on) without written permission */
72 /* from the author.                                                     */
73 /*                                                                      */
74 /* -------------------------------------------------------------------- */
75
76 #if defined (_WIN32) || defined(_WIN64)
77 #  include <windows.h>
78 #endif
79
80 #include <string.h>
81 #include <stdlib.h>
82 #include <stdio.h>
83 #if !defined (DEBUG) && !defined(NDEBUG)
84 #  define   NDEBUG
85 #endif
86 #include <assert.h>
87
88 // SMP stuff
89
90 #if defined (CPUS) && !defined (SMP) && (CPUS > 1)
91 #  error Cannot use CPUS > 1 without SMP defined
92 #endif
93
94 static  lock_t  lockLRU;
95
96 // Declarations
97
98 typedef unsigned    char BYTE;
99 typedef unsigned    long ULONG;
100 typedef signed      char tb_t;
101
102 #if !defined (COLOR_DECLARED)
103 typedef int color;
104 #  define   x_colorWhite    0
105 #  define   x_colorBlack    1
106 #  define   x_colorNeutral  2
107 #  define COLOR_DECLARED
108 #endif
109
110 #if !defined (PIECES_DECLARED)
111 typedef int piece;
112 #  define   x_pieceNone     0
113 #  define   x_piecePawn     1
114 #  define   x_pieceKnight   2
115 #  define   x_pieceBishop   3
116 #  define   x_pieceRook     4
117 #  define   x_pieceQueen    5
118 #  define   x_pieceKing     6
119 #  define PIECES_DECLARED
120 #endif
121
122 #if !defined (SqFind2)
123 #  define   SqFind2(psq,pi1,sq1,pi2,sq2)    sq1=SqFindFirst(psq,pi1);sq2=SqFindFirst(psq,pi2);
124 #endif
125
126 // Machine and compiler-specific declarations
127
128 #if defined (_MSC_VER)
129
130 #  undef    TB_CDECL
131 #  define   TB_CDECL    __cdecl
132 #  define   TB_FASTCALL __fastcall
133 #  if _MSC_VER >= 1200
134 #    define INLINE      __forceinline
135 #  endif
136
137 #else
138
139 #  define   TB_CDECL
140 #  define   TB_FASTCALL
141
142 #endif
143
144 #if !defined (INLINE)
145 #  define   INLINE  inline
146 #endif
147
148 // Printf formats
149
150 #if defined (T_INDEX64) && defined (_MSC_VER)
151 #   define HEX_INDEX_FORMAT "%016I64X"
152 #   define DEC_INDEX_FORMAT "%I64u"
153 #elif defined (T_INDEX64)
154 #   define HEX_INDEX_FORMAT "%016llX"
155 #   define DEC_INDEX_FORMAT "%llu"
156 #else
157 #   define HEX_INDEX_FORMAT "%08X"
158 #   define DEC_INDEX_FORMAT "%lu"
159 #endif
160
161 // Directory delimiter
162
163 #if defined (_WIN32) || defined(_WIN64)
164 #   define DELIMITER   "\\"
165 #elif defined (__MWERKS__)
166 #   define DELIMITER   ":"
167 #else
168 #   define DELIMITER   "/"
169 #endif
170
171
172 // Some constants from SJE program
173
174 #define pageL 256
175
176 /* tablebase byte entry semispan length */
177
178 #define tbbe_ssL ((pageL - 4) / 2)
179
180 /* tablebase signed byte entry values */
181
182 #define bev_broken  (tbbe_ssL + 1)  /* illegal or busted */
183
184 #define bev_mi1     tbbe_ssL        /* mate in 1 move */
185 #define bev_mimin   1               /* mate in 126 moves */
186
187 #define bev_draw    0               /* draw */
188
189 #define bev_limax   (-1)            /* mated in 125 moves */
190 #define bev_li0     (-tbbe_ssL)     /* mated in 0 moves */
191
192 #define bev_limaxx  (-tbbe_ssL - 1) /* mated in 126 moves */
193 #define bev_miminx  (-tbbe_ssL - 2) /* mate in 127 moves */
194
195 // Some constants for 16-bit tables
196
197 #define L_pageL 65536
198
199 /* tablebase short entry semispan length */
200
201 #define L_tbbe_ssL ((L_pageL - 4) / 2)
202
203 /* tablebase signed short entry values */
204
205 #define L_bev_broken  (L_tbbe_ssL + 1)      /* illegal or busted */
206
207 #define L_bev_mi1     L_tbbe_ssL            /* mate in 1 move */
208 #define L_bev_mimin   1                     /* mate in 32766 moves */
209
210 #define L_bev_draw    0                     /* draw */
211
212 #define L_bev_limax   (-1)                  /* mated in 32765 moves */
213 #define L_bev_li0     (-L_tbbe_ssL)         /* mated in 0 moves */
214
215 #define L_bev_limaxx    (-L_tbbe_ssL - 1)   /* mated in 32766 moves */
216 #define L_bev_miminx    (-L_tbbe_ssL - 2)   /* mate in 32767 moves */
217
218 // Convertion from 8-bit to 16-bit score
219 // UNDONE: Maybe implement via lookup table?
220
221 #define S_to_L(tbt)\
222     (\
223      (0 == tbt) ? 0:\
224      (tbt > 0) ? (bev_broken != tbt ? tbt + 32640 : L_bev_broken):\
225      (tbt >= bev_li0) ? tbt - 32640:\
226      (bev_limaxx == tbt) ? -32640:\
227      /*bev_miminx == tbt*/  32640\
228     )
229
230 // Constants
231
232 #define i8  ((unsigned) 8)
233 #define i14 ((unsigned) 14)
234 #define i42 ((unsigned) 42)
235 #define i43 ((unsigned) 43)
236 #define i44 ((unsigned) 44)
237 #define i45 ((unsigned) 45)
238 #define i46 ((unsigned) 46)
239 #define i47 ((unsigned) 47)
240 #define i48 ((unsigned) 48)
241 #define i57 ((unsigned) 57)
242 #define i58 ((unsigned) 58)
243 #define i59 ((unsigned) 59)
244 #define i60 ((unsigned) 60)
245 #define i61 ((unsigned) 61)
246 #define i62 ((unsigned) 62)
247 #define i63 ((unsigned) 63)
248 #define i64 ((unsigned) 64)
249
250 #define x_row_1 0
251 #define x_row_2 1
252 #define x_row_3 2
253 #define x_row_4 3
254 #define x_row_5 4
255 #define x_row_6 5
256 #define x_row_7 6
257 #define x_row_8 7
258
259 #define x_column_a 0
260 #define x_column_b 1
261 #define x_column_c 2
262 #define x_column_d 3
263 #define x_column_e 4
264 #define x_column_f 5
265 #define x_column_g 6
266 #define x_column_h 7
267
268 /* reflection macros */
269
270 #define reflect_x(sq) ((sq) ^ 0x38)
271 #define reflect_y(sq) ((sq) ^ 0x07)
272 #define reflect_xy(sq) rgsqReflectXY[sq]
273
274 static const square rgsqReflectXY [] =
275 {
276   0,  8, 16, 24, 32, 40, 48, 56,
277   1,  9, 17, 25, 33, 41, 49, 57,
278   2, 10, 18, 26, 34, 42, 50, 58,
279   3, 11, 19, 27, 35, 43, 51, 59,
280   4, 12, 20, 28, 36, 44, 52, 60,
281   5, 13, 21, 29, 37, 45, 53, 61,
282   6, 14, 22, 30, 38, 46, 54, 62,
283   7, 15, 23, 31, 39, 47, 55, 63,
284 };
285
286 static const square rgsqReflectMaskY [] =
287 {
288  0, 0, 0, 0, 7, 7, 7, 7,
289  0, 0, 0, 0, 7, 7, 7, 7,
290  0, 0, 0, 0, 7, 7, 7, 7,
291  0, 0, 0, 0, 7, 7, 7, 7,
292  0, 0, 0, 0, 7, 7, 7, 7,
293  0, 0, 0, 0, 7, 7, 7, 7,
294  0, 0, 0, 0, 7, 7, 7, 7,
295  0, 0, 0, 0, 7, 7, 7, 7,
296 };
297
298 static const square rgsqReflectMaskYandX [] =
299 {
300  0, 0, 0, 0, 7, 7, 7, 7,
301  0, 0, 0, 0, 7, 7, 7, 7,
302  0, 0, 0, 0, 7, 7, 7, 7,
303  0, 0, 0, 0, 7, 7, 7, 7,
304  0x38, 0x38, 0x38, 0x38, 0x38+7, 0x38+7, 0x38+7, 0x38+7,
305  0x38, 0x38, 0x38, 0x38, 0x38+7, 0x38+7, 0x38+7, 0x38+7,
306  0x38, 0x38, 0x38, 0x38, 0x38+7, 0x38+7, 0x38+7, 0x38+7,
307  0x38, 0x38, 0x38, 0x38, 0x38+7, 0x38+7, 0x38+7, 0x38+7,
308 };
309
310 static const square rgsqReflectInvertMask[] = { 0, 0x38 };
311
312 /* useful macros */
313
314 #define TbRow(sq)               ((sq) >> 3)
315 #define TbColumn(sq)            ((sq) & 7)
316
317 #if defined (NEW)
318 #  define   PchExt(side) ((x_colorWhite == side) ? ".nbw" : ".nbb")
319 #else
320 #  define   PchExt(side) ((x_colorWhite == side) ? ".tbw" : ".tbb")
321 #endif
322
323 // Verbose levels
324
325 static bool     fPrint = false;     // Print some technical statistics
326 static bool     fVerbose = false;   // Print additional information
327
328 // Malloc that checks for out-of-memory condition
329
330 static size_t   cbAllocated;
331 static int      cOpenFilesAttempts;
332 static int      cOpenFilesSuceed;
333
334 static void* PvMalloc
335     (
336     size_t cb
337     )
338     {
339     void    *pv;
340
341     pv = malloc (cb);
342     if (NULL == pv)
343         {
344         printf ("*** Cannot allocate %d bytes of memory\n", cb);
345         exit (1);
346         }
347     cbAllocated += cb;
348     return pv;
349     }
350
351 #if defined (NEW)   // New index schema ----------------------------------------
352
353 // 'Invalid' value have to be large, so index
354 // of invalid position will be very large, too.
355
356 #define INF 4000
357
358 // Enumeration: valid positions with 2 kings on board; white king restricted to
359 // a1-d1-d4 triangle; also, if it's at a1-d4 half-diagonal, then black king
360 // must be in a1-h1-h8 triangle
361
362 static const short rgsTriKings [64 * 64] =
363 {
364  INF, INF,   0,   1,   2,   3,   4,   5, INF, INF,   6,   7,   8,   9,  10,  11,
365  INF, INF,  12,  13,  14,  15,  16,  17, INF, INF, INF,  18,  19,  20,  21,  22,
366  INF, INF, INF, INF,  23,  24,  25,  26, INF, INF, INF, INF, INF,  27,  28,  29,
367  INF, INF, INF, INF, INF, INF,  30,  31, INF, INF, INF, INF, INF, INF, INF,  32,
368  INF, INF, INF,  33,  34,  35,  36,  37, INF, INF, INF,  38,  39,  40,  41,  42,
369   43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,
370   59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,
371   75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,
372   91, INF, INF, INF,  92,  93,  94,  95,  96, INF, INF, INF,  97,  98,  99, 100,
373  101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
374  117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,
375  133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,
376  149, 150, INF, INF, INF, 151, 152, 153, 154, 155, INF, INF, INF, 156, 157, 158,
377  159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174,
378  175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190,
379  191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206,
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, 207, 208, 209, 210, 211, INF, INF, INF, 212, 213, 214, 215, 216,
401  INF, INF, INF, 217, 218, 219, 220, 221, INF, INF, INF, 222, 223, 224, 225, 226,
402  INF, INF, INF, INF, 227, 228, 229, 230, INF, INF, INF, INF, INF, 231, 232, 233,
403  INF, INF, INF, INF, INF, INF, 234, 235, INF, INF, INF, INF, INF, INF, INF, 236,
404  237, INF, INF, INF, 238, 239, 240, 241, 242, INF, INF, INF, 243, 244, 245, 246,
405  247, INF, INF, INF, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259,
406  260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275,
407  276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291,
408  292, 293, INF, INF, INF, 294, 295, 296, 297, 298, INF, INF, INF, 299, 300, 301,
409  302, 303, INF, INF, INF, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
410  315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330,
411  331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346,
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  347, 348, 349, 350, 351, 352, 353, 354, INF, INF, INF, INF, 355, 356, 357, 358,
437  INF, INF, INF, INF, 359, 360, 361, 362, INF, INF, INF, INF, 363, 364, 365, 366,
438  INF, INF, INF, INF, 367, 368, 369, 370, INF, INF, INF, INF, INF, 371, 372, 373,
439  INF, INF, INF, INF, INF, INF, 374, 375, INF, INF, INF, INF, INF, INF, INF, 376,
440  377, 378, 379, 380, 381, 382, 383, 384, 385, 386, INF, INF, INF, 387, 388, 389,
441  390, 391, INF, INF, INF, 392, 393, 394, 395, 396, INF, INF, INF, 397, 398, 399,
442  400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415,
443  416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431,
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  432, 433, 434, 435, 436, 437, 438, 439, INF, 440, 441, 442, 443, 444, 445, 446,
473  INF, INF, INF, INF, INF, 447, 448, 449, INF, INF, INF, INF, INF, 450, 451, 452,
474  INF, INF, INF, INF, INF, 453, 454, 455, INF, INF, INF, INF, INF, 456, 457, 458,
475  INF, INF, INF, INF, INF, INF, 459, 460, INF, INF, INF, INF, INF, INF, INF, 461,
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  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
524  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
525  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
526  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
527  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
528  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
529  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
530  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
531  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
532  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
533  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
534  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
535  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
536  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
537  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
538  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
539  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
540  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
541  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
542  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
543  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
544  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
545  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
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, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
563  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
564  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
565  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
566  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
567  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
568  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
569  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
570  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
571  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
572  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
573  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
574  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
575  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
576  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
577  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
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  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
595  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
596  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
597  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
598  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
599  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
600  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
601  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
602  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
603  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
604  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
605  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
606  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
607  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
608  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
609  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
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 };
621
622 // Enumeration: all valid positions with 2 kings on board when white king
623 // restricted to left half of the board
624
625 static const short rgsHalfKings [64 * 64] =
626 {
627  INF, INF,   0,   1,   2,   3,   4,   5, INF, INF,   6,   7,   8,   9,  10,  11,
628   12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,
629   28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,
630   44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,
631  INF, INF, INF,  60,  61,  62,  63,  64, INF, INF, INF,  65,  66,  67,  68,  69,
632   70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,
633   86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99, 100, 101,
634  102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
635  118, INF, INF, INF, 119, 120, 121, 122, 123, INF, INF, INF, 124, 125, 126, 127,
636  128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
637  144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
638  160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
639  176, 177, INF, INF, INF, 178, 179, 180, 181, 182, INF, INF, INF, 183, 184, 185,
640  186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201,
641  202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217,
642  218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233,
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  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
659  INF, INF, 234, 235, 236, 237, 238, 239, INF, INF, 240, 241, 242, 243, 244, 245,
660  INF, INF, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259,
661  260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275,
662  276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291,
663  INF, INF, INF, 292, 293, 294, 295, 296, INF, INF, INF, 297, 298, 299, 300, 301,
664  INF, INF, INF, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
665  315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330,
666  331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346,
667  347, INF, INF, INF, 348, 349, 350, 351, 352, INF, INF, INF, 353, 354, 355, 356,
668  357, INF, INF, INF, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369,
669  370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385,
670  386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401,
671  402, 403, INF, INF, INF, 404, 405, 406, 407, 408, INF, INF, INF, 409, 410, 411,
672  412, 413, INF, INF, INF, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424,
673  425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440,
674  441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456,
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  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
691  457, 458, 459, 460, 461, 462, 463, 464, INF, INF, 465, 466, 467, 468, 469, 470,
692  INF, INF, 471, 472, 473, 474, 475, 476, INF, INF, 477, 478, 479, 480, 481, 482,
693  483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498,
694  499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514,
695  515, 516, 517, 518, 519, 520, 521, 522, INF, INF, INF, 523, 524, 525, 526, 527,
696  INF, INF, INF, 528, 529, 530, 531, 532, INF, INF, INF, 533, 534, 535, 536, 537,
697  538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553,
698  554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569,
699  570, 571, 572, 573, 574, 575, 576, 577, 578, INF, INF, INF, 579, 580, 581, 582,
700  583, INF, INF, INF, 584, 585, 586, 587, 588, INF, INF, INF, 589, 590, 591, 592,
701  593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608,
702  609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624,
703  625, 626, 627, 628, 629, 630, 631, 632, 633, 634, INF, INF, INF, 635, 636, 637,
704  638, 639, INF, INF, INF, 640, 641, 642, 643, 644, INF, INF, INF, 645, 646, 647,
705  648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663,
706  664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679,
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  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
723  680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695,
724  INF, INF, 696, 697, 698, 699, 700, 701, INF, INF, 702, 703, 704, 705, 706, 707,
725  INF, INF, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721,
726  722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737,
727  738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753,
728  INF, INF, INF, 754, 755, 756, 757, 758, INF, INF, INF, 759, 760, 761, 762, 763,
729  INF, INF, INF, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776,
730  777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792,
731  793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808,
732  809, INF, INF, INF, 810, 811, 812, 813, 814, INF, INF, INF, 815, 816, 817, 818,
733  819, INF, INF, INF, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831,
734  832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847,
735  848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863,
736  864, 865, INF, INF, INF, 866, 867, 868, 869, 870, INF, INF, INF, 871, 872, 873,
737  874, 875, INF, INF, INF, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886,
738  887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902,
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  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
755  903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918,
756  919, 920, 921, 922, 923, 924, 925, 926, INF, INF, 927, 928, 929, 930, 931, 932,
757  INF, INF, 933, 934, 935, 936, 937, 938, INF, INF, 939, 940, 941, 942, 943, 944,
758  945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960,
759  961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976,
760  977, 978, 979, 980, 981, 982, 983, 984, INF, INF, INF, 985, 986, 987, 988, 989,
761  INF, INF, INF, 990, 991, 992, 993, 994, INF, INF, INF, 995, 996, 997, 998, 999,
762 1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,
763 1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,
764 1032,1033,1034,1035,1036,1037,1038,1039,1040, INF, INF, INF,1041,1042,1043,1044,
765 1045, INF, INF, INF,1046,1047,1048,1049,1050, INF, INF, INF,1051,1052,1053,1054,
766 1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,
767 1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,
768 1087,1088,1089,1090,1091,1092,1093,1094,1095,1096, INF, INF, INF,1097,1098,1099,
769 1100,1101, INF, INF, INF,1102,1103,1104,1105,1106, INF, INF, INF,1107,1108,1109,
770 1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,
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  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
787 1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,
788 1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,
789  INF, INF,1158,1159,1160,1161,1162,1163, INF, INF,1164,1165,1166,1167,1168,1169,
790  INF, INF,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,
791 1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,
792 1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215,
793  INF, INF, INF,1216,1217,1218,1219,1220, INF, INF, INF,1221,1222,1223,1224,1225,
794  INF, INF, INF,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,1238,
795 1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,
796 1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,
797 1271, INF, INF, INF,1272,1273,1274,1275,1276, INF, INF, INF,1277,1278,1279,1280,
798 1281, INF, INF, INF,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,
799 1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,
800 1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,
801 1326,1327, INF, INF, INF,1328,1329,1330,1331,1332, INF, INF, INF,1333,1334,1335,
802 1336,1337, INF, INF, INF,1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,
803  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
804  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
805  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
806  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
807  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
808  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
809  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
810  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
811  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
812  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
813  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
814  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
815  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
816  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
817  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
818  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
819 1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1364,
820 1365,1366,1367,1368,1369,1370,1371,1372,1373,1374,1375,1376,1377,1378,1379,1380,
821 1381,1382,1383,1384,1385,1386,1387,1388, INF, INF,1389,1390,1391,1392,1393,1394,
822  INF, INF,1395,1396,1397,1398,1399,1400, INF, INF,1401,1402,1403,1404,1405,1406,
823 1407,1408,1409,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,
824 1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,
825 1439,1440,1441,1442,1443,1444,1445,1446, INF, INF, INF,1447,1448,1449,1450,1451,
826  INF, INF, INF,1452,1453,1454,1455,1456, INF, INF, INF,1457,1458,1459,1460,1461,
827 1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,
828 1478,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,
829 1494,1495,1496,1497,1498,1499,1500,1501,1502, INF, INF, INF,1503,1504,1505,1506,
830 1507, INF, INF, INF,1508,1509,1510,1511,1512, INF, INF, INF,1513,1514,1515,1516,
831 1517,1518,1519,1520,1521,1522,1523,1524,1525,1526,1527,1528,1529,1530,1531,1532,
832 1533,1534,1535,1536,1537,1538,1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,
833 1549,1550,1551,1552,1553,1554,1555,1556,1557,1558, INF, INF, INF,1559,1560,1561,
834 1562,1563, INF, INF, INF,1564,1565,1566,1567,1568, INF, INF, INF,1569,1570,1571,
835  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
836  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
837  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
838  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
839  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
840  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
841  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
842  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
843  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
844  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
845  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
846  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
847  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
848  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
849  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
850  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
851 1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,
852 1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600,1601,1602,1603,
853 1604,1605,1606,1607,1608,1609,1610,1611,1612,1613,1614,1615,1616,1617,1618,1619,
854  INF, INF,1620,1621,1622,1623,1624,1625, INF, INF,1626,1627,1628,1629,1630,1631,
855 1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1642,1643,1644,1645,1646,1647,
856 1648,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,1659,1660,1661,1662,1663,
857 1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,1674,1675,1676,1677,1678,1679,
858  INF, INF, INF,1680,1681,1682,1683,1684, INF, INF, INF,1685,1686,1687,1688,1689,
859 1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,
860 1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721,
861 1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,1734,1735,1736,1737,
862 1738, INF, INF, INF,1739,1740,1741,1742,1743, INF, INF, INF,1744,1745,1746,1747,
863 1748,1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,
864 1764,1765,1766,1767,1768,1769,1770,1771,1772,1773,1774,1775,1776,1777,1778,1779,
865 1780,1781,1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793,1794,1795,
866 1796,1797, INF, INF, INF,1798,1799,1800,1801,1802, INF, INF, INF,1803,1804,1805,
867  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
868  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
869  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
870  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
871  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
872  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
873  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
874  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
875  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
876  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
877  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
878  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
879  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
880  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
881  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
882  INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
883 };
884
885 // Useful macro and enumeration tables
886
887 #define IndTriKings(sqk1,sqk2)  ((unsigned) rgsTriKings[sqk1*64+sqk2])
888 #define IndHalfKings(sqk1,sqk2) ((unsigned) rgsHalfKings[sqk1*64+sqk2])
889
890 static const bool rgfTriangle[64] =
891 {
892      true,  true,  true,  true,  false, false, false, false,
893      false, true,  true,  true,  false, false, false, false,
894      false, false, true,  true,  false, false, false, false,
895      false, false, false, true,  false, false, false, false,
896      false, false, false, false, false, false, false, false,
897      false, false, false, false, false, false, false, false,
898      false, false, false, false, false, false, false, false,
899      false, false, false, false, false, false, false, false,
900 };
901
902 static const bool rgfNotDiagonal[64] =
903 {
904      false, true,  true,  true,  true,  true,  true,  true,
905      true,  false, true,  true,  true,  true,  true,  true,
906      true,  true,  false, true,  true,  true,  true,  true,
907      true,  true,  true,  false, true,  true,  true,  true,
908      true,  true,  true,  true,  false, true,  true,  true,
909      true,  true,  true,  true,  true,  false, true,  true,
910      true,  true,  true,  true,  true,  true,  false, true,
911      true,  true,  true,  true,  true,  true,  true,  false,
912 };
913
914 static const bool rgfInLargeTriangle[64] =
915 {
916      true,  true,  true,  true,  true,  true,  true,  true,
917      false, true,  true,  true,  true,  true,  true,  true,
918      false, false, true,  true,  true,  true,  true,  true,
919      false, false, false, true,  true,  true,  true,  true,
920      false, false, false, false, true,  true,  true,  true,
921      false, false, false, false, false, true,  true,  true,
922      false, false, false, false, false, false, true,  true,
923      false, false, false, false, false, false, false, true,
924 };
925
926 #define FInTriangle(sqwk,sqbk)  (rgfTriangle[sqwk] & (rgfNotDiagonal[sqwk]|rgfInLargeTriangle[sqbk]))
927
928 // Sort pieces
929
930 #define SORT(sq1,sq2)   if (sq1>sq2) { square sqTmp; sqTmp=sq1; sq1=sq2; sq2=sqTmp; }
931
932 // Exclude occupied squares
933
934 #define EXCLUDE1(sq,sq1)                         (sq-(sq>sq1))
935 #define EXCLUDE2(sq,sq1,sq2)                     (sq-((sq>sq1)+(sq>sq2)))
936 #define EXCLUDE3(sq,sq1,sq2,sq3)                 (sq-((sq>sq1)+(sq>sq2)+(sq>sq3)))
937 #define EXCLUDE4(sq,sq1,sq2,sq3,sq4)             (sq-((sq>sq1)+(sq>sq2)+(sq>sq3)+(sq>sq4)))
938 #define EXCLUDE5(sq,sq1,sq2,sq3,sq4,sq5)         (sq-((sq>sq1)+(sq>sq2)+(sq>sq3)+(sq>sq4)+(sq>sq5)))
939 #define EXCLUDE6(sq,sq1,sq2,sq3,sq4,sq5,sq6)     (sq-((sq>sq1)+(sq>sq2)+(sq>sq3)+(sq>sq4)+(sq>sq5)+(sq>sq6)))
940 #define EXCLUDE7(sq,sq1,sq2,sq3,sq4,sq5,sq6,sq7) (sq-((sq>sq1)+(sq>sq2)+(sq>sq3)+(sq>sq4)+(sq>sq5)+(sq>sq6)+(sq>sq7)))
941
942 #if !defined(SWAP)
943 #define SWAP(sq1, sq2)  {square sq_tmp = sq2; sq2 = sq1; sq1 = sq_tmp;}
944 #endif
945
946 // Calculate index - a lot of functions...
947
948 // Enumeration tables
949
950 static BYTE     *rgprgsqPiece[6];   // Enumeration for each piece (0 - black pawn)
951                                     // For each position of the King, all legal squares
952                                     // of the opposite piece enumerated
953 static BYTE     rgcLegal[6][64];    // # of enumerated positions for each piece and each
954                                     // location of enemy king
955
956 // Enumerations - indexed by [piece] and [kings enumeration].
957 // In each table for each [piece] and [king enumeration] we store # of preceeding positions.
958
959 static ULONG    *rgprgulSinglePawnless[6];
960 static ULONG    *rgprgulPairPawnless[6][6];
961 #if defined (T41_INCLUDE) || defined (T42_INCLUDE)
962   static ULONG  *rgprgulTriplePawnless[6][6][6];
963 #endif
964 static ULONG    *rgprgulSinglePawnPresent[6];
965 static ULONG    *rgprgulPairPawnPresent[6][6];
966 #if defined (T41_INCLUDE) || defined (T42_INCLUDE)
967   static ULONG  *rgprgulTriplePawnPresent[6][6][6];
968 #endif
969
970 // Total # of enumerated positions
971
972 static ULONG    rgcSinglePawnPresent[6];
973 static ULONG    rgcSinglePawnless[6];
974 static ULONG    rgcPairPawnPresent[6][6];
975 static ULONG    rgcPairPawnless[6][6];
976 #if defined (T41_INCLUDE) || defined (T42_INCLUDE)
977   static ULONG  rgcTriplePawnPresent[6][6][6];
978   static ULONG  rgcTriplePawnless[6][6][6];
979 #endif
980
981 // Infinities. Have to be larger than any legal enumeration yet small enough
982 // so there will be no overflow when combining them with remaining pieces.
983
984 #define INF_SINGLE  (110000)
985 #define INF_PAIR    (6500000)
986 #define INF_TRIPLE  (500000000)
987
988 // Initialize squares and counters table for one piece.
989 // Piece can be x_pieceNone - that means 'pawn of the wrong color', e.g. KPK BTM.
990
991 static void VInitSquaresTable
992     (
993     piece   pi,
994     BYTE    *prgsqPiece,
995     BYTE    *prgcLegal
996     )
997     {
998     int sqLo, sqHi;
999
1000     memset (prgsqPiece, -1, 64*64);
1001     sqLo = 0;
1002     sqHi = 64;
1003     if (pi <= x_piecePawn)
1004         {
1005         sqLo = 8;
1006         sqHi = 56;
1007         }
1008     for (int sqKing = 0; sqKing < 64; sqKing ++)
1009         {
1010         int iPiece;
1011
1012         iPiece = 0;
1013         for (int sq = sqLo; sq < sqHi; sq ++)
1014             {
1015             if (sq == sqKing)
1016                 continue;
1017             switch (pi)
1018                 {
1019             case x_piecePawn:
1020                 if (
1021                     0 != TbColumn (sq) && sqKing == sq+7 ||
1022                     7 != TbColumn (sq) && sqKing == sq+9
1023                    )
1024                    continue;
1025                 break;
1026             case x_pieceKnight:
1027                 if (
1028                     TbRow (sq) >= 2 && TbColumn (sq) >= 1 && sqKing == sq-17 ||
1029                     TbRow (sq) >= 2 && TbColumn (sq) <= 6 && sqKing == sq-15 ||
1030                     TbRow (sq) >= 1 && TbColumn (sq) >= 2 && sqKing == sq-10 ||
1031                     TbRow (sq) >= 1 && TbColumn (sq) <= 5 && sqKing == sq-6 ||
1032                     TbRow (sq) <= 6 && TbColumn (sq) >= 2 && sqKing == sq+6 ||
1033                     TbRow (sq) <= 6 && TbColumn (sq) <= 5 && sqKing == sq+10 ||
1034                     TbRow (sq) <= 5 && TbColumn (sq) >= 1 && sqKing == sq+15 ||
1035                     TbRow (sq) <= 5 && TbColumn (sq) <= 6 && sqKing == sq+17
1036                    )
1037                     continue;
1038                 break;
1039             case x_pieceBishop:
1040                 if (
1041                     0 != TbRow (sq) && 0 != TbColumn (sq) && sqKing == sq-9 ||
1042                     0 != TbRow (sq) && 7 != TbColumn (sq) && sqKing == sq-7 ||
1043                     7 != TbRow (sq) && 0 != TbColumn (sq) && sqKing == sq+7 ||
1044                     7 != TbRow (sq) && 7 != TbColumn (sq) && sqKing == sq+9
1045                    )
1046                     continue;
1047                 break;
1048             case x_pieceRook:
1049                 if (
1050                     0 != TbColumn (sq) && sqKing == sq-1 ||
1051                     7 != TbColumn (sq) && sqKing == sq+1 ||
1052                     0 != TbRow (sq) && sqKing == sq-8 ||
1053                     7 != TbRow (sq) && sqKing == sq+8
1054                    )
1055                     continue;
1056                 break;
1057             case x_pieceQueen:
1058                 if (
1059                     0 != TbColumn (sq) && sqKing == sq-1 ||
1060                     7 != TbColumn (sq) && sqKing == sq+1 ||
1061                     0 != TbRow (sq) && sqKing == sq-8 ||
1062                     7 != TbRow (sq) && sqKing == sq+8 ||
1063                     0 != TbRow (sq) && 0 != TbColumn (sq) && sqKing == sq-9 ||
1064                     0 != TbRow (sq) && 7 != TbColumn (sq) && sqKing == sq-7 ||
1065                     7 != TbRow (sq) && 0 != TbColumn (sq) && sqKing == sq+7 ||
1066                     7 != TbRow (sq) && 7 != TbColumn (sq) && sqKing == sq+9
1067                    )
1068                     continue;
1069                 break;
1070                 }
1071             prgsqPiece[sqKing*64+sq] = (BYTE) iPiece;
1072             iPiece ++;
1073             }
1074         prgcLegal[sqKing] = (BYTE) iPiece;
1075         }
1076     }
1077
1078 // Initialize enumeration table for single piece
1079
1080 static void VInitSingle
1081     (
1082     ULONG       *prgIndex,
1083     const short *prgsKings,
1084     const BYTE  *prgcLegal,
1085     const BYTE  *prgsqPiece,
1086     ULONG       *pcEnumeration
1087     )
1088     {
1089     ULONG iIndex;
1090
1091     iIndex = 0;
1092     for (int sqKing1 = 0; sqKing1 < 64; sqKing1 ++)
1093         for (int sqKing2 = 0; sqKing2 < 64; sqKing2 ++)
1094             {
1095             if (INF != prgsKings[sqKing1*64+sqKing2])
1096                 {
1097                 prgIndex[prgsKings[sqKing1*64+sqKing2]] = iIndex;
1098                 iIndex += prgcLegal[sqKing2] - ((BYTE) -1 != prgsqPiece[sqKing2*64+sqKing1]);
1099                 }
1100             }
1101     *pcEnumeration = iIndex;
1102     }
1103
1104 // Initialize enumeration table for pair of pieces
1105
1106 static void VInitPair
1107     (
1108     ULONG       *prgIndex,
1109     const short *prgsKings,
1110     const BYTE  *prgcLegal1,
1111     const BYTE  *prgsqPiece1,
1112     const BYTE  *prgcLegal2,
1113     const BYTE  *prgsqPiece2,
1114     ULONG       *pcEnumeration
1115     )
1116     {
1117     ULONG iIndex;
1118     ULONG cPositions1, cPositions2;
1119
1120     iIndex = 0;
1121     for (int sqKing1 = 0; sqKing1 < 64; sqKing1 ++)
1122         for (int sqKing2 = 0; sqKing2 < 64; sqKing2 ++)
1123             {
1124             if (INF != prgsKings[sqKing1*64+sqKing2])
1125                 {
1126                 prgIndex[prgsKings[sqKing1*64+sqKing2]] = iIndex;
1127                 cPositions1 = prgcLegal1[sqKing2] - ((BYTE) -1 != prgsqPiece1[sqKing2*64+sqKing1]);
1128                 if (prgcLegal1 == prgcLegal2)
1129                     iIndex += cPositions1*(cPositions1-1)/2;
1130                 else
1131                     {
1132                     cPositions2 = prgcLegal2[sqKing2] - ((BYTE) -1 != prgsqPiece2[sqKing2*64+sqKing1]);
1133                     iIndex += cPositions1*cPositions2;
1134                     }
1135                 }
1136             }
1137     *pcEnumeration = iIndex;
1138     }
1139
1140 #if defined (T41_INCLUDE) || defined (T42_INCLUDE)
1141
1142 // Initialize enumeration table for triple piece
1143
1144 static void VInitTriple
1145     (
1146     ULONG       *prgIndex,
1147     const short *prgsKings,
1148     const BYTE  *prgcLegal1,
1149     const BYTE  *prgsqPiece1,
1150     const BYTE  *prgcLegal2,
1151     const BYTE  *prgsqPiece2,
1152     const BYTE  *prgcLegal3,
1153     const BYTE  *prgsqPiece3,
1154     ULONG       *pcEnumeration
1155     )
1156     {
1157     ULONG iIndex;
1158     ULONG cPositions1, cPositions2, cPositions3;
1159
1160     iIndex = 0;
1161     for (int sqKing1 = 0; sqKing1 < 64; sqKing1 ++)
1162         for (int sqKing2 = 0; sqKing2 < 64; sqKing2 ++)
1163             {
1164             if (INF != prgsKings[sqKing1*64+sqKing2])
1165                 {
1166                 prgIndex[prgsKings[sqKing1*64+sqKing2]] = iIndex;
1167                 cPositions1 = prgcLegal1[sqKing2] - ((BYTE) -1 != prgsqPiece1[sqKing2*64+sqKing1]);
1168                 if (prgcLegal1 == prgcLegal2 && prgcLegal2 == prgcLegal3)
1169                     iIndex += cPositions1*(cPositions1-1)*(cPositions1-2)/6;
1170                 else if (prgcLegal1 == prgcLegal2)
1171                     {
1172                     cPositions3 = prgcLegal3[sqKing2] - ((BYTE) -1 != prgsqPiece3[sqKing2*64+sqKing1]);
1173                     iIndex += cPositions1*(cPositions1-1)/2*cPositions3;
1174                     }
1175                 else if (prgcLegal2 == prgcLegal3)
1176                     {
1177                     cPositions2 = prgcLegal2[sqKing2] - ((BYTE) -1 != prgsqPiece2[sqKing2*64+sqKing1]);
1178                     iIndex += cPositions1*cPositions2*(cPositions2-1)/2;
1179                     }
1180                 else
1181                     {
1182                     cPositions2 = prgcLegal2[sqKing2] - ((BYTE) -1 != prgsqPiece2[sqKing2*64+sqKing1]);
1183                     cPositions3 = prgcLegal3[sqKing2] - ((BYTE) -1 != prgsqPiece3[sqKing2*64+sqKing1]);
1184                     iIndex += cPositions1*cPositions2*cPositions3;
1185                     }
1186                 }
1187             }
1188     *pcEnumeration = iIndex;
1189     }
1190
1191 #endif
1192
1193 // Initialize all Enumeration tables
1194
1195 static bool fEnumerationInitted = false;
1196
1197 static void VInitEnumerations (void)
1198     {
1199     piece   pi1;
1200     piece   pi2;
1201 #if defined (T41_INCLUDE) || defined (T42_INCLUDE)
1202     piece   pi3;
1203 #endif
1204
1205     if (fEnumerationInitted)
1206         return;
1207     fEnumerationInitted = true;
1208     // Initialize square tables
1209     for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
1210         {
1211         rgprgsqPiece[pi1] = (BYTE *) PvMalloc (64*64);
1212         VInitSquaresTable (pi1, rgprgsqPiece[pi1], rgcLegal[pi1]);
1213         }
1214
1215     for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
1216         {
1217         // Initialize enumeration tables for single piece
1218         rgprgulSinglePawnPresent[pi1] = (ULONG *) PvMalloc (1806*sizeof (ULONG));
1219         VInitSingle (rgprgulSinglePawnPresent[pi1], rgsHalfKings,
1220                      rgcLegal[pi1], rgprgsqPiece[pi1], &rgcSinglePawnPresent[pi1]);
1221         if (pi1 > x_piecePawn)
1222             {
1223             rgprgulSinglePawnless[pi1] = (ULONG *) PvMalloc (462*sizeof (ULONG));
1224             VInitSingle (rgprgulSinglePawnless[pi1], rgsTriKings,
1225                          rgcLegal[pi1], rgprgsqPiece[pi1], &rgcSinglePawnless[pi1]);
1226             }
1227         // Initialize enumeration tables for pair of pieces
1228         for (pi2 = (x_pieceNone == pi1 ? x_pieceNone : x_piecePawn); pi2 <= pi1; pi2 = (piece) (pi2 + 1))
1229             {
1230             rgprgulPairPawnPresent[pi1][pi2] = (ULONG *) PvMalloc (1806*sizeof (ULONG));
1231             VInitPair (rgprgulPairPawnPresent[pi1][pi2], rgsHalfKings,
1232                        rgcLegal[pi1], rgprgsqPiece[pi1], rgcLegal[pi2], rgprgsqPiece[pi2],
1233                        &rgcPairPawnPresent[pi1][pi2]);
1234             if (pi1 > x_piecePawn && pi2 > x_piecePawn)
1235                 {
1236                 rgprgulPairPawnless[pi1][pi2] = (ULONG *) PvMalloc (462*sizeof (ULONG));
1237                 VInitPair (rgprgulPairPawnless[pi1][pi2], rgsTriKings,
1238                            rgcLegal[pi1], rgprgsqPiece[pi1], rgcLegal[pi2], rgprgsqPiece[pi2],
1239                            &rgcPairPawnless[pi1][pi2]);
1240                 }
1241 #if defined (T41_INCLUDE) || defined (T42_INCLUDE)
1242             // Initialize enumeration tables for three pieces
1243             for (pi3 = (x_pieceNone == pi1 ? x_pieceNone : x_piecePawn); pi3 <= pi2; pi3 = (piece) (pi3 + 1))
1244                 {
1245                 if (pi1 <= x_piecePawn || pi2 <= x_piecePawn || pi3 <= x_piecePawn)
1246                     {
1247                     rgprgulTriplePawnPresent[pi1][pi2][pi3] = (ULONG *) PvMalloc (1806*sizeof (ULONG));
1248                     VInitTriple (rgprgulTriplePawnPresent[pi1][pi2][pi3], rgsHalfKings,
1249                                  rgcLegal[pi1], rgprgsqPiece[pi1],
1250                                  rgcLegal[pi2], rgprgsqPiece[pi2],
1251                                  rgcLegal[pi3], rgprgsqPiece[pi3],
1252                                  &rgcTriplePawnPresent[pi1][pi2][pi3]);
1253                     }
1254                 else
1255                     {
1256                     rgprgulTriplePawnless[pi1][pi2][pi3] = (ULONG *) PvMalloc (462*sizeof (ULONG));
1257                     VInitTriple (rgprgulTriplePawnless[pi1][pi2][pi3], rgsTriKings,
1258                         rgcLegal[pi1], rgprgsqPiece[pi1],
1259                         rgcLegal[pi2], rgprgsqPiece[pi2],
1260                         rgcLegal[pi3], rgprgsqPiece[pi3],
1261                         &rgcTriplePawnless[pi1][pi2][pi3]);
1262 #if defined (T42_INCLUDE)
1263                     rgprgulTriplePawnPresent[pi1][pi2][pi3] = (ULONG *) PvMalloc (1806*sizeof (ULONG));
1264                     VInitTriple (rgprgulTriplePawnPresent[pi1][pi2][pi3], rgsHalfKings,
1265                                  rgcLegal[pi1], rgprgsqPiece[pi1],
1266                                  rgcLegal[pi2], rgprgsqPiece[pi2],
1267                                  rgcLegal[pi3], rgprgsqPiece[pi3],
1268                                  &rgcTriplePawnPresent[pi1][pi2][pi3]);
1269 #endif
1270                     }
1271                 }
1272 #endif
1273             }
1274         }
1275
1276     // All done!
1277     if (fPrint)
1278         {
1279         for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
1280             printf ("%c - %d enumerated positions\n", "pPNBRQ"[pi1], rgcSinglePawnPresent[pi1]);
1281         for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
1282             {
1283             if (0 != rgcSinglePawnless[pi1])
1284                 printf ("pawnless %c - %d enumerated positions\n", "pPNBRQ"[pi1], rgcSinglePawnless[pi1]);
1285             }
1286         for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
1287             for (pi2 = x_pieceNone; pi2 <= pi1; pi2 = (piece) (pi2 + 1))
1288                 {
1289                 if (0 != rgcPairPawnPresent[pi1][pi2])
1290                     printf ("%c%c - %d enumerated positions\n", "pPNBRQ"[pi1], "pPNBRQ"[pi2],
1291                             rgcPairPawnPresent[pi1][pi2]);
1292                 }
1293         for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
1294             for (pi2 = x_pieceNone; pi2 <= pi1; pi2 = (piece) (pi2 + 1))
1295                 {
1296                 if (0 != rgcPairPawnless[pi1][pi2])
1297                     printf ("pawnless %c%c - %d enumerated positions\n", "pPNBRQ"[pi1], "pPNBRQ"[pi2],
1298                             rgcPairPawnless[pi1][pi2]);
1299                 }
1300 #if defined (T41_INCLUDE) || defined (T42_INCLUDE)
1301         for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
1302             for (pi2 = x_pieceNone; pi2 <= pi1; pi2 = (piece) (pi2 + 1))
1303                 for (pi3 = x_pieceNone; pi3 <= pi2; pi3 = (piece) (pi3 + 1))
1304                     {
1305                     if (0 != rgcTriplePawnPresent[pi1][pi2][pi3])
1306                         printf ("%c%c%c - %d enumerated positions\n",
1307                                 "pPNBRQ"[pi1], "pPNBRQ"[pi2], "pPNBRQ"[pi3],
1308                                 rgcTriplePawnPresent[pi1][pi2][pi3]);
1309                     }
1310         for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
1311             for (pi2 = x_pieceNone; pi2 <= pi1; pi2 = (piece) (pi2 + 1))
1312                 for (pi3 = x_pieceNone; pi3 <= pi2; pi3 = (piece) (pi3 + 1))
1313                     {
1314                     if (0 != rgcTriplePawnless[pi1][pi2][pi3])
1315                         printf ("pawnless %c%c%c - %d enumerated positions\n",
1316                                 "pPNBRQ"[pi1], "pPNBRQ"[pi2], "pPNBRQ"[pi3],
1317                                 rgcTriplePawnless[pi1][pi2][pi3]);
1318                     }
1319 #endif
1320         printf ("\nAllocated %dk\n\n", (cbAllocated + 1023)/1024);
1321         }
1322     }
1323
1324 // Return enumeration of 2 kings and single piece
1325
1326 template <int piw1, bool fPawns, bool fInvert> class TEnumerate1
1327     {
1328 public:
1329     static INLINE unsigned TB_FASTCALL Index
1330         (
1331         square  sqwk,
1332         square  sqw1,
1333         square  sqbk
1334         )
1335         {
1336         unsigned ind;
1337         ULONG    ulKings;
1338
1339         // For black pawn invert the board
1340         if (piw1 <= x_piecePawn && fInvert)
1341             {
1342             sqwk = reflect_x(sqwk);
1343             sqw1 = reflect_x(sqw1);
1344             sqbk = reflect_x(sqbk);
1345             }
1346         
1347         // Get enumerated square
1348         ind = rgprgsqPiece[piw1][sqbk*64+sqw1];
1349 #if defined (ILLEGAL_POSSIBLE)
1350         if ((BYTE) -1 == ind)
1351             return INF_SINGLE;
1352 #endif
1353         // Get enumerated position of both kings
1354         if (fPawns)
1355             ulKings = rgsHalfKings[sqwk*64+sqbk];   // 0..1805
1356         else
1357             ulKings = rgsTriKings[sqwk*64+sqbk];    // 0..461
1358 #if defined (ILLEGAL_POSSIBLE)
1359         if (INF == ulKings)
1360             return INF_SINGLE;
1361 #endif
1362         // Can we remove one extra square?
1363         if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
1364             ind -= (sqw1 > sqwk);
1365         // Add enumerated square to the # of the preceeding positions
1366         return ind + (fPawns ? rgprgulSinglePawnPresent[piw1][ulKings] : rgprgulSinglePawnless[piw1][ulKings]);
1367         }
1368     };
1369
1370 // Return enumeration of 2 kings and 2 pieces
1371
1372 template <int piw1, int piw2, bool fPawns, bool fInvert> class TEnumerate2
1373     {
1374 public:
1375     static INLINE unsigned TB_FASTCALL Index
1376         (
1377         square  sqwk,
1378         square  sqw1,
1379         square  sqw2,
1380         square  sqbk
1381         )
1382         {
1383         unsigned ind1, ind2, cInd2;
1384         ULONG    ulKings;
1385
1386         // For black pawn invert the board
1387         if (piw2 <= x_piecePawn && fInvert)
1388             {
1389             sqwk = reflect_x(sqwk);
1390             sqw1 = reflect_x(sqw1);
1391             sqw2 = reflect_x(sqw2);
1392             sqbk = reflect_x(sqbk);
1393             }
1394         
1395         // Get enumerated squares for both pieces
1396         if (piw1 == piw2)
1397             SORT (sqw1, sqw2);
1398         ind1 = rgprgsqPiece[piw1][sqbk*64+sqw1];
1399         ind2 = rgprgsqPiece[piw2][sqbk*64+sqw2];
1400 #if defined (ILLEGAL_POSSIBLE)
1401         if ((BYTE) -1 == ind1 || (BYTE) -1 == ind2)
1402             return INF_PAIR;
1403 #endif
1404         // Get enumerated position of both kings
1405         if (fPawns)
1406             ulKings = rgsHalfKings[sqwk*64+sqbk];   // 0..1805
1407         else
1408             ulKings = rgsTriKings[sqwk*64+sqbk];    // 0..461
1409 #if defined (ILLEGAL_POSSIBLE)
1410         if (INF == ulKings)
1411             return INF_PAIR;
1412 #endif
1413         if (piw1 == piw2)
1414             {
1415             // Can we remove one extra square?
1416             if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
1417                 {
1418                 ind1 -= (sqw1 > sqwk);
1419                 ind2 -= (sqw2 > sqwk);
1420                 }
1421             // Add enumerated squares to the # of the preceeding positions
1422             return  ind2*(ind2-1)/2 + ind1 +
1423                     (fPawns ? rgprgulPairPawnPresent[piw1][piw2][ulKings] : rgprgulPairPawnless[piw1][piw2][ulKings]);
1424             }
1425         else
1426             {
1427             // Can we remove WK square from 1st piece Enumeration?
1428             if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
1429                 ind1 -= (sqw1 > sqwk);
1430             // Get # of enumerated positions of 2nd piece
1431             cInd2 = rgcLegal[piw2][sqbk];
1432             // Can we remove WK square from 2nd piece Enumeration?
1433             if ((piw2>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw2][sqbk*64+sqwk]))
1434                 {
1435                 cInd2 --;
1436                 ind2 -= (sqw2 > sqwk);
1437                 }
1438             // Add enumerated square to the # of the preceeding positions
1439             return cInd2*ind1 + ind2 + (fPawns ? rgprgulPairPawnPresent[piw1][piw2][ulKings] : rgprgulPairPawnless[piw1][piw2][ulKings]);
1440             }
1441         }
1442     };
1443
1444 #if defined (T41_INCLUDE) || defined (T42_INCLUDE)
1445
1446 // Return enumeration of 2 kings and 3 pieces
1447
1448 template <int piw1, int piw2, int piw3, bool fPawns, bool fInvert> class TEnumerate3
1449     {
1450 public:
1451     static INLINE unsigned TB_FASTCALL Index
1452         (
1453         square  sqwk,
1454         square  sqw1,
1455         square  sqw2,
1456         square  sqw3,
1457         square  sqbk
1458         )
1459         {
1460         unsigned ind1, ind2, ind3, cInd1, cInd2, cInd3;
1461         ULONG    ulKings;
1462
1463         // For black pawn invert the board
1464         if (piw3 <= x_piecePawn && fInvert)
1465             {
1466             sqwk = reflect_x(sqwk);
1467             sqw1 = reflect_x(sqw1);
1468             sqw2 = reflect_x(sqw2);
1469             sqw3 = reflect_x(sqw3);
1470             sqbk = reflect_x(sqbk);
1471             }
1472         
1473         // Get enumerated squares for all pieces
1474         if (piw1 == piw2 && piw1 == piw3)
1475             {
1476             SORT (sqw1, sqw2);
1477             SORT (sqw2, sqw3);
1478             SORT (sqw1, sqw2);
1479             }
1480         else if (piw1 == piw2)
1481             {
1482             SORT (sqw1, sqw2);
1483             }
1484         else if (piw2 == piw3)
1485             {
1486             SORT (sqw2, sqw3);
1487             }
1488         ind1 = rgprgsqPiece[piw1][sqbk*64+sqw1];
1489         ind2 = rgprgsqPiece[piw2][sqbk*64+sqw2];
1490         ind3 = rgprgsqPiece[piw3][sqbk*64+sqw3];
1491 #if defined (ILLEGAL_POSSIBLE)
1492         if ((BYTE) -1 == ind1 || (BYTE) -1 == ind2 || (BYTE) -1 == ind3)
1493             return INF_TRIPLE;
1494 #endif
1495         // Get enumerated position of both kings
1496         if (fPawns)
1497             ulKings = rgsHalfKings[sqwk*64+sqbk];   // 0..1805
1498         else
1499             ulKings = rgsTriKings[sqwk*64+sqbk];    // 0..461
1500 #if defined (ILLEGAL_POSSIBLE)
1501         if (INF == ulKings)
1502             return INF_TRIPLE;
1503 #endif
1504         if (piw1 == piw2 && piw2 == piw3)
1505             {
1506             // Can we remove one extra square?
1507             if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
1508                 {
1509                 ind1 -= (sqw1 > sqwk);
1510                 ind2 -= (sqw2 > sqwk);
1511                 ind3 -= (sqw3 > sqwk);
1512                 }
1513             // Add enumerated squares to the # of the preceeding positions
1514             return  ind3*(ind3-1)*(ind3-2)/6 + ind2*(ind2-1)/2 + ind1 +
1515                     (fPawns ? rgprgulTriplePawnPresent[piw1][piw2][piw3][ulKings] :
1516                               rgprgulTriplePawnless[piw1][piw2][piw3][ulKings]);
1517             }
1518         else if (piw1 == piw2)
1519             {
1520             // Can we remove one extra square?
1521             if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
1522                 {
1523                 ind1 -= (sqw1 > sqwk);
1524                 ind2 -= (sqw2 > sqwk);
1525                 }
1526             // Get # of enumerated positions of 3rd piece
1527             cInd3 = rgcLegal[piw3][sqbk];
1528             // Can we remove WK square from 3rd piece Enumeration?
1529             if ((piw3>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw3][sqbk*64+sqwk]))
1530                 {
1531                 cInd3 --;
1532                 ind3 -= (sqw3 > sqwk);
1533                 }
1534             // Add enumerated squares to the # of the preceeding positions
1535             return  (ind2*(ind2-1)/2 + ind1)*cInd3 + ind3 +
1536                     (fPawns ? rgprgulTriplePawnPresent[piw1][piw2][piw3][ulKings] :
1537                               rgprgulTriplePawnless[piw1][piw2][piw3][ulKings]);
1538             }
1539         else if (piw2 == piw3)
1540             {
1541             // Can we remove one extra square?
1542             if ((piw2>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw2][sqbk*64+sqwk]))
1543                 {
1544                 ind2 -= (sqw2 > sqwk);
1545                 ind3 -= (sqw3 > sqwk);
1546                 }
1547             // Get # of enumerated positions of 1st piece
1548             cInd1 = rgcLegal[piw1][sqbk];
1549             // Can we remove WK square from 3rd piece Enumeration?
1550             if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
1551                 {
1552                 cInd1 --;
1553                 ind1 -= (sqw1 > sqwk);
1554                 }
1555             // Add enumerated squares to the # of the preceeding positions
1556             return  (ind3*(ind3-1)/2 + ind2)*cInd1 + ind1 +
1557                     (fPawns ? rgprgulTriplePawnPresent[piw1][piw2][piw3][ulKings] :
1558                               rgprgulTriplePawnless[piw1][piw2][piw3][ulKings]);
1559             }
1560         else
1561             {
1562             // Can we remove WK square from 1st piece Enumeration?
1563             if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
1564                 ind1 -= (sqw1 > sqwk);
1565             // Get # of enumerated positions of 2nd piece
1566             cInd2 = rgcLegal[piw2][sqbk];
1567             // Can we remove WK square from 2nd piece Enumeration?
1568             if ((piw2>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw2][sqbk*64+sqwk]))
1569                 {
1570                 cInd2 --;
1571                 ind2 -= (sqw2 > sqwk);
1572                 }
1573             // Get # of enumerated positions of 3rd piece
1574             cInd3 = rgcLegal[piw3][sqbk];
1575             // Can we remove WK square from 3rd piece Enumeration?
1576             if ((piw3>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw3][sqbk*64+sqwk]))
1577                 {
1578                 cInd3 --;
1579                 ind3 -= (sqw3 > sqwk);
1580                 }
1581             // Add enumerated square to the # of the preceeding positions
1582             return  cInd3*(cInd2*ind1 + ind2) + ind3 +
1583                     (fPawns ? rgprgulTriplePawnPresent[piw1][piw2][piw3][ulKings] :
1584                               rgprgulTriplePawnless[piw1][piw2][piw3][ulKings]);
1585             }
1586         }
1587     };
1588
1589 #endif
1590
1591 // Enumerate en passant captures
1592
1593 static INLINE unsigned TB_FASTCALL IndEnPassant11W
1594     (
1595     square  sqw,
1596     square  sqb,
1597     square  sqEnP
1598     )
1599     {
1600     assert (sqb+8 == sqEnP);
1601     if (sqw+7 == sqEnP)
1602         // Capture to the left
1603         return  (sqw&7)-1;
1604     else
1605         {
1606         // Capture to the right
1607         assert (sqw+9 == sqEnP);
1608         return  (sqw&7)+7;
1609         }
1610     }
1611
1612 static INLINE unsigned TB_FASTCALL IndEnPassant11B
1613     (
1614     square  sqw,
1615     square  sqb,
1616     square  sqEnP
1617     )
1618     {
1619     assert (sqw-8 == sqEnP);
1620     if (sqb-9 == sqEnP)
1621         // Capture to the left
1622         return (sqb&7)-1;
1623     else
1624         {
1625         // Capture to the right
1626         assert (sqb-7 == sqEnP);
1627         return (sqb&7)+7;
1628         }
1629     }
1630
1631 static INLINE unsigned TB_FASTCALL IndEnPassant21W
1632     (
1633     square  sqw1,
1634     square  sqw2,
1635     square  sqb,
1636     square  sqEnP
1637     )
1638     {
1639     assert (sqb+8 == sqEnP);
1640     SORT (sqw1, sqw2);
1641     if (sqw1+7 == sqEnP && 0 != TbColumn(sqw1))
1642         // Capture to the left
1643         return (sqw1&7)-1+(EXCLUDE3(sqw2,sqb,sqEnP,sqEnP+8)-i8-1)*i14;
1644     else if (sqw1+9 == sqEnP && 7 != TbColumn(sqw1))
1645         // Capture to the right
1646         return (sqw1&7)+7+(EXCLUDE3(sqw2,sqb,sqEnP,sqEnP+8)-i8-1)*i14;
1647     else if (sqw2+7 == sqEnP && 0 != TbColumn(sqw2))
1648         // Capture to the left
1649         return (sqw2&7)-1+(EXCLUDE3(sqw1,sqb,sqEnP,sqEnP+8)-i8)*i14;
1650     else
1651         {
1652         // Capture to the right
1653         assert (sqw2+9 == sqEnP && 7 != TbColumn(sqw2));
1654         return (sqw2&7)+7+(EXCLUDE3(sqw1,sqb,sqEnP,sqEnP+8)-i8)*i14;
1655         }
1656     }
1657
1658 static INLINE unsigned TB_FASTCALL IndEnPassant21B
1659     (
1660     square  sqw1,
1661     square  sqw2,
1662     square  sqb,
1663     square  sqEnP
1664     )
1665     {
1666     assert (sqw1 < sqw2);   // Must be already sorted
1667     if (sqb-9 == sqEnP && 0 != TbColumn(sqb))
1668         // Capture to the left
1669         if (sqw1-8 == sqEnP)
1670             return (sqb&7)-1+(EXCLUDE3(sqw2,sqb,sqEnP,sqEnP-8)-i8-1)*i14;
1671         else
1672             {
1673             assert (sqw2-8 == sqEnP);
1674             return (sqb&7)-1+(EXCLUDE3(sqw1,sqb,sqEnP,sqEnP-8)-i8)*i14;
1675             }
1676     else
1677         {
1678         // Capture to the right
1679         assert (sqb-7 == sqEnP && 7 != TbColumn(sqb));
1680         if (sqw1-8 == sqEnP)
1681             return (sqb&7)+7+(EXCLUDE3(sqw2,sqb,sqEnP,sqEnP-8)-i8-1)*i14;
1682         else
1683             {
1684             assert (sqw2-8 == sqEnP);
1685             return (sqb&7)+7+(EXCLUDE3(sqw1,sqb,sqEnP,sqEnP-8)-i8)*i14;
1686             }
1687         }
1688     }
1689
1690 static INLINE unsigned TB_FASTCALL IndEnPassant12W
1691     (
1692     square  sqw,
1693     square  sqb1,
1694     square  sqb2,
1695     square  sqEnP
1696     )
1697 {
1698     if(sqb2+8 == sqEnP)
1699         SWAP(sqb1, sqb2);
1700
1701     assert(sqb1+8 == sqEnP);
1702
1703     if (sqw+7 == sqEnP && 0 != TbColumn(sqw))
1704         // Capture to the left
1705         return TbColumn(sqw)-1+(EXCLUDE4(sqb2,sqb1,sqw,sqEnP,sqEnP+8)-i8)*i14;
1706
1707     assert(sqw+9 == sqEnP && 7 != TbColumn(sqw));
1708
1709     // Capture to the right
1710     return TbColumn(sqw)+7 + (EXCLUDE4(sqb2,sqb1,sqw,sqEnP,sqEnP+8)-i8)*i14;
1711 }
1712
1713 static INLINE unsigned TB_FASTCALL IndEnPassant12B
1714     (
1715     square  sqw,
1716     square  sqb1,
1717     square  sqb2,
1718     square  sqEnP
1719     )
1720 {
1721     assert(sqw-8 == sqEnP);
1722
1723     SORT(sqb1, sqb2);
1724
1725     if(sqb1-9 == sqEnP && 0 != TbColumn(sqb1))
1726         // Capture to the left
1727         return TbColumn(sqb1) - 1 + (sqb2-i8-4)*i14;
1728     else if(sqb1-7 == sqEnP && 7 != TbColumn(sqb1))
1729         // Capture to the right
1730         return TbColumn(sqb1) + 7 + (sqb2-i8-4)*i14;
1731     else if(sqb2-9 == sqEnP && 0 != TbColumn(sqb2))
1732         // Capture to the left
1733         return TbColumn(sqb2) - 1 + (EXCLUDE2(sqb1,sqEnP,sqEnP-8)-i8)*i14;
1734
1735     // Capture to the right
1736     assert(sqb2-7 == sqEnP && 7 != TbColumn(sqb2));
1737     return TbColumn(sqb2) + 7 + (EXCLUDE2(sqb1,sqEnP,sqEnP-8)-i8)*i14;
1738 }
1739
1740 static INLINE unsigned TB_FASTCALL IndEnPassant22W
1741     (
1742     square  sqw1,
1743     square  sqw2,
1744     square  sqb1,
1745     square  sqb2,
1746     square  sqEnP
1747     )
1748 {
1749     square sqEmptyEnP = sqEnP + 8;
1750
1751     if(sqb2+8== sqEnP)
1752        SWAP(sqb1, sqb2);
1753
1754     assert(sqb1+8 == sqEnP);
1755
1756     SORT(sqw1, sqw2);
1757
1758     if (sqw1+7 == sqEnP && 0 != TbColumn(sqw1))
1759             // Capture to the left
1760         return TbColumn(sqw1)-1+
1761            (EXCLUDE2(sqw2,sqEnP,sqEmptyEnP)-i8-2)*i14+
1762            (EXCLUDE5(sqb2,sqb1,sqw1,sqw2,sqEnP,sqEmptyEnP)-i8)*(i14*i44);
1763     else if (sqw1+9 == sqEnP && 7 != TbColumn(sqw1))
1764             // Capture to the right
1765         return TbColumn(sqw1)+7+
1766            (EXCLUDE2(sqw2,sqEnP,sqEmptyEnP)-i8-2)*i14+
1767            (EXCLUDE5(sqb2,sqb1,sqw1,sqw2,sqEnP,sqEmptyEnP)-i8)*(i14*i44);
1768     else if (sqw2+7 == sqEnP && 0 != TbColumn(sqw2))
1769             // Capture to the left
1770         return TbColumn(sqw2)-1+
1771            (sqw1-i8)*i14+
1772            (EXCLUDE5(sqb2,sqb1,sqw1,sqw2,sqEnP,sqEmptyEnP)-i8)*(i14*i44);
1773
1774     // Capture to the right
1775     assert(sqw2+9 == sqEnP && 7 != TbColumn(sqw2));
1776     return TbColumn(sqw2)+7+
1777            (sqw1-i8)*i14+
1778        (EXCLUDE5(sqb2,sqb1,sqw1,sqw2,sqEnP,sqEmptyEnP)-i8)*(i14*i44);
1779 }
1780
1781 static INLINE unsigned TB_FASTCALL IndEnPassant22B
1782     (
1783     square  sqw1,
1784     square  sqw2,
1785     square  sqb1,
1786     square  sqb2,
1787     square  sqEnP
1788     )
1789 {
1790     square sqEmptyEnP = sqEnP - 8;
1791
1792     if(sqw2-8 == sqEnP)
1793        SWAP(sqw1, sqw2);
1794
1795     assert(sqw1-8 == sqEnP);
1796
1797     SORT(sqb1, sqb2);
1798
1799     if (sqb1-9 == sqEnP && 0 != TbColumn(sqb1))
1800         // Capture to the left
1801         return TbColumn(sqb1)-1+
1802            (sqb2-i8-4)*i14+
1803            (EXCLUDE5(sqw2,sqw1,sqb1,sqb2,sqEnP,sqEmptyEnP)-i8)*(i14*i44);
1804     else if (sqb1-7 == sqEnP && 7 != TbColumn(sqb1))
1805         // Capture to the right
1806         return TbColumn(sqb1)+7+
1807            (sqb2-i8-4)*i14+
1808            (EXCLUDE5(sqw2,sqw1,sqb1,sqb2,sqEnP,sqEmptyEnP)-i8)*(i14*i44);
1809     else if (sqb2-9 == sqEnP && 0 != TbColumn(sqb2))
1810         // Capture to the left
1811         return TbColumn(sqb2)-1+
1812            (EXCLUDE2(sqb1,sqEnP,sqEmptyEnP)-i8)*i14+
1813            (EXCLUDE5(sqw2,sqw1,sqb1,sqb2,sqEnP,sqEmptyEnP)-i8)*(i14*i44);
1814
1815     // Capture to the right
1816     assert(sqb2-7 == sqEnP && 7 != TbColumn(sqb2));
1817     return TbColumn(sqb2)+7+
1818            (EXCLUDE2(sqb1,sqEnP,sqEmptyEnP)-i8)*i14+
1819        (EXCLUDE5(sqw2,sqw1,sqb1,sqb2,sqEnP,sqEmptyEnP)-i8)*(i14*i44);
1820 }
1821
1822 static INLINE unsigned TB_FASTCALL IndEnPassant31W
1823     (
1824     square  sqw1,
1825     square  sqw2,
1826     square  sqw3,
1827     square  sqb,
1828     square  sqEnP
1829     )
1830 {
1831     square sqEmptyEnP = sqEnP + 8;
1832
1833     assert(sqb + 8 == sqEnP);
1834
1835     SORT (sqw1, sqw2);
1836     SORT (sqw2, sqw3);
1837     SORT (sqw1, sqw2);
1838
1839     if (sqw1+7 == sqEnP && 0 != TbColumn(sqw1)) {
1840         // Capture to the left
1841         sqw3 = EXCLUDE2(sqw3,sqEnP,sqEmptyEnP)-i8-2;
1842         return TbColumn(sqw1)-1+
1843                (EXCLUDE2(sqw2,sqEnP,sqEmptyEnP)-i8-2)*i14+
1844                (sqw3*(sqw3-1)/2)*i14;
1845         }
1846     else if (sqw1+9 == sqEnP && 7 != TbColumn(sqw1)) {
1847         // Capture to the right
1848         sqw3 = EXCLUDE2(sqw3,sqEnP,sqEmptyEnP)-i8-2;
1849         return TbColumn(sqw1)+7+
1850                (EXCLUDE2(sqw2,sqEnP,sqEmptyEnP)-i8-2)*i14+
1851                (sqw3*(sqw3-1)/2)*i14;
1852     }
1853     else if (sqw2+7 == sqEnP && 0 != TbColumn(sqw2)) {
1854         // Capture to the left
1855         sqw3 = EXCLUDE2(sqw3,sqEnP,sqEmptyEnP)-i8-2;
1856         return TbColumn(sqw2)-1+
1857                (sqw1-i8)*i14+
1858                (sqw3*(sqw3-1)/2)*i14;
1859     }
1860     else if (sqw2+9 == sqEnP && 7 != TbColumn(sqw2)) {
1861         // Capture to the right
1862         sqw3 = EXCLUDE2(sqw3,sqEnP,sqEmptyEnP)-i8-2;
1863         return TbColumn(sqw2)+7+
1864                (sqw1-i8)*i14+
1865                (sqw3*(sqw3-1)/2)*i14;
1866     }
1867     else if (sqw3+7 == sqEnP && 0 != TbColumn(sqw3)) {
1868         // Capture to the left
1869         sqw2 = sqw2-i8;
1870         return TbColumn(sqw3)-1+
1871                (sqw1-i8)*i14+
1872                (sqw2*(sqw2-1)/2)*i14;
1873     }
1874     else {
1875         // Capture to the right
1876         sqw2 = sqw2-i8;
1877         return TbColumn(sqw3)+7+
1878                (sqw1-i8)*i14+
1879                (sqw2*(sqw2-1)/2)*i14;
1880     }
1881 }
1882
1883 static INLINE unsigned TB_FASTCALL IndEnPassant31B
1884     (
1885     square  sqw1,
1886     square  sqw2,
1887     square  sqw3,
1888     square  sqb,
1889     square  sqEnP
1890     )
1891 {
1892     square sqEmptyEnP = sqEnP - 8;
1893
1894     if(sqw2 - 8 == sqEnP)
1895         SWAP(sqw1, sqw2);
1896     if(sqw3 - 8 == sqEnP)
1897         SWAP(sqw1, sqw3);
1898
1899     assert(sqw1 - 8 == sqEnP);
1900
1901     SORT(sqw2, sqw3);
1902
1903     if(sqb - 9 == sqEnP && 0 != TbColumn(sqb)) {
1904         sqw3 = EXCLUDE4(sqw3,sqw1,sqb,sqEnP,sqEmptyEnP)-i8;
1905         return TbColumn(sqb)-1+
1906         (EXCLUDE4(sqw2,sqw1,sqb,sqEnP,sqEmptyEnP)-i8)*i14+
1907         (sqw3*(sqw3-1)/2)*i14;
1908     }
1909     else {
1910         assert(sqb - 7 == sqEnP && 7 != TbColumn(sqb));
1911         sqw3 = EXCLUDE4(sqw3,sqw1,sqb,sqEnP,sqEmptyEnP)-i8;
1912         return TbColumn(sqb)+7+
1913             (EXCLUDE4(sqw2,sqw1,sqb,sqEnP,sqEmptyEnP)-i8)*i14+
1914         (sqw3*(sqw3-1)/2)*i14;
1915     }
1916 }
1917
1918 // Index calculation functions for different endgame classes
1919
1920 template <int piw1> class T21
1921     {
1922 public:
1923     static INDEX TB_FASTCALL IndCalcW
1924         (
1925         square  *psqW,
1926         square  *psqB,
1927         square  sqEnP,
1928         int     fInvert
1929         )
1930         {
1931         square sqwk, sqw1, sqbk, sqMask;
1932
1933         sqwk = SqFindKing (psqW);
1934         sqw1 = SqFindOne  (psqW, piw1);
1935         sqbk = SqFindKing (psqB);
1936
1937         if (x_piecePawn == piw1)
1938             sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
1939         else
1940             sqMask = rgsqReflectMaskYandX [sqwk];
1941         sqwk ^= sqMask;
1942         sqbk ^= sqMask;
1943         sqw1 ^= sqMask;
1944
1945         if (x_piecePawn != piw1)
1946             {
1947             // No pawn
1948             if (! FInTriangle (sqwk, sqbk))
1949                 {
1950                 sqwk = reflect_xy(sqwk);
1951                 sqbk = reflect_xy(sqbk);
1952                 sqw1 = reflect_xy(sqw1);
1953                 };
1954             }
1955         return TEnumerate1<piw1,x_piecePawn==piw1 ? true : false,false>::Index(sqwk,sqw1,sqbk);
1956         }
1957
1958     static INDEX TB_FASTCALL IndCalcB
1959         (
1960         square  *psqW,
1961         square  *psqB,
1962         square  sqEnP,
1963         int     fInvert
1964         )
1965         {
1966         square sqwk, sqw1, sqbk, sqMask;
1967
1968         sqwk = SqFindKing (psqW);
1969         sqw1 = SqFindOne  (psqW, piw1);
1970         sqbk = SqFindKing (psqB);
1971
1972         if (x_piecePawn == piw1)
1973             sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
1974         else
1975             sqMask = rgsqReflectMaskYandX [sqbk];
1976         sqwk ^= sqMask;
1977         sqbk ^= sqMask;
1978         sqw1 ^= sqMask;
1979
1980         if (x_piecePawn == piw1)
1981             return TEnumerate1<x_pieceNone,true,true>::Index(sqbk,sqw1,sqwk);
1982         else
1983             {
1984             // No pawn
1985             if (! FInTriangle (sqbk, sqwk))
1986                 {
1987                 sqwk = reflect_xy(sqwk);
1988                 sqbk = reflect_xy(sqbk);
1989                 sqw1 = reflect_xy(sqw1);
1990                 };
1991             return IndTriKings(sqbk,sqwk)*i62 + EXCLUDE2(sqw1,sqwk,sqbk);
1992             }
1993         }
1994     };
1995
1996 template <int piw1, int pib1> class T22
1997     {
1998 public:
1999     static INDEX TB_FASTCALL IndCalcW
2000         (
2001         square  *psqW,
2002         square  *psqB,
2003         square  sqEnP,
2004         int     fInvert
2005         )
2006         {
2007         square sqwk, sqw1, sqbk, sqb1, sqMask;
2008
2009         sqwk = SqFindKing (psqW);
2010         sqw1 = SqFindOne  (psqW, piw1);
2011         sqbk = SqFindKing (psqB);
2012         sqb1 = SqFindOne  (psqB, pib1);
2013
2014         if (x_piecePawn == pib1)
2015             sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
2016         else
2017             sqMask = rgsqReflectMaskYandX [sqwk];
2018         sqwk ^= sqMask;
2019         sqbk ^= sqMask;
2020         sqw1 ^= sqMask;
2021         sqb1 ^= sqMask;
2022
2023         if (x_piecePawn == pib1)
2024             {
2025             // There are pawns on the board
2026             if (x_piecePawn == piw1)
2027                 {
2028                 // One white and one black pawn
2029                 if (XX == sqEnP)
2030                     return  TEnumerate1<x_piecePawn,true,false>::Index(sqwk,sqw1,sqbk)*i47 + 
2031                             EXCLUDE1(sqb1,sqw1)-i8; // 47
2032                 else
2033                     return  rgcSinglePawnPresent[x_piecePawn]*i47 +
2034                             IndHalfKings(sqwk,sqbk)*i14 +
2035                             IndEnPassant11W (sqw1, sqb1, sqEnP ^ sqMask);
2036                 }
2037             else
2038                 // Only black pawn
2039                 return  TEnumerate1<piw1,true,false>::Index(sqwk,sqw1,sqbk)*i48 + sqb1-i8;
2040             }
2041         else
2042             {
2043             // No pawns at all
2044             if (!FInTriangle (sqwk, sqbk))
2045                 {
2046                 sqwk = reflect_xy(sqwk);
2047                 sqbk = reflect_xy(sqbk);
2048                 sqw1 = reflect_xy(sqw1);
2049                 sqb1 = reflect_xy(sqb1);
2050                 };
2051             return  TEnumerate1<piw1,false,false>::Index(sqwk,sqw1,sqbk)*i61 +
2052                     EXCLUDE3(sqb1,sqwk,sqbk,sqw1);  // 61
2053             }
2054         }
2055
2056     static INDEX TB_FASTCALL IndCalcB
2057         (
2058         square  *psqW,
2059         square  *psqB,
2060         square  sqEnP,
2061         int     fInvert
2062         )
2063         {
2064         square sqwk, sqw1, sqbk, sqb1, sqMask;
2065
2066         sqwk = SqFindKing (psqW);
2067         sqw1 = SqFindOne  (psqW, piw1);
2068         sqbk = SqFindKing (psqB);
2069         sqb1 = SqFindOne  (psqB, pib1);
2070
2071         if (x_piecePawn == pib1)
2072             sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
2073         else
2074             sqMask = rgsqReflectMaskYandX [sqbk];
2075         sqwk ^= sqMask;
2076         sqbk ^= sqMask;
2077         sqw1 ^= sqMask;
2078         sqb1 ^= sqMask;
2079
2080         if (x_piecePawn == pib1)
2081             {
2082             // There are pawns on the board
2083             if (x_piecePawn == piw1)
2084                 {
2085                 // One white and one black pawn
2086                 if (XX == sqEnP)
2087                     return  TEnumerate1<x_piecePawn,true,true>::Index(sqbk,sqb1,sqwk)*i47 + 
2088                             EXCLUDE1(sqw1,sqb1)-i8; // 47
2089                 else
2090                     return  rgcSinglePawnPresent[x_piecePawn]*i47 +
2091                             IndHalfKings(sqbk,sqwk)*i14 +
2092                             IndEnPassant11B (sqw1, sqb1, sqEnP ^ sqMask);
2093                 }
2094             }
2095         else
2096             {
2097             // No pawns at all
2098             if (!FInTriangle (sqbk, sqwk))
2099                 {
2100                 sqwk = reflect_xy(sqwk);
2101                 sqbk = reflect_xy(sqbk);
2102                 sqw1 = reflect_xy(sqw1);
2103                 sqb1 = reflect_xy(sqb1);
2104                 };
2105             }
2106         return  (x_piecePawn == pib1 ?  TEnumerate1<pib1,true,true>::Index(sqbk,sqb1,sqwk) :
2107                                         TEnumerate1<pib1,false,false>::Index(sqbk,sqb1,sqwk))*i61 +
2108                 EXCLUDE3(sqw1,sqwk,sqbk,sqb1);  // 61
2109         }
2110     };
2111
2112 template <int piw1, int piw2> class T31
2113     {
2114 public:
2115     static INDEX TB_FASTCALL IndCalcW
2116         (
2117         square  *psqW,
2118         square  *psqB,
2119         square  sqEnP,
2120         int     fInvert
2121         )
2122         {
2123         square sqwk, sqw1, sqw2, sqbk, sqMask;
2124
2125         sqwk = SqFindKing (psqW);
2126         if (piw1 == piw2)
2127             {
2128             sqw1 = SqFindFirst  (psqW, piw1);
2129             sqw2 = SqFindSecond (psqW, piw2);
2130             }
2131         else
2132             {
2133             SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
2134             }
2135         sqbk = SqFindKing (psqB);
2136
2137         if (x_piecePawn == piw2)
2138             sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
2139         else
2140             sqMask = rgsqReflectMaskYandX [sqwk];
2141         sqwk ^= sqMask;
2142         sqbk ^= sqMask;
2143         sqw1 ^= sqMask;
2144         sqw2 ^= sqMask;
2145
2146         if (x_piecePawn != piw2)
2147             {
2148             // There are no pawns on the board
2149             if (!FInTriangle (sqwk, sqbk))
2150                 {
2151                 sqwk = reflect_xy(sqwk);
2152                 sqw1 = reflect_xy(sqw1);
2153                 sqw2 = reflect_xy(sqw2);
2154                 sqbk = reflect_xy(sqbk);
2155                 };
2156             }
2157         return TEnumerate2<piw1, piw2, x_piecePawn==piw2 ? true : false, false>::Index(sqwk, sqw1, sqw2, sqbk);
2158         }
2159
2160     static INDEX TB_FASTCALL IndCalcB
2161         (
2162         square  *psqW,
2163         square  *psqB,
2164         square  sqEnP,
2165         int     fInvert
2166         )
2167         {
2168         square sqwk, sqw1, sqw2, sqbk, sqMask;
2169
2170         sqwk = SqFindKing (psqW);
2171         if (piw1 == piw2)
2172             {
2173             sqw1 = SqFindFirst (psqW, piw1);
2174             sqw2 = SqFindSecond (psqW, piw2);
2175             }
2176         else
2177             {
2178             SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
2179             }
2180         sqbk = SqFindKing (psqB);
2181
2182         if (x_piecePawn == piw2)
2183             sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
2184         else
2185             sqMask = rgsqReflectMaskYandX [sqbk];
2186         sqwk ^= sqMask;
2187         sqbk ^= sqMask;
2188         sqw1 ^= sqMask;
2189         sqw2 ^= sqMask;
2190
2191         if (x_piecePawn == piw2)
2192             {
2193             // There are pawns on the board
2194             if (x_piecePawn == piw1)
2195                 // Two white pawns
2196                 return  TEnumerate2<x_pieceNone,x_pieceNone,true,true>::Index(sqbk,sqw1,sqw2,sqwk);
2197             else
2198                 // Only one white pawn
2199                 return  TEnumerate1<x_pieceNone,true,true>::Index(sqbk,sqw2,sqwk)*i61 +
2200                         EXCLUDE3(sqw1,sqwk,sqbk,sqw2);  // 61
2201             }
2202         else
2203             {
2204             // No pawns
2205             if (!FInTriangle (sqbk, sqwk))
2206                 {
2207                 sqwk = reflect_xy(sqwk);
2208                 sqw1 = reflect_xy(sqw1);
2209                 sqw2 = reflect_xy(sqw2);
2210                 sqbk = reflect_xy(sqbk);
2211                 };
2212             if (piw1 == piw2)
2213                 {
2214                 SORT (sqw1, sqw2);
2215                 sqw2 = EXCLUDE2(sqw2,sqwk,sqbk);                    // 62
2216                 return  IndTriKings(sqbk,sqwk)*(i62*i61/2) +
2217                         sqw2*(sqw2-1)/2+EXCLUDE2(sqw1,sqwk,sqbk);   // 62*61/2
2218                 }
2219             else
2220                 return  IndTriKings(sqbk,sqwk)*(i62*i61) +
2221                         EXCLUDE2(sqw1,sqwk,sqbk)*i61 +  // 62
2222                         EXCLUDE3(sqw2,sqwk,sqbk,sqw1);  // 61
2223             }
2224         }
2225     };
2226
2227 template <int piw1, int piw2, int pib1> class T32
2228     {
2229 public:
2230     static INDEX TB_FASTCALL IndCalcW
2231         (
2232         square  *psqW,
2233         square  *psqB,
2234         square  sqEnP,
2235         int     fInvert
2236         )
2237         {
2238         square sqwk, sqw1, sqw2, sqbk, sqb1, sqMask;
2239
2240         sqwk = SqFindKing (psqW);
2241         if (piw1 == piw2)
2242             {
2243             sqw1 = SqFindFirst  (psqW, piw1);
2244             sqw2 = SqFindSecond (psqW, piw2);
2245             }
2246         else
2247             {
2248             SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
2249             }
2250         sqbk = SqFindKing (psqB);
2251         sqb1 = SqFindOne  (psqB, pib1);
2252
2253         if (x_piecePawn == piw2 || x_piecePawn == pib1)
2254             sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
2255         else
2256             sqMask = rgsqReflectMaskYandX [sqwk];
2257         sqwk ^= sqMask;
2258         sqbk ^= sqMask;
2259         sqw1 ^= sqMask;
2260         sqw2 ^= sqMask;
2261         sqb1 ^= sqMask;
2262
2263         if (x_piecePawn == piw2 || x_piecePawn == pib1)
2264             {
2265             // There are pawns on the board
2266             if (x_piecePawn == pib1)
2267                 {
2268                 // Black pawn
2269                 if (x_piecePawn == piw1 && x_piecePawn == piw2)
2270                     {
2271                     // All 3 pieces are pawns
2272                     if (XX == sqEnP)
2273                         return  TEnumerate2<x_piecePawn,x_piecePawn,true,false>::
2274                                     Index(sqwk,sqw1,sqw2,sqbk)*i46+
2275                                 EXCLUDE2(sqb1,sqw1,sqw2)-i8;    // 46
2276                     else
2277                         // En passant capture
2278                         return  rgcPairPawnPresent[x_piecePawn][x_piecePawn]*i46 +
2279                                 IndHalfKings(sqwk,sqbk)*(i14*i44) +
2280                                 IndEnPassant21W (sqw1, sqw2, sqb1, sqEnP ^ sqMask);
2281                     }
2282                 else if (x_piecePawn == piw2)
2283                     {
2284                     // One white pawn, one black pawn
2285                     if (XX == sqEnP)
2286                         return  TEnumerate2<piw1,x_piecePawn,true,false>::
2287                                     Index(sqwk,sqw1,sqw2,sqbk)*i47 +
2288                                 EXCLUDE1(sqb1,sqw2)-i8; // 47
2289                     else
2290                         // En passant capture
2291                         return  rgcPairPawnPresent[piw1][x_piecePawn]*i47 +
2292                                 TEnumerate1<piw1,true,false>::Index(sqwk,sqw1,sqbk)*i14 +
2293                                 IndEnPassant11W (sqw2, sqb1, sqEnP ^ sqMask);
2294                     }
2295                 else
2296                     // Only black pawn
2297                     return  TEnumerate2<piw1,piw2,true,false>::
2298                                 Index(sqwk,sqw1,sqw2,sqbk)*i48 +
2299                             sqb1-i8;    // 48
2300                 }
2301             }
2302         else
2303             {
2304             // No pawns
2305             if (!FInTriangle (sqwk, sqbk))
2306                 {
2307                 sqwk = reflect_xy(sqwk);
2308                 sqw1 = reflect_xy(sqw1);
2309                 sqw2 = reflect_xy(sqw2);
2310                 sqbk = reflect_xy(sqbk);
2311                 sqb1 = reflect_xy(sqb1);
2312                 };
2313             }
2314         return  TEnumerate2<piw1,piw2,(x_piecePawn==piw2||x_piecePawn==pib1) ? true : false,false>::
2315                     Index(sqwk,sqw1,sqw2,sqbk)*i60 +
2316                 EXCLUDE4(sqb1,sqwk,sqbk,sqw1,sqw2); // 60
2317         }
2318
2319     static INDEX TB_FASTCALL IndCalcB
2320         (
2321         square  *psqW,
2322         square  *psqB,
2323         square  sqEnP,
2324         int     fInvert
2325         )
2326         {
2327         square sqwk, sqw1, sqw2, sqbk, sqb1, sqMask;
2328
2329         sqwk = SqFindKing (psqW);
2330         if (piw1 == piw2)
2331             {
2332             sqw1 = SqFindFirst  (psqW, piw1);
2333             sqw2 = SqFindSecond (psqW, piw2);
2334             }
2335         else
2336             {
2337             SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
2338             }
2339         sqbk = SqFindKing (psqB);
2340         sqb1 = SqFindOne  (psqB, pib1);
2341
2342         if (x_piecePawn == piw2 || x_piecePawn == pib1)
2343             sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
2344         else
2345             sqMask = rgsqReflectMaskYandX [sqbk];
2346         sqwk ^= sqMask;
2347         sqbk ^= sqMask;
2348         sqw1 ^= sqMask;
2349         sqw2 ^= sqMask;
2350         sqb1 ^= sqMask;
2351
2352         if (x_piecePawn == piw2 || x_piecePawn == pib1)
2353             {
2354             // There are pawns on the board
2355             if (x_piecePawn == pib1)
2356                 {
2357                 // Black pawn
2358                 if (x_piecePawn == piw1 && x_piecePawn == piw2)
2359                     {
2360                     // All 3 pieces are pawns
2361                     SORT (sqw1, sqw2);
2362                     if (XX == sqEnP)
2363                         {
2364                         sqw2 = EXCLUDE1(sqw2,sqb1)-i8;                  // 47
2365                         return  TEnumerate1<x_piecePawn,true,true>::
2366                                     Index(sqbk,sqb1,sqwk)*(i47*i46/2) +
2367                                 sqw2*(sqw2-1)/2+EXCLUDE1(sqw1,sqb1)-i8; // 47*46/2
2368                         }
2369                     else
2370                         // En passant capture
2371                         return  rgcSinglePawnPresent[x_piecePawn]*(i47*i46/2) +
2372                                 IndHalfKings(sqbk,sqwk)*(i44*i14) +
2373                                 IndEnPassant21B (sqw1, sqw2, sqb1, sqEnP ^ sqMask);
2374                     }
2375                 else if (x_piecePawn == piw2)
2376                     {
2377                     // One white pawn, one black pawn
2378                     if (XX == sqEnP)
2379                         return  TEnumerate1<x_piecePawn,true,true>::
2380                                     Index(sqbk,sqb1,sqwk)*(i60*i47) +
2381                                 EXCLUDE4(sqw1,sqwk,sqbk,sqw2,sqb1)*i47 +    // 60
2382                                 EXCLUDE1(sqw2,sqb1)-i8;                     // 47
2383                     else
2384                         {
2385                         // En passant capture
2386                         sqEnP ^= sqMask;
2387                         return  rgcSinglePawnPresent[x_piecePawn]*(i60*i47) +
2388                                 IndHalfKings(sqbk,sqwk)*(i58*i14) +
2389                                 EXCLUDE6(sqw1,sqwk,sqbk,sqw2,sqb1,sqEnP,sqEnP-8)*i14 +  // 58
2390                                 IndEnPassant11B (sqw2, sqb1, sqEnP);
2391                         }
2392                     }
2393                 else
2394                     {
2395                     // Only black pawn
2396                     if (piw1 == piw2)
2397                         {
2398                         // 2 identical white pieces
2399                         SORT (sqw1, sqw2);
2400                         sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1);                       // 61
2401                         return  TEnumerate1<x_piecePawn,true,true>::
2402                                     Index(sqbk,sqb1,sqwk)*(i61*i60/2) +
2403                                 sqw2*(sqw2-1)/2 + EXCLUDE3(sqw1,sqwk,sqbk,sqb1);    // 61*60/2
2404                         }
2405                     return  TEnumerate1<x_piecePawn,true,true>::
2406                                 Index(sqbk,sqb1,sqwk)*(i61*i60) +
2407                             EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*i60 + // 61
2408                             EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1); // 60
2409                     }
2410                 }
2411             else
2412                 {
2413                 // No black pawn
2414                 if (x_piecePawn == piw1)
2415                     {
2416                     // Only 2 white pawns
2417                     SORT (sqw1, sqw2);
2418                     sqw2 -= i8;
2419                     return  TEnumerate1<pib1,true,true>::
2420                                 Index(sqbk,sqb1,sqwk)*(i48*47/2) +
2421                             sqw2*(sqw2-1)/2+sqw1-i8;            // 48*47/2
2422                     }
2423                 else
2424                     // Only one white pawn
2425                     return  TEnumerate1<pib1,true,true>::
2426                                 Index(sqbk,sqb1,sqwk)*(i60*i48) +
2427                             EXCLUDE4(sqw1,sqwk,sqbk,sqw2,sqb1)*i48 +    // 60
2428                             sqw2-i8;                                    // 48
2429                 }
2430             }
2431         else
2432             {
2433             // No pawns
2434             if (!FInTriangle (sqbk, sqwk))
2435                 {
2436                 sqwk = reflect_xy(sqwk);
2437                 sqw1 = reflect_xy(sqw1);
2438                 sqw2 = reflect_xy(sqw2);
2439                 sqbk = reflect_xy(sqbk);
2440                 sqb1 = reflect_xy(sqb1);
2441                 };
2442             if (piw1 == piw2)
2443                 {
2444                 // 2 identical white pieces
2445                 SORT (sqw1, sqw2);
2446                 sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1);                   // 61
2447                 return  TEnumerate1<pib1,false,false>::
2448                             Index(sqbk,sqb1,sqwk)*(i61*i60/2) +
2449                         sqw2*(sqw2-1)/2+EXCLUDE3(sqw1,sqwk,sqbk,sqb1);  // 61*60/2
2450                 }
2451             else
2452                 return  TEnumerate1<pib1,false,false>::
2453                             Index(sqbk,sqb1,sqwk)*(i61*i60) +
2454                         EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*i60 + // 61
2455                         EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1); // 60
2456             }
2457         }
2458     };
2459
2460 #if defined (T41_INCLUDE)
2461
2462 template <int piw1, int piw2, int piw3> class T41
2463     {
2464 public:
2465     static INDEX TB_FASTCALL IndCalcW
2466         (
2467         square  *psqW,
2468         square  *psqB,
2469         square  sqEnP,
2470         int     fInvert
2471         )
2472         {
2473         square sqwk, sqw1, sqw2, sqw3, sqbk, sqMask;
2474
2475         sqwk = SqFindKing (psqW);
2476         sqw1 = SqFindFirst (psqW, piw1);
2477         if (piw1 == piw2 && piw2 == piw3)
2478             {
2479             sqw2 = SqFindSecond (psqW, piw2);
2480             sqw3 = SqFindThird (psqW, piw3);
2481             }
2482         else if (piw1 == piw2)
2483             {
2484             sqw2 = SqFindSecond (psqW, piw2);
2485             sqw3 = SqFindFirst (psqW, piw3);
2486             }
2487         else if (piw2 == piw3)
2488             {
2489             sqw2 = SqFindFirst (psqW, piw2);
2490             sqw3 = SqFindSecond (psqW, piw3);
2491             }
2492         else
2493             {
2494             sqw2 = SqFindFirst (psqW, piw2);
2495             sqw3 = SqFindFirst (psqW, piw3);
2496             }
2497         sqbk = SqFindKing (psqB);
2498
2499         if (x_piecePawn == piw3)
2500             sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
2501         else
2502             sqMask = rgsqReflectMaskYandX [sqwk];
2503         sqwk ^= sqMask;
2504         sqbk ^= sqMask;
2505         sqw1 ^= sqMask;
2506         sqw2 ^= sqMask;
2507         sqw3 ^= sqMask;
2508
2509         if (x_piecePawn != piw3)
2510             {
2511             // No pawns
2512             if (!FInTriangle (sqwk, sqbk))
2513                 {
2514                 sqwk = reflect_xy(sqwk);
2515                 sqw1 = reflect_xy(sqw1);
2516                 sqw2 = reflect_xy(sqw2);
2517                 sqw3 = reflect_xy(sqw3);
2518                 sqbk = reflect_xy(sqbk);
2519                 };
2520             }
2521         return  TEnumerate3<piw1,piw2,piw3,x_piecePawn == piw3,false>::Index(sqwk,sqw1,sqw2,sqw3,sqbk);
2522         }
2523
2524     static INDEX TB_FASTCALL IndCalcB
2525         (
2526         square  *psqW,
2527         square  *psqB,
2528         square  sqEnP,
2529         int     fInvert
2530         )
2531         {
2532         square sqwk, sqw1, sqw2, sqw3, sqbk, sqMask;
2533
2534         sqwk = SqFindKing (psqW);
2535         sqw1 = SqFindFirst (psqW, piw1);
2536         if (piw1 == piw2 && piw2 == piw3)
2537             {
2538             sqw2 = SqFindSecond (psqW, piw2);
2539             sqw3 = SqFindThird (psqW, piw3);
2540             }
2541         else if (piw1 == piw2)
2542             {
2543             sqw2 = SqFindSecond (psqW, piw2);
2544             sqw3 = SqFindFirst (psqW, piw3);
2545             }
2546         else if (piw2 == piw3)
2547             {
2548             sqw2 = SqFindFirst (psqW, piw2);
2549             sqw3 = SqFindSecond (psqW, piw3);
2550             }
2551         else
2552             {
2553             sqw2 = SqFindFirst (psqW, piw2);
2554             sqw3 = SqFindFirst (psqW, piw3);
2555             }
2556         sqbk = SqFindKing (psqB);
2557
2558         if (x_piecePawn == piw3)
2559             sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
2560         else
2561             sqMask = rgsqReflectMaskYandX [sqbk];
2562         sqwk ^= sqMask;
2563         sqbk ^= sqMask;
2564         sqw1 ^= sqMask;
2565         sqw2 ^= sqMask;
2566         sqw3 ^= sqMask;
2567
2568         if (x_piecePawn == piw3)
2569             {
2570             // There are pawns on the board
2571             if (x_piecePawn == piw1)
2572                 // 3 white pawns
2573                 return  TEnumerate3<x_pieceNone,x_pieceNone,x_pieceNone,true,true>::
2574                             Index(sqbk,sqw1,sqw2,sqw3,sqwk);
2575             else if (x_piecePawn == piw2)
2576                 // 2 white pawns
2577                 return  TEnumerate2<x_pieceNone,x_pieceNone,true,true>::
2578                             Index(sqbk,sqw2,sqw3,sqwk)*i60 +
2579                         EXCLUDE4(sqw1,sqwk,sqbk,sqw2,sqw3); // 60
2580             else if (piw1 == piw2)
2581                 {
2582                 // 1 pawn, 2 pieces equal
2583                 SORT (sqw1, sqw2);
2584                 sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqw3);                   // 61
2585                 return  TEnumerate1<x_pieceNone,true,true>::
2586                             Index(sqbk,sqw3,sqwk)*(i61*i60/2) +
2587                         sqw2*(sqw2-1)/2+EXCLUDE3(sqw1,sqwk,sqbk,sqw3);  // 61*60/2
2588                 }
2589             else
2590                 // Only one white pawn
2591                 return  TEnumerate1<x_pieceNone,true,true>::Index(sqbk,sqw3,sqwk)*i61*i60 +
2592                         EXCLUDE3(sqw1,sqwk,sqbk,sqw3)*i60 + // 61
2593                         EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqw3); // 60
2594             }
2595         else
2596             {
2597             // No pawns
2598             if (!FInTriangle (sqbk, sqwk))
2599                 {
2600                 sqwk = reflect_xy(sqwk);
2601                 sqw1 = reflect_xy(sqw1);
2602                 sqw2 = reflect_xy(sqw2);
2603                 sqw3 = reflect_xy(sqw3);
2604                 sqbk = reflect_xy(sqbk);
2605                 };
2606             if (piw1 == piw2 && piw2 == piw3)
2607                 {
2608                 // All 3 pieces equal
2609                 SORT (sqw1, sqw2);
2610                 SORT (sqw2, sqw3);
2611                 SORT (sqw1, sqw2);
2612                 sqw3 = EXCLUDE2(sqw3,sqwk,sqbk);    // 62
2613                 sqw2 = EXCLUDE2(sqw2,sqwk,sqbk);
2614                 return  IndTriKings(sqbk,sqwk)*(i62*i61*i60/6) +
2615                         sqw3*(sqw3-1)*(sqw3-2)/6+
2616                         sqw2*(sqw2-1)/2+
2617                         EXCLUDE2(sqw1,sqwk,sqbk);   // 62*61*60/6
2618                 }
2619             else if (piw1 == piw2)
2620                 {
2621                 // 2 major pieces equal
2622                 SORT (sqw1, sqw2);
2623                 sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqw3);                           // 61
2624                 return  IndTriKings(sqbk,sqwk)*(i61*i60/2*i62) +
2625                         (sqw2*(sqw2-1)/2+EXCLUDE3(sqw1,sqwk,sqbk,sqw3))*i62 +   // 61*60/2
2626                         EXCLUDE2(sqw3,sqwk,sqbk);                               // 62
2627                 }
2628             else if (piw2 == piw3)
2629                 {
2630                 // 2 minor pieces equal
2631                 SORT (sqw2, sqw3);
2632                 sqw3 = EXCLUDE3(sqw3,sqwk,sqbk,sqw1);                   // 61
2633                 return  IndTriKings(sqbk,sqwk)*(i62*i61*i60/2) +
2634                         EXCLUDE2(sqw1,sqwk,sqbk)*(i61*i60/2) +          // 62
2635                         sqw3*(sqw3-1)/2+EXCLUDE3(sqw2,sqwk,sqbk,sqw1);  // 61*60/2
2636                 }
2637             else
2638                 return  IndTriKings(sqbk,sqwk)*(i62*i61*i60) +
2639                         EXCLUDE2(sqw1,sqwk,sqbk)*(i61*i60) +    // 62
2640                         EXCLUDE3(sqw2,sqwk,sqbk,sqw1)*i60 +     // 61
2641                         EXCLUDE4(sqw3,sqwk,sqbk,sqw1,sqw2);     // 60
2642             }
2643         }
2644     };
2645
2646 #endif  // T41
2647
2648 #if defined (ILLEGAL_POSSIBLE)
2649
2650 #define CHECK_INF_SINGLE(ind)\
2651         if (INF_SINGLE == ind)\
2652             return (INDEX) -1;\
2653
2654 #define CHECK_INF_PAIR(ind)\
2655         if (INF_PAIR == ind)\
2656             return (INDEX) -1;\
2657
2658 #define CHECK_INF_TRIPLE(ind)\
2659         if (INF_TRIPLE == ind)\
2660             return (INDEX) -1;\
2661
2662 #else
2663
2664 #define CHECK_INF_SINGLE(ind)
2665 #define CHECK_INF_PAIR(ind)
2666 #define CHECK_INF_TRIPLE(ind)
2667
2668 #endif
2669
2670 #if defined (T33_INCLUDE)
2671
2672 template <int piw1, int piw2, int pib1, int pib2> class T33
2673 {
2674 public:
2675     static INDEX TB_FASTCALL IndCalcW
2676         (
2677         square  *psqW,
2678         square  *psqB,
2679         square  sqEnP,
2680         int     fInvert
2681         )
2682     {
2683         square   sqwk, sqw1, sqw2, sqbk, sqb1, sqb2, sqMask;
2684         unsigned uInd;
2685
2686         sqwk = SqFindKing (psqW);
2687         if (piw1 == piw2) {
2688             sqw1 = SqFindFirst  (psqW, piw1);
2689             sqw2 = SqFindSecond (psqW, piw2);
2690             }
2691         else {
2692             SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
2693             }
2694         sqbk = SqFindKing (psqB);
2695         if (pib1 == pib2) {
2696             sqb1 = SqFindFirst  (psqB, pib1);
2697             sqb2 = SqFindSecond (psqB, pib2);
2698             }
2699         else {
2700             SqFind2 (psqB, pib1, sqb1, pib2, sqb2);
2701             }
2702
2703         if(x_piecePawn == piw2 || x_piecePawn == pib2)
2704             sqMask = rgsqReflectMaskY[sqwk] ^ rgsqReflectInvertMask[fInvert];
2705         else
2706             sqMask = rgsqReflectMaskYandX[sqwk];
2707
2708         sqwk ^= sqMask;
2709         sqbk ^= sqMask;
2710         sqw1 ^= sqMask;
2711         sqw2 ^= sqMask;
2712         sqb1 ^= sqMask;
2713         sqb2 ^= sqMask;
2714
2715         if(x_piecePawn == piw2 || x_piecePawn == pib2) {
2716             // There are pawns on the board
2717             if(XX == sqEnP) {
2718                 // No En Passant possible
2719                 uInd = TEnumerate2<piw1,piw2,true,false>::Index(sqwk,sqw1,sqw2,sqbk);
2720                 CHECK_INF_PAIR(uInd);
2721                 if(x_piecePawn == piw1) {
2722                     // all 4 pieces are pawns
2723                     SORT(sqb1, sqb2);
2724                     sqb2 = EXCLUDE2(sqb2,sqw1,sqw2) - i8;
2725                     return uInd*(INDEX)(i46*i45/2) +
2726                            sqb2*(sqb2-1)/2 + EXCLUDE2(sqb1,sqw1,sqw2) - i8;
2727                 }
2728                 else if(x_piecePawn == piw2) {
2729                     if(x_piecePawn == pib1) {
2730                         // 1 white, 2 black pawns
2731                         SORT(sqb1, sqb2);
2732                         sqb2 = EXCLUDE1(sqb2,sqw2) - i8;
2733                         return uInd*(INDEX)(i47*i46/2) +
2734                                sqb2*(sqb2-1)/2 + EXCLUDE1(sqb1,sqw2) - i8;
2735                     }
2736                     else if(x_piecePawn == pib2) {
2737                         // 1 white, 1 black pawn
2738                         return uInd*(INDEX)(i59*i47) +
2739                                (EXCLUDE1(sqb2,sqw2)-i8)*i59 +
2740                                EXCLUDE5(sqb1,sqb2,sqwk,sqw1,sqw2,sqbk);
2741                     }
2742                     else if(pib2 == pib1) {
2743                         // only 1 white pawn, two identical black pieces
2744                         SORT(sqb1, sqb2);
2745                         sqb2 = EXCLUDE4(sqb2,sqwk,sqw1,sqw2,sqbk);
2746                         return uInd*(INDEX)(i60*i59/2) +
2747                                sqb2*(sqb2-1)/2 +
2748                                EXCLUDE4(sqb1,sqwk,sqw1,sqw2,sqbk);
2749                     }
2750                     else {
2751                         // only 1 white pawn, two different black pieces
2752                         return uInd*(INDEX)(i60*i59) +
2753                                EXCLUDE4(sqb2,sqwk,sqw1,sqw2,sqbk)*i59 +
2754                                EXCLUDE5(sqb1,sqb2,sqwk,sqw1,sqw2,sqbk);
2755                     }
2756                 }
2757                 else if(x_piecePawn == pib1) {
2758                     // no white pawns, two black pawns
2759                     SORT(sqb1, sqb2);
2760                     sqb2 -= i8;
2761                     return uInd*(INDEX)(i48*i47/2) +
2762                            sqb2*(sqb2-1)/2 + sqb1 - i8;
2763                 }
2764                 else {
2765                     // no white pawns, 1 black pawn
2766                     return uInd*(INDEX)(i48*i59) +
2767                            (sqb2 - i8)*i59 +
2768                            EXCLUDE5(sqb1,sqb2,sqwk,sqw1,sqw2,sqbk);
2769                 }
2770             }
2771             else {
2772                 // En Passant possible
2773                 sqEnP ^= sqMask;
2774                 if(x_piecePawn == piw1) {
2775                     // all 4 pieces are pawns
2776                     uInd = rgcPairPawnPresent[x_piecePawn][x_piecePawn];
2777                     return uInd*(INDEX)(i46*i45/2) +
2778                            IndHalfKings(sqwk,sqbk)*(i14*i44*i43) +
2779                            IndEnPassant22W(sqw1, sqw2, sqb1, sqb2, sqEnP);
2780                 }
2781                 else {
2782                     assert(x_piecePawn == piw2);
2783
2784                     uInd = TEnumerate1<piw1, true, false>::
2785                            Index(sqwk,sqw1,sqbk);
2786                     CHECK_INF_SINGLE(uInd);
2787
2788                     if(x_piecePawn == pib1) {
2789                         // 1 white pawn, 2 black pawns
2790                         return rgcPairPawnPresent[piw1][x_piecePawn]*((INDEX)(i47*i46/2)) +
2791                                (uInd*(i14*i44) +
2792                                 IndEnPassant12W(sqw2, sqb1, sqb2, sqEnP));
2793                     }
2794                     else {
2795                         // 1 white pawn, 1 black pawn
2796                         assert(x_piecePawn == pib2);
2797                         return rgcPairPawnPresent[piw1][x_piecePawn]*((INDEX)(i47*i59))+
2798                                (uInd*(i14*i57) +
2799                                  EXCLUDE7(sqb1,sqb2,sqwk,sqw1,sqw2,sqbk,sqEnP,sqEnP+8)*i14+
2800                                  IndEnPassant11W(sqw2,sqb2,sqEnP));
2801                     }
2802                 }
2803             }
2804         }
2805         else {
2806             // no pawns at all
2807             if (!FInTriangle (sqwk, sqbk)) {
2808                 sqwk = reflect_xy(sqwk);
2809                 sqw1 = reflect_xy(sqw1);
2810                 sqw2 = reflect_xy(sqw2);
2811                 sqbk = reflect_xy(sqbk);
2812                 sqb1 = reflect_xy(sqb1);
2813                 sqb2 = reflect_xy(sqb2);
2814                 }
2815
2816             uInd = TEnumerate2<piw1,piw2,false,false>::Index(sqwk,sqw1,sqw2,sqbk);
2817             CHECK_INF_PAIR(uInd);
2818             if (pib1 == pib2) {
2819                 SORT (sqb1, sqb2);
2820                 sqb2 = EXCLUDE4(sqb2,sqwk,sqbk,sqw1,sqw2);
2821                 return  uInd*(i60*i59/2) +
2822                         sqb2*(sqb2-1)/2+
2823                         EXCLUDE4(sqb1,sqwk,sqbk,sqw1,sqw2);
2824                 }
2825             else {
2826                 // Divide by 2 to avoid overflow on the 32-bit systems, later
2827                 // add to itself to produce the correct result. Only the final
2828                 // addition have to be done using 64-bit arithmetic.
2829                 uInd *= (i60*i59/2);
2830                 return  ((INDEX) uInd) +
2831                           (INDEX) (uInd +
2832                             EXCLUDE4(sqb1,sqwk,sqbk,sqw1,sqw2)*i59 +
2833                             EXCLUDE5(sqb2,sqwk,sqbk,sqw1,sqw2,sqb1));
2834                 }
2835             }
2836     }
2837
2838     static INDEX TB_FASTCALL IndCalcB
2839         (
2840         square  *psqW,
2841         square  *psqB,
2842         square  sqEnP,
2843         int     fInvert
2844         )
2845     {
2846         square   sqwk, sqw1, sqw2, sqbk, sqb1, sqb2, sqMask;
2847         unsigned uInd;
2848
2849         sqwk = SqFindKing (psqW);
2850         if (piw1 == piw2) {
2851             sqw1 = SqFindFirst  (psqW, piw1);
2852             sqw2 = SqFindSecond (psqW, piw2);
2853             }
2854         else {
2855             SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
2856             }
2857         sqbk = SqFindKing (psqB);
2858         if (pib1 == pib2) {
2859             sqb1 = SqFindFirst  (psqB, pib1);
2860             sqb2 = SqFindSecond (psqB, pib2);
2861             }
2862         else {
2863             SqFind2 (psqB, pib1, sqb1, pib2, sqb2);
2864             }
2865
2866         if(piw2 == x_piecePawn || pib2 == x_piecePawn)
2867             sqMask = rgsqReflectMaskY[sqbk] ^ rgsqReflectInvertMask[fInvert];
2868         else
2869             sqMask = rgsqReflectMaskYandX[sqbk];
2870
2871         sqwk ^= sqMask;
2872         sqw1 ^= sqMask;
2873         sqw2 ^= sqMask;
2874         sqbk ^= sqMask;
2875         sqb1 ^= sqMask;
2876         sqb2 ^= sqMask;
2877
2878         if(x_piecePawn == piw2 || x_piecePawn == pib2) {
2879             // There are pawns on the board
2880             if(XX == sqEnP) {
2881                 // No En Passant possible
2882                 uInd = TEnumerate2<pib1,pib2,true,true>::Index(sqbk,sqb1,sqb2,sqwk);
2883                 CHECK_INF_PAIR(uInd);
2884                 if(x_piecePawn == piw1) {
2885                     // all 4 pieces are pawns
2886                     SORT(sqw1, sqw2);
2887                     sqw2 = EXCLUDE2(sqw2,sqb1,sqb2) - i8;
2888                     return uInd*(INDEX)(i46*i45/2) +
2889                            sqw2*(sqw2-1)/2 + EXCLUDE2(sqw1,sqb1,sqw2) - i8;
2890                 }
2891                 else if(x_piecePawn == piw2) {
2892                     if(x_piecePawn == pib1) {
2893                         // 1 white, 2 black pawns
2894                         return uInd*(INDEX)(i46*i59) +
2895                                (EXCLUDE2(sqw2,sqb1,sqb2)-i8)*i59 +
2896                                EXCLUDE5(sqw1,sqw2,sqb1,sqb2,sqwk,sqbk);
2897                     }
2898                     else if(x_piecePawn == pib2) {
2899                         // 1 white, 1 black pawn
2900                         return uInd*(INDEX)(i47*i59) +
2901                                (EXCLUDE1(sqw2,sqb2)-i8)*i59 +
2902                                EXCLUDE5(sqw1,sqw2,sqb1,sqb2,sqwk,sqbk);
2903                     }
2904                     else {
2905                         // only 1 white pawn
2906                         return uInd*(INDEX)(i48*i59) +
2907                                (sqw2 - i8)*i59 +
2908                                EXCLUDE5(sqw1,sqw2,sqb1,sqb2,sqwk,sqbk);
2909                     }
2910                 }
2911                 else if(piw1 == piw2) {
2912                     // no white pawns, two identical white pieces
2913                     SORT(sqw1, sqw2);
2914                     sqw2 = EXCLUDE4(sqw2,sqb1,sqb2,sqwk,sqbk);
2915                     return uInd*(INDEX)(i60*i59/2) +
2916                            sqw2*(sqw2-1)/2 +
2917                            EXCLUDE4(sqw1,sqb1,sqb2,sqwk,sqbk);
2918                 }
2919                 else {
2920                     // no white pawns, two different white pieces
2921                     return uInd*(INDEX)(i60*i59) +
2922                            EXCLUDE4(sqw2,sqb1,sqb2,sqwk,sqbk)*i59 +
2923                            EXCLUDE5(sqw1,sqw2,sqb1,sqb2,sqwk,sqbk);
2924                 }
2925             }
2926             else {
2927                 // En Passant possible
2928                 sqEnP ^= sqMask;
2929                 if(x_piecePawn == piw1) {
2930                     // all 4 pieces are pawns
2931                     uInd = rgcPairPawnPresent[x_piecePawn][x_piecePawn];
2932                     return uInd*(INDEX)(i46*i45/2) +
2933                            IndHalfKings(sqbk,sqwk)*(i14*i44*i43) +
2934                            IndEnPassant22B(sqw1, sqw2, sqb1, sqb2, sqEnP);
2935                 }
2936                 else if(x_piecePawn == pib1) {
2937                     // 1 white, 2 black pawns
2938                     assert(x_piecePawn == piw2);
2939                     uInd = rgcPairPawnPresent[x_piecePawn][x_piecePawn];
2940                     return uInd*(INDEX)(i46*i59) +
2941                            IndHalfKings(sqbk,sqwk)*(i14*i44*i57) +
2942                            EXCLUDE7(sqw1,sqw2,sqb1,sqb2,sqbk,sqwk,sqEnP,sqEnP-8)*(i44*i14)+
2943                            IndEnPassant12B(sqw2, sqb1, sqb2, sqEnP);
2944                 }
2945                 else {
2946                     // 1 white, 1 black pawn
2947                     assert(x_piecePawn == piw2 && x_piecePawn == pib2);
2948                     uInd = TEnumerate1<pib1, true, true>::
2949                            Index(sqbk,sqb1,sqwk);
2950                     CHECK_INF_SINGLE(uInd);
2951                     return rgcPairPawnPresent[pib1][x_piecePawn]*((INDEX)(i47*i59)) +
2952                            (uInd*(i14*i57) +
2953                             EXCLUDE7(sqw1,sqw2,sqb1,sqb2,sqwk,sqbk,sqEnP,sqEnP-8)*i14 +
2954                             IndEnPassant11B(sqw2,sqb2,sqEnP));
2955                 }
2956             }
2957         }
2958         else {
2959             // no pawns at all
2960             if (!FInTriangle (sqbk, sqwk)) {
2961             sqwk = reflect_xy(sqwk);
2962             sqw1 = reflect_xy(sqw1);
2963             sqw2 = reflect_xy(sqw2);
2964             sqbk = reflect_xy(sqbk);
2965             sqb1 = reflect_xy(sqb1);
2966             sqb2 = reflect_xy(sqb2);
2967             }
2968             uInd = TEnumerate2<pib1,pib2,false,false>::Index(sqbk,sqb1,sqb2,sqwk);
2969             CHECK_INF_PAIR(uInd);
2970             if (piw1 == piw2) {
2971             SORT (sqw1, sqw2);
2972                 sqw2 = EXCLUDE4(sqw2,sqbk,sqwk,sqb1,sqb2);
2973                 return  uInd*(i60*i59/2) +
2974                     sqw2*(sqw2-1)/2+
2975                         EXCLUDE4(sqw1,sqbk,sqwk,sqb1,sqb2);
2976             }
2977             else {
2978             // Divide by 2 to avoid overflow on the 32-bit systems, later
2979             // add to itself to produce the correct result. Only the final
2980                 // addition have to be done using 64-bit arithmetic.
2981                 uInd *= (i60*i59/2);
2982                 return  ((INDEX) uInd) +
2983                          (INDEX) (uInd +
2984                           EXCLUDE4(sqw1,sqbk,sqwk,sqb1,sqb2)*i59 +
2985                            EXCLUDE5(sqw2,sqbk,sqwk,sqb1,sqb2,sqw1));
2986             }
2987         }
2988     }
2989
2990     // IndCalcBF should replace IndCalcB for symmetric endgames
2991
2992     static INDEX TB_FASTCALL IndCalcBF
2993         (
2994         square  *psqW,
2995         square  *psqB,
2996         square  sqEnP,
2997         int fInvert
2998         )
2999     {
3000             return IndCalcW(psqB, psqW, sqEnP, !fInvert);
3001     }
3002 };
3003
3004 #endif  // T33
3005
3006 #if defined (T42_INCLUDE)
3007
3008 // TODO: Add code for the TBs with pawns
3009
3010 template <int piw1, int piw2, int piw3, int pib1> class T42
3011     {
3012 public:
3013     static INDEX TB_FASTCALL IndCalcW
3014         (
3015         square  *psqW,
3016         square  *psqB,
3017         square  sqEnP,
3018         int     fInvert
3019         )
3020         {
3021         unsigned uInd;
3022         square sqwk, sqw1, sqw2, sqw3, sqbk, sqb1, sqMask;
3023
3024         sqwk = SqFindKing (psqW);
3025         sqw1 = SqFindFirst (psqW, piw1);
3026         if (piw1 == piw2 && piw2 == piw3)
3027             {
3028             sqw2 = SqFindSecond (psqW, piw2);
3029             sqw3 = SqFindThird (psqW, piw3);
3030             }
3031         else if (piw1 == piw2)
3032             {
3033             sqw2 = SqFindSecond (psqW, piw2);
3034             sqw3 = SqFindFirst (psqW, piw3);
3035             }
3036         else if (piw2 == piw3)
3037             {
3038             sqw2 = SqFindFirst (psqW, piw2);
3039             sqw3 = SqFindSecond (psqW, piw3);
3040             }
3041         else
3042             {
3043             sqw2 = SqFindFirst (psqW, piw2);
3044             sqw3 = SqFindFirst (psqW, piw3);
3045             }
3046         sqbk = SqFindKing (psqB);
3047         sqb1 = SqFindOne  (psqB, pib1);
3048
3049         if (x_piecePawn == piw3 || x_piecePawn == pib1)
3050             sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
3051         else
3052             sqMask = rgsqReflectMaskYandX [sqwk];
3053         sqwk ^= sqMask;
3054         sqbk ^= sqMask;
3055         sqw1 ^= sqMask;
3056         sqw2 ^= sqMask;
3057         sqw3 ^= sqMask;
3058         sqb1 ^= sqMask;
3059
3060         if (x_piecePawn == piw3 || x_piecePawn == pib1)
3061             {
3062             // There are pawns on the board
3063             if (x_piecePawn == pib1)
3064                 {
3065                 // Black pawn
3066                 if (x_piecePawn == piw1)
3067                     {
3068                     // All 4 pieces are pawns
3069                     if (XX == sqEnP)
3070                         {
3071                         uInd = TEnumerate3<x_piecePawn,x_piecePawn,x_piecePawn,true,false>::
3072                                 Index(sqwk,sqw1,sqw2,sqw3,sqbk);
3073                         CHECK_INF_TRIPLE(uInd);
3074                         return uInd*i45 + EXCLUDE3(sqb1,sqw1,sqw2,sqw3)-i8; // 45
3075                         }
3076                     else
3077                         {
3078                         // En passant capture
3079                         uInd = rgcTriplePawnPresent[x_piecePawn][x_piecePawn][x_piecePawn];
3080                         return  uInd*i45 +
3081                                 IndHalfKings(sqwk,sqbk)*(i14*i44*i43/2) +
3082                                 IndEnPassant31W (sqw1, sqw2, sqw3, sqb1, sqEnP ^ sqMask);
3083                         }
3084                     }
3085                 else if (x_piecePawn == piw2)
3086                     {
3087                     // Two white pawns, one black pawn
3088                     if (XX == sqEnP)
3089                         {
3090                         uInd = TEnumerate3<piw1,x_piecePawn,x_piecePawn,true,false>::
3091                                 Index(sqwk,sqw1,sqw2,sqw3,sqbk);
3092                         CHECK_INF_TRIPLE(uInd);
3093                         return uInd*(INDEX)i46 + (EXCLUDE2(sqb1,sqw2,sqw3)-i8);   // 46
3094                         }
3095                     else
3096                         {
3097                         // En passant capture
3098                         uInd = TEnumerate1<piw1,true,false>::Index(sqwk,sqw1,sqbk);
3099                         CHECK_INF_SINGLE(uInd);
3100                         return  rgcTriplePawnPresent[piw1][x_piecePawn][x_piecePawn]*(INDEX)i46 +
3101                                 (uInd*(i14*i44) + IndEnPassant21W (sqw2, sqw3, sqb1, sqEnP ^ sqMask));
3102                         }
3103                     }
3104                 else if (x_piecePawn == piw3)
3105                     {
3106                     // One white pawn, one black pawn
3107                     if (XX == sqEnP)
3108                         {
3109                         uInd = TEnumerate3<piw1,piw2,x_piecePawn,true,false>::
3110                                 Index(sqwk,sqw1,sqw2,sqw3,sqbk);
3111                         CHECK_INF_TRIPLE(uInd);
3112                         return  uInd*((INDEX)i47) + (EXCLUDE1(sqb1,sqw3)-i8);    // 47
3113                         }
3114                     else
3115                         {
3116                         // En passant capture
3117                         uInd = TEnumerate2<piw1,piw2,true,false>::Index(sqwk,sqw1,sqw2,sqbk);
3118                         CHECK_INF_PAIR(uInd);
3119                         return  rgcTriplePawnPresent[piw1][piw2][x_piecePawn]*(INDEX)i47 +
3120                                 (uInd*i14 + IndEnPassant11W (sqw3, sqb1, sqEnP ^ sqMask));
3121                         }
3122                     }
3123                 else
3124                     {
3125                     // Only black pawn
3126                     uInd = TEnumerate3<piw1,piw2,piw3,true,false>::
3127                             Index(sqwk,sqw1,sqw2,sqw3,sqbk);
3128                     CHECK_INF_TRIPLE(uInd);
3129                     return  (uInd*3)*(INDEX)16 + (sqb1-i8); // 48
3130                     }
3131                 }
3132             else
3133                 {
3134                 // No black pawn
3135                 uInd = TEnumerate3<piw1,piw2,piw3,true,false>::
3136                     Index(sqwk,sqw1,sqw2,sqw3,sqbk);
3137                 CHECK_INF_TRIPLE(uInd);
3138                 return uInd*(INDEX)i59 + EXCLUDE5(sqb1,sqwk,sqbk,sqw1,sqw2,sqw3);    // 59
3139                 }
3140             }
3141         else
3142             {
3143             // No pawns
3144             if (!FInTriangle (sqwk, sqbk))
3145                 {
3146                 sqwk = reflect_xy(sqwk);
3147                 sqw1 = reflect_xy(sqw1);
3148                 sqw2 = reflect_xy(sqw2);
3149                 sqw3 = reflect_xy(sqw3);
3150                 sqbk = reflect_xy(sqbk);
3151                 sqb1 = reflect_xy(sqb1);
3152                 };
3153             uInd = TEnumerate3<piw1,piw2,piw3,false,false>::Index(sqwk,sqw1,sqw2,sqw3,sqbk);
3154             CHECK_INF_TRIPLE(uInd);
3155             return uInd*(INDEX)i59 + EXCLUDE5(sqb1,sqwk,sqbk,sqw1,sqw2,sqw3);   // 59
3156             }
3157         }
3158
3159     static INDEX TB_FASTCALL IndCalcB
3160         (
3161         square  *psqW,
3162         square  *psqB,
3163         square  sqEnP,
3164         int     fInvert
3165         )
3166         {
3167         unsigned uInd;
3168         square sqwk, sqw1, sqw2, sqw3, sqbk, sqb1, sqMask, sqTemp;
3169
3170         sqwk = SqFindKing (psqW);
3171         sqw1 = SqFindFirst (psqW, piw1);
3172         if (piw1 == piw2 && piw2 == piw3)
3173             {
3174             sqw2 = SqFindSecond (psqW, piw2);
3175             sqw3 = SqFindThird (psqW, piw3);
3176             }
3177         else if (piw1 == piw2)
3178             {
3179             sqw2 = SqFindSecond (psqW, piw2);
3180             sqw3 = SqFindFirst (psqW, piw3);
3181             }
3182         else if (piw2 == piw3)
3183             {
3184             sqw2 = SqFindFirst (psqW, piw2);
3185             sqw3 = SqFindSecond (psqW, piw3);
3186             }
3187         else
3188             {
3189             sqw2 = SqFindFirst (psqW, piw2);
3190             sqw3 = SqFindFirst (psqW, piw3);
3191             }
3192         sqbk = SqFindKing (psqB);
3193         sqb1 = SqFindOne  (psqB, pib1);
3194
3195         if (x_piecePawn == piw3 || x_piecePawn == pib1)
3196             sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
3197         else
3198             sqMask = rgsqReflectMaskYandX [sqbk];
3199         sqwk ^= sqMask;
3200         sqbk ^= sqMask;
3201         sqw1 ^= sqMask;
3202         sqw2 ^= sqMask;
3203         sqw3 ^= sqMask;
3204         sqb1 ^= sqMask;
3205
3206         if (x_piecePawn == piw3 || x_piecePawn == pib1)
3207             {
3208             // There are pawns on the board
3209             if (x_piecePawn == pib1)
3210                 {
3211                 // Black pawn
3212                 if (x_piecePawn == piw1)
3213                     {
3214                     // All 4 pieces are pawns
3215                     SORT (sqw1, sqw2);
3216                     SORT (sqw2, sqw3);
3217                     SORT (sqw1, sqw2);
3218                     if (XX == sqEnP)
3219                         {
3220                         sqw3 = EXCLUDE1(sqw3,sqb1)-i8;                  // 47
3221                         sqw2 = EXCLUDE1(sqw2,sqb1)-i8;                  // 47
3222                         uInd = TEnumerate1<x_piecePawn,true,true>::Index(sqbk,sqb1,sqwk);
3223                         CHECK_INF_SINGLE(uInd);
3224                         return  uInd*(i47*i46*i45/6) +
3225                                 sqw3*(sqw3-1)*(sqw3-2)/6 +
3226                                 sqw2*(sqw2-1)/2 +
3227                                 EXCLUDE1(sqw1,sqb1)-i8; // 47*46*45/6
3228                         }
3229                     else
3230                         // En passant capture
3231                         return  rgcSinglePawnPresent[x_piecePawn]*(i47*i46*i45/6) +
3232                                 IndHalfKings(sqbk,sqwk)*(i44*i43/2*i14) +
3233                                 IndEnPassant31B (sqw1, sqw2, sqw3, sqb1, sqEnP ^ sqMask);
3234                     }
3235                 else if (x_piecePawn == piw2)
3236                     {
3237                     // Two white pawns, one black pawn
3238                     SORT (sqw2, sqw3);
3239                     if (XX == sqEnP)
3240                         {
3241                         sqTemp = EXCLUDE1(sqw3,sqb1)-i8;                    // 47
3242                         uInd = TEnumerate1<x_piecePawn,true,true>::
3243                                     Index(sqbk,sqb1,sqwk);
3244                         CHECK_INF_SINGLE(uInd);
3245                         return (uInd*(i59*i47)*(INDEX)(i46/2)) +
3246                                 (EXCLUDE5(sqw1,sqwk,sqbk,sqw2,sqw3,sqb1)*(i47*i46/2) +  // 59
3247                                  sqTemp*(sqTemp-1)/2 +
3248                                  EXCLUDE1(sqw2,sqb1)-i8);   // 47*46/2
3249                         }
3250                     else
3251                         {
3252                         // En passant capture
3253                         sqEnP ^= sqMask;
3254                         uInd = rgcSinglePawnPresent[x_piecePawn];
3255                         return (uInd*(i59*i47))*(INDEX)(i46/2) +
3256                                 (IndHalfKings(sqbk,sqwk)*(i57*i44*i14) +
3257                                  EXCLUDE7(sqw1,sqwk,sqbk,sqw2,sqw3,sqb1,sqEnP,sqEnP-8)*(i44*i14) +  // 57
3258                                  IndEnPassant21B (sqw2, sqw3, sqb1, sqEnP));
3259                         }
3260                     }
3261                 else if (x_piecePawn == piw3)
3262                     {
3263                     // One white pawn, one black pawn
3264                     if (piw1 == piw2)
3265                         {
3266                         // Two identical white pieces
3267                         SORT (sqw1, sqw2);
3268                         if (XX == sqEnP)
3269                             {
3270                             sqw2 = EXCLUDE4(sqw2,sqwk,sqbk,sqw3,sqb1);
3271                             sqw1 = EXCLUDE4(sqw1,sqwk,sqbk,sqw3,sqb1);
3272                             uInd = TEnumerate1<x_piecePawn,true,true>::Index(sqbk,sqb1,sqwk);
3273                             CHECK_INF_SINGLE(uInd);
3274                             return  (uInd*(i59*i47))*((INDEX)i60/2) +
3275                                     ((sqw2*(sqw2-1)/2+sqw1)*i47 +   // 60*59/2
3276                                      EXCLUDE1(sqw3,sqb1)-i8);           // 47
3277                             }
3278                         else
3279                             {
3280                             // En passant capture
3281                             sqEnP ^= sqMask;
3282                             sqw2 = EXCLUDE6(sqw2,sqwk,sqbk,sqw3,sqb1,sqEnP,sqEnP-8);
3283                             sqw1 = EXCLUDE6(sqw1,sqwk,sqbk,sqw3,sqb1,sqEnP,sqEnP-8);
3284                             uInd = rgcSinglePawnPresent[x_piecePawn];
3285                             return  (uInd*(i59*i47))*((INDEX)i60/2) +
3286                                     (IndHalfKings(sqbk,sqwk)*(i58*i57/2*i14) +
3287                                      (sqw2*(sqw2-1)/2+sqw1)*i14 + // 58*57/2
3288                                      IndEnPassant11B (sqw3, sqb1, sqEnP));
3289                             }
3290                         }
3291                     else
3292                         {
3293                         // Two different white pieces
3294                         if (XX == sqEnP)
3295                             {
3296                             uInd = TEnumerate1<x_piecePawn,true,true>::Index(sqbk,sqb1,sqwk);
3297                             CHECK_INF_SINGLE(uInd);
3298                             return  (uInd*(i59*i47))*((INDEX)i60) +
3299                                     (EXCLUDE4(sqw1,sqwk,sqbk,sqw3,sqb1)*i59*i47 +   // 60
3300                                      EXCLUDE5(sqw2,sqwk,sqbk,sqw1,sqw3,sqb1)*i47 +  // 59
3301                                      EXCLUDE1(sqw3,sqb1)-i8);                       // 47
3302                             }
3303                         else
3304                             {
3305                             // En passant capture
3306                             sqEnP ^= sqMask;
3307                             uInd = rgcSinglePawnPresent[x_piecePawn];
3308                             return  (uInd*(i59*i47))*((INDEX)i60) +
3309                                     (IndHalfKings(sqbk,sqwk)*(i58*i57*i14) +
3310                                      EXCLUDE6(sqw1,sqwk,sqbk,sqw3,sqb1,sqEnP,sqEnP-8)*(i57*i14) +   // 58
3311                                      EXCLUDE7(sqw2,sqwk,sqbk,sqw1,sqw3,sqb1,sqEnP,sqEnP-8)*i14 +        // 57
3312                                      IndEnPassant11B (sqw3, sqb1, sqEnP));
3313                             }
3314                         }
3315                     }
3316                 else
3317                     {
3318                     // Only black pawn
3319                     uInd = TEnumerate1<x_piecePawn,true,true>::Index(sqbk,sqb1,sqwk);
3320                     CHECK_INF_SINGLE(uInd);
3321                     if (piw1 == piw3)
3322                         {
3323                         // 3 identical white pieces
3324                         SORT (sqw1, sqw2);
3325                         SORT (sqw2, sqw3);
3326                         SORT (sqw1, sqw2);
3327                         sqw1 = EXCLUDE3(sqw1,sqwk,sqbk,sqb1);                       // 61
3328                         sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1);                       // 61
3329                         sqw3 = EXCLUDE3(sqw3,sqwk,sqbk,sqb1);                       // 61
3330                         return  uInd*(i61*i60*i59/6) +
3331                                 sqw3*(sqw3-1)*(sqw3-2)/6 + sqw2*(sqw2-1)/2 + sqw1;  // 61*60*59/6
3332                         }
3333                     else if (piw1 == piw2)
3334                         {
3335                         // 2 identical major white pieces
3336                         SORT (sqw1, sqw2);
3337                         sqw3 = EXCLUDE5(sqw3,sqwk,sqbk,sqw1,sqw2,sqb1);
3338                         sqw1 = EXCLUDE3(sqw1,sqwk,sqbk,sqb1);               // 61
3339                         sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1);               // 61
3340                         return  (uInd*(i61*i59))*(INDEX)(i60/2) +
3341                                 ((sqw2*(sqw2-1)/2 + sqw1)*i59 +             // 61*60/2
3342                                  sqw3);                                     // 59
3343                         }
3344                     else if (piw2 == piw3)
3345                         {
3346                         // 2 identical minor white pieces
3347                         SORT (sqw2, sqw3);
3348                         sqw2 = EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1);              // 60
3349                         sqw3 = EXCLUDE4(sqw3,sqwk,sqbk,sqw1,sqb1);              // 60
3350                         return  (uInd*(i61*i59))*(INDEX)(i60/2) +
3351                                 (EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*(i60*i59/2) +    // 61
3352                                  sqw3*(sqw3-1)/2 + sqw2);                       // 60*59/2
3353                         }
3354                     else
3355                         {
3356                         // All 3 white pieces are different
3357                         return  (uInd*(i61*i59))*(INDEX)i60 +
3358                                 (EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*(i60*i59) +  // 61
3359                                  EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1)*i59 +   // 60
3360                                  EXCLUDE5(sqw3,sqwk,sqbk,sqw1,sqw2,sqb1));  // 59
3361                         }
3362                     }
3363                 }
3364             else
3365                 {
3366                 // No black pawn
3367                 uInd = TEnumerate1<pib1,true,true>::Index(sqbk,sqb1,sqwk);
3368                 CHECK_INF_SINGLE(uInd);
3369                 if (x_piecePawn == piw1)
3370                     {
3371                     // Only 3 white pawns
3372                     SORT (sqw1, sqw2);
3373                     SORT (sqw2, sqw3);
3374                     SORT (sqw1, sqw2);
3375                     sqw3 -= i8;
3376                     sqw2 -= i8;
3377                     return  uInd*(i48*47*i46/6) +
3378                             sqw3*(sqw3-1)*(sqw3-2)/6+sqw2*(sqw2-1)/2+sqw1-i8;           // 48*47*46/6
3379                     }
3380                 else if (x_piecePawn == piw2)
3381                     {
3382                     // 2 white pawns, one non-pawn
3383                     SORT (sqw2, sqw3);
3384                     sqTemp = sqw3 - i8;
3385                     return  (uInd*(i59*47))*(INDEX)(i48/2) +
3386                             (EXCLUDE5(sqw1,sqwk,sqbk,sqb1,sqw2,sqw3)*(i48*i47/2) +
3387                              sqTemp*(sqTemp-1)/2+sqw2-i8);          // 48*47/2
3388                     }
3389                 else if (piw1 == piw2)
3390                     {
3391                     // One white pawn, 2 identical white pieces
3392                     SORT (sqw1, sqw2);
3393                     sqw1 = EXCLUDE4(sqw1,sqwk,sqbk,sqb1,sqw3);
3394                     sqw2 = EXCLUDE4(sqw2,sqwk,sqbk,sqb1,sqw3);
3395                     return  (uInd*(i60*i59/2))*(INDEX)i48 +
3396                             ((sqw2*(sqw2-1)/2+sqw1)*i48 +   // 60*59/2
3397                              sqw3-i8);                      // 48
3398                     }
3399                 else
3400                     {
3401                     // One white pawn, 2 different white pieces
3402                     return  (uInd*(i60*i59))*(INDEX)i48 +
3403                             (EXCLUDE4(sqw1,sqwk,sqbk,sqb1,sqw3)*(i59*i48) + // 60
3404                              EXCLUDE5(sqw2,sqwk,sqbk,sqb1,sqw1,sqw3)*i48 +  // 59
3405                              sqw3-i8);                                      // 48
3406                     }
3407                 }
3408             }
3409         else
3410             {
3411             // No pawns
3412             if (!FInTriangle (sqbk, sqwk))
3413                 {
3414                 sqwk = reflect_xy(sqwk);
3415                 sqw1 = reflect_xy(sqw1);
3416                 sqw2 = reflect_xy(sqw2);
3417                 sqw3 = reflect_xy(sqw3);
3418                 sqbk = reflect_xy(sqbk);
3419                 sqb1 = reflect_xy(sqb1);
3420                 };
3421             uInd = TEnumerate1<pib1,false,false>::Index(sqbk,sqb1,sqwk);
3422             CHECK_INF_SINGLE(uInd);
3423             if (piw1 == piw2 && piw2 == piw3)
3424                 {
3425                 // All 3 pieces equal
3426                 SORT (sqw1, sqw2);
3427                 SORT (sqw2, sqw3);
3428                 SORT (sqw1, sqw2);
3429                 sqw3 = EXCLUDE3(sqw3,sqwk,sqbk,sqb1);   // 61
3430                 sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1);
3431                 return  uInd*(i61*i60*i59/6) +
3432                         sqw3*(sqw3-1)*(sqw3-2)/6+
3433                         sqw2*(sqw2-1)/2+
3434                         EXCLUDE3(sqw1,sqwk,sqbk,sqb1);  // 61*60*59/6
3435                 }
3436             else if (piw1 == piw2)
3437                 {
3438                 // 2 major pieces equal
3439                 SORT (sqw1, sqw2);
3440                 sqw2 = EXCLUDE4(sqw2,sqwk,sqbk,sqw3,sqb1);                          // 60
3441                 return uInd*(i60*i59/2*i61) +
3442                         (sqw2*(sqw2-1)/2+EXCLUDE4(sqw1,sqwk,sqbk,sqw3,sqb1))*i61 +  // 60*59/2
3443                         EXCLUDE3(sqw3,sqwk,sqbk,sqb1);                              // 61
3444                 }
3445             else if (piw2 == piw3)
3446                 {
3447                 // 2 minor pieces equal
3448                 SORT (sqw2, sqw3);
3449                 sqw3 = EXCLUDE4(sqw3,sqwk,sqbk,sqw1,sqb1);                  // 60
3450                 return uInd*(i61*i60*i59/2) +
3451                         EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*(i60*i59/2) +         // 62
3452                         sqw3*(sqw3-1)/2+EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1); // 60*59/2
3453                 }
3454             else
3455                 {
3456                 uInd *= i61*i60*i59/2;
3457                 return (INDEX) uInd + 
3458                        (INDEX) (uInd +
3459                                 EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*(i60*i59) +   // 61
3460                                 EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1)*i59 +    // 60
3461                                 EXCLUDE5(sqw3,sqwk,sqbk,sqw1,sqw2,sqb1));   // 59
3462                 }
3463             }
3464         }
3465     };
3466
3467 #endif  // T42
3468
3469 #else   // Old SJE schema ------------------------------------------------------
3470
3471 /* scanning pattern: triangle encoding */
3472
3473 static const INDEX sptriv[] = 
3474     {
3475      0,  1,  2,  3, -1, -1, -1, -1,
3476     -1,  4,  5,  6, -1, -1, -1, -1,
3477     -1, -1,  7,  8, -1, -1, -1, -1,
3478     -1, -1, -1,  9, -1, -1, -1, -1,
3479     -1, -1, -1, -1, -1, -1, -1, -1,
3480     -1, -1, -1, -1, -1, -1, -1, -1,
3481     -1, -1, -1, -1, -1, -1, -1, -1,
3482     -1, -1, -1, -1, -1, -1, -1, -1,
3483     };
3484
3485 /* scanning pattern: queenside flank encoding */
3486
3487 static const INDEX spqsfv[] = 
3488     {
3489      0,  1,  2,  3, -1, -1, -1, -1,
3490      4,  5,  6,  7, -1, -1, -1, -1,
3491      8,  9, 10, 11, -1, -1, -1, -1,
3492     12, 13, 14, 15, -1, -1, -1, -1,
3493     16, 17, 18, 19, -1, -1, -1, -1,
3494     20, 21, 22, 23, -1, -1, -1, -1,
3495     24, 25, 26, 27, -1, -1, -1, -1,
3496     28, 29, 30, 31, -1, -1, -1, -1,
3497     };
3498
3499 /*--> CalcIndex3A: calculate index, mode 3A */
3500 INLINE INDEX CalcIndex3A
3501     (
3502     square sq0,
3503     square sq1,
3504     square sq2
3505     )
3506     {
3507     INDEX index;
3508
3509     if (TbRow(sq2) > x_row_4)
3510         {
3511         sq0 = reflect_x(sq0);
3512         sq1 = reflect_x(sq1);
3513         sq2 = reflect_x(sq2);
3514         };
3515
3516     if (TbColumn(sq2) > x_column_d)
3517         {
3518         sq0 = reflect_y(sq0);
3519         sq1 = reflect_y(sq1);
3520         sq2 = reflect_y(sq2);
3521         };
3522
3523     if (TbRow(sq2) > TbColumn(sq2))
3524         {
3525         sq0 = reflect_xy(sq0);
3526         sq1 = reflect_xy(sq1);
3527         sq2 = reflect_xy(sq2);
3528         };
3529
3530     index =
3531         sq0 +
3532         sq1 * i64 +
3533         sptriv [sq2] * i64 * i64;
3534
3535     return (index);
3536     }
3537
3538 /*--> CalcIndex3B: calculate index, mode 3B */
3539 INLINE INDEX CalcIndex3B
3540     (
3541     square sq0,
3542     square sq1,
3543     square sq2
3544     )
3545     {
3546     INDEX index;
3547
3548     if (TbColumn(sq1) > x_column_d)
3549         {
3550         sq0 = reflect_y(sq0);
3551         sq1 = reflect_y(sq1);
3552         sq2 = reflect_y(sq2);
3553         };
3554
3555     index =
3556         sq0 +
3557         spqsfv [sq1] * i64 +
3558         sq2 * (i64 / 2) * i64;
3559
3560     return (index);
3561     }
3562
3563 /*--> CalcIndex4A: calculate index, mode 4A */
3564 INLINE INDEX CalcIndex4A
3565     (
3566     square sq0,
3567     square sq1,
3568     square sq2,
3569     square sq3
3570     )
3571     {
3572     INDEX index;
3573
3574     if (TbRow(sq3) > x_row_4)
3575         {
3576         sq0 = reflect_x(sq0);
3577         sq1 = reflect_x(sq1);
3578         sq2 = reflect_x(sq2);
3579         sq3 = reflect_x(sq3);
3580         };
3581
3582     if (TbColumn(sq3) > x_column_d)
3583         {
3584         sq0 = reflect_y(sq0);
3585         sq1 = reflect_y(sq1);
3586         sq2 = reflect_y(sq2);
3587         sq3 = reflect_y(sq3);
3588         };
3589
3590     if (TbRow(sq3) > TbColumn(sq3))
3591         {
3592         sq0 = reflect_xy(sq0);
3593         sq1 = reflect_xy(sq1);
3594         sq2 = reflect_xy(sq2);
3595         sq3 = reflect_xy(sq3);
3596         };
3597
3598     index =
3599         sq0 +
3600         sq1 * i64 +
3601         sq2 * i64 * i64 +
3602         sptriv [sq3] * i64 * i64 * i64;
3603
3604     return (index);
3605     }
3606
3607 /*--> CalcIndex4B: calculate index, mode 4B */
3608 INLINE INDEX CalcIndex4B
3609     (
3610     square sq0,
3611     square sq1,
3612     square sq2,
3613     square sq3
3614     )
3615     {
3616     INDEX index;
3617
3618     if (TbColumn(sq3) > x_column_d)
3619         {
3620         sq0 = reflect_y(sq0);
3621         sq1 = reflect_y(sq1);
3622         sq2 = reflect_y(sq2);
3623         sq3 = reflect_y(sq3);
3624         };
3625
3626     index =
3627         sq0 +
3628         sq1 * i64 +
3629         sq2 * i64 * i64 +
3630         spqsfv [sq3] * i64 * i64 * i64;
3631
3632     return (index);
3633     }
3634
3635 /*--> CalcIndex4C: calculate index, mode 4C */
3636 INLINE INDEX CalcIndex4C
3637     (
3638     square sq0,
3639     square sq1,
3640     square sq2,
3641     square sq3
3642     )
3643     {
3644     INDEX index;
3645
3646     if (TbColumn(sq2) > x_column_d)
3647         {
3648         sq0 = reflect_y(sq0);
3649         sq1 = reflect_y(sq1);
3650         sq2 = reflect_y(sq2);
3651         sq3 = reflect_y(sq3);
3652         };
3653
3654     index =
3655         sq0 +
3656         sq1 * i64 +
3657         spqsfv [sq2] * i64 * i64 +
3658         sq3 * (i64 / 2) * i64 * i64;
3659
3660     return (index);
3661     }
3662
3663 /*--> CalcIndex5A: calculate index, mode 5A */
3664 INLINE INDEX CalcIndex5A
3665     (
3666     square sq0,
3667     square sq1,
3668     square sq2,
3669     square sq3,
3670     square sq4
3671     )
3672     {
3673     INDEX index;
3674
3675     if (TbRow(sq4) > x_row_4)
3676         {
3677         sq0 = reflect_x(sq0);
3678         sq1 = reflect_x(sq1);
3679         sq2 = reflect_x(sq2);
3680         sq3 = reflect_x(sq3);
3681         sq4 = reflect_x(sq4);
3682         };
3683
3684     if (TbColumn(sq4) > x_column_d)
3685         {
3686         sq0 = reflect_y(sq0);
3687         sq1 = reflect_y(sq1);
3688         sq2 = reflect_y(sq2);
3689         sq3 = reflect_y(sq3);
3690         sq4 = reflect_y(sq4);
3691         };
3692
3693     if (TbRow(sq4) > TbColumn(sq4))
3694         {
3695         sq0 = reflect_xy(sq0);
3696         sq1 = reflect_xy(sq1);
3697         sq2 = reflect_xy(sq2);
3698         sq3 = reflect_xy(sq3);
3699         sq4 = reflect_xy(sq4);
3700         };
3701
3702     index =
3703         sq0 +
3704         sq1 * i64 +
3705         sq2 * i64 * i64 +
3706         sq3 * i64 * i64 * i64 +
3707         sptriv [sq4] * i64 * i64 * i64 * i64;
3708
3709     return (index);
3710     }
3711
3712 /*--> CalcIndex5B: calculate index, mode 5B */
3713 INLINE INDEX CalcIndex5B
3714     (
3715     square sq0,
3716     square sq1,
3717     square sq2,
3718     square sq3,
3719     square sq4
3720     )
3721     {
3722     INDEX index;
3723
3724     if (TbColumn(sq4) > x_column_d)
3725         {
3726         sq0 = reflect_y(sq0);
3727         sq1 = reflect_y(sq1);
3728         sq2 = reflect_y(sq2);
3729         sq3 = reflect_y(sq3);
3730         sq4 = reflect_y(sq4);
3731         };
3732
3733     index =
3734         sq0 +
3735         sq1 * i64 +
3736         sq2 * i64 * i64 +
3737         sq3 * i64 * i64 * i64 +
3738         spqsfv [sq4] * i64 * i64 * i64 * i64;
3739
3740     return (index);
3741     }
3742
3743 /*--> CalcIndex5C: calculate index, mode 5C */
3744 INLINE INDEX CalcIndex5C
3745     (
3746     square sq0,
3747     square sq1,
3748     square sq2,
3749     square sq3,
3750     square sq4
3751     )
3752     {
3753     INDEX index;
3754
3755     if (TbColumn(sq3) > x_column_d)
3756         {
3757         sq0 = reflect_y(sq0);
3758         sq1 = reflect_y(sq1);
3759         sq2 = reflect_y(sq2);
3760         sq3 = reflect_y(sq3);
3761         sq4 = reflect_y(sq4);
3762         };
3763
3764     index =
3765         sq0 +
3766         sq1 * i64 +
3767         sq2 * i64 * i64 +
3768         spqsfv [sq3] * i64 * i64 * i64 +
3769         sq4 * (i64 / 2) * i64 * i64 * i64;
3770
3771     return (index);
3772     }
3773
3774 /*--> CalcIndex5D: calculate index, mode 5D */
3775 INLINE INDEX CalcIndex5D
3776     (
3777     square sq0,
3778     square sq1,
3779     square sq2,
3780     square sq3,
3781     square sq4
3782     )
3783     {
3784     INDEX index;
3785
3786     if (TbColumn(sq2) > x_column_d)
3787         {
3788         sq0 = reflect_y(sq0);
3789         sq1 = reflect_y(sq1);
3790         sq2 = reflect_y(sq2);
3791         sq3 = reflect_y(sq3);
3792         sq4 = reflect_y(sq4);
3793         };
3794
3795     index =
3796         sq0 +
3797         sq1 * i64 +
3798         spqsfv [sq2] * i64 * i64 +
3799         sq3 * (i64 / 2) * i64 * i64 +
3800         sq4 * (i64 / 2) * i64 * i64 * i64;
3801
3802     return (index);
3803     }
3804
3805 // Calculate index - a lot of functions...
3806
3807 #define IndCalcW    IndCalc
3808 #define IndCalcB    IndCalc
3809
3810 template <int pi> class T21
3811     {
3812 public:
3813     static INDEX TB_FASTCALL IndCalc
3814         (
3815         square  *psqW,
3816         square  *psqB,
3817         square  sqEnP,
3818         int     fInvert
3819         )
3820         {
3821         square sq0, sq1, sq2;
3822
3823         sq0 = SqFindKing (psqW);
3824         sq1 = SqFindOne  (psqW, pi);
3825         sq2 = SqFindKing (psqB);
3826
3827         if (x_piecePawn == pi)
3828             {
3829             if (fInvert)
3830                 {
3831                 sq0 = reflect_x (sq0);
3832                 sq1 = reflect_x (sq1);
3833                 sq2 = reflect_x (sq2);
3834                 }
3835             return CalcIndex3B (sq0, sq1, sq2);
3836             }
3837         else
3838             return CalcIndex3A (sq0, sq1, sq2);
3839         }
3840     };
3841
3842 template <int pi1, int pi2> class T22
3843     {
3844 public:
3845     static INDEX TB_FASTCALL IndCalc
3846         (
3847         square  *psqW,
3848         square  *psqB,
3849         square  sqEnP,
3850         int     fInvert
3851         )
3852         {
3853         square sq0, sq1, sq2, sq3;
3854
3855         sq0 = SqFindKing (psqW);
3856         sq1 = SqFindOne  (psqW, pi1);
3857         sq2 = SqFindKing (psqB);
3858         sq3 = SqFindOne  (psqB, pi2);
3859
3860         if (x_piecePawn == pi1 || x_piecePawn == pi2)
3861             {
3862             if (fInvert)
3863                 {
3864                 sq0 = reflect_x (sq0);
3865                 sq1 = reflect_x (sq1);
3866                 sq2 = reflect_x (sq2);
3867                 sq3 = reflect_x (sq3);
3868                 }
3869             return CalcIndex4B (sq0, sq1, sq2, sq3);
3870             }
3871         else
3872             return CalcIndex4A (sq0, sq1, sq2, sq3);
3873         }
3874     };
3875
3876 template <int pi1, int pi2> class T31
3877     {
3878 public:
3879     static INDEX TB_FASTCALL IndCalc
3880         (
3881         square  *psqW,
3882         square  *psqB,
3883         square  sqEnP,
3884         int     fInvert
3885         )
3886         {
3887         square sq0, sq1, sq2, sq3;
3888
3889         sq0 = SqFindKing (psqW);
3890         sq1 = SqFindFirst (psqW, pi1);
3891         if (pi1 == pi2)
3892             sq2 = SqFindSecond (psqW, pi2);
3893         else
3894             sq2 = SqFindFirst (psqW, pi2);
3895         sq3 = SqFindKing (psqB);
3896
3897         if (x_piecePawn == pi1 || x_piecePawn == pi2)
3898             {
3899             if (fInvert)
3900                 {
3901                 sq0 = reflect_x (sq0);
3902                 sq1 = reflect_x (sq1);
3903                 sq2 = reflect_x (sq2);
3904                 sq3 = reflect_x (sq3);
3905                 }
3906             return CalcIndex4C (sq0, sq1, sq2, sq3);
3907             }
3908         else
3909             return CalcIndex4A (sq0, sq1, sq2, sq3);
3910         }
3911     };
3912
3913 template <int pi1, int pi2, int pi3> class T32
3914     {
3915 public:
3916     static INDEX TB_FASTCALL IndCalc
3917         (
3918         square  *psqW,
3919         square  *psqB,
3920         square  sqEnP,
3921         int     fInvert
3922         )
3923         {
3924         square sq0, sq1, sq2, sq3, sq4;
3925
3926         sq0 = SqFindKing (psqW);
3927         sq1 = SqFindFirst (psqW, pi1);
3928         if (pi1 == pi2)
3929             sq2 = SqFindSecond (psqW, pi2);
3930         else
3931             sq2 = SqFindFirst (psqW, pi2);
3932         sq3 = SqFindKing (psqB);
3933         sq4 = SqFindOne  (psqB, pi3);
3934
3935         if (x_piecePawn == pi1 || x_piecePawn == pi2 || x_piecePawn == pi3)
3936             {
3937             if (fInvert)
3938                 {
3939                 sq0 = reflect_x (sq0);
3940                 sq1 = reflect_x (sq1);
3941                 sq2 = reflect_x (sq2);
3942                 sq3 = reflect_x (sq3);
3943                 sq4 = reflect_x (sq4);
3944                 }
3945             if (x_piecePawn == pi3)
3946                 return CalcIndex5B (sq0, sq1, sq2, sq3, sq4);
3947             else
3948                 return CalcIndex5D (sq0, sq1, sq2, sq3, sq4);
3949             }
3950         else
3951             return CalcIndex5A (sq0, sq1, sq2, sq3, sq4);
3952         }
3953     };
3954
3955 #if defined (T41_INCLUDE)
3956
3957 template <int pi1, int pi2, int pi3> class T41
3958     {
3959 public:
3960     static INDEX TB_FASTCALL IndCalc
3961         (
3962         square  *psqW,
3963         square  *psqB,
3964         square  sqEnP,
3965         int     fInvert
3966         )
3967         {
3968         square sq0, sq1, sq2, sq3, sq4;
3969
3970         sq0 = SqFindKing (psqW);
3971         sq1 = SqFindFirst (psqW, pi1);
3972         sq2 = SqFindFirst (psqW, pi2);
3973         sq3 = SqFindFirst (psqW, pi3);
3974         sq4 = SqFindKing (psqB);
3975
3976         if (x_piecePawn == pi1 || x_piecePawn == pi2 || x_piecePawn == pi3)
3977             {
3978             // There are pawns on the board
3979             if (fInvert)
3980                 {
3981                 sq0 = reflect_x (sq0);
3982                 sq1 = reflect_x (sq1);
3983                 sq2 = reflect_x (sq2);
3984                 sq3 = reflect_x (sq3);
3985                 sq4 = reflect_x (sq4);
3986                 }
3987             return CalcIndex5C (sq0, sq1, sq2, sq3, sq4);
3988             }
3989         else    // No pawns
3990             return CalcIndex5A (sq0, sq1, sq2, sq3, sq4);
3991         }
3992     };
3993
3994 #endif
3995
3996 #endif  //----------------------------------------------------------------------
3997
3998 // All tablebases enumerated
3999
4000 #define tbid_kk      0
4001 #define tbid_kpk     1
4002 #define tbid_knk     2
4003 #define tbid_kbk     3
4004 #define tbid_krk     4
4005 #define tbid_kqk     5
4006 #define tbid_kpkp    6
4007 #define tbid_knkp    7
4008 #define tbid_knkn    8
4009 #define tbid_kbkp    9
4010 #define tbid_kbkn   10
4011 #define tbid_kbkb   11
4012 #define tbid_krkp   12
4013 #define tbid_krkn   13
4014 #define tbid_krkb   14
4015 #define tbid_krkr   15
4016 #define tbid_kqkp   16
4017 #define tbid_kqkn   17
4018 #define tbid_kqkb   18
4019 #define tbid_kqkr   19
4020 #define tbid_kqkq   20
4021 #define tbid_kppk   21
4022 #define tbid_knpk   22
4023 #define tbid_knnk   23
4024 #define tbid_kbpk   24
4025 #define tbid_kbnk   25
4026 #define tbid_kbbk   26
4027 #define tbid_krpk   27
4028 #define tbid_krnk   28
4029 #define tbid_krbk   29
4030 #define tbid_krrk   30
4031 #define tbid_kqpk   31
4032 #define tbid_kqnk   32
4033 #define tbid_kqbk   33
4034 #define tbid_kqrk   34
4035 #define tbid_kqqk   35
4036 #define tbid_kppkp  36
4037 #define tbid_kppkn  37
4038 #define tbid_kppkb  38
4039 #define tbid_kppkr  39
4040 #define tbid_kppkq  40
4041 #define tbid_knpkp  41
4042 #define tbid_knpkn  42
4043 #define tbid_knpkb  43
4044 #define tbid_knpkr  44
4045 #define tbid_knpkq  45
4046 #define tbid_knnkp  46
4047 #define tbid_knnkn  47
4048 #define tbid_knnkb  48
4049 #define tbid_knnkr  49
4050 #define tbid_knnkq  50
4051 #define tbid_kbpkp  51
4052 #define tbid_kbpkn  52
4053 #define tbid_kbpkb  53
4054 #define tbid_kbpkr  54
4055 #define tbid_kbpkq  55
4056 #define tbid_kbnkp  56
4057 #define tbid_kbnkn  57
4058 #define tbid_kbnkb  58
4059 #define tbid_kbnkr  59
4060 #define tbid_kbnkq  60
4061 #define tbid_kbbkp  61
4062 #define tbid_kbbkn  62
4063 #define tbid_kbbkb  63
4064 #define tbid_kbbkr  64
4065 #define tbid_kbbkq  65
4066 #define tbid_krpkp  66
4067 #define tbid_krpkn  67
4068 #define tbid_krpkb  68
4069 #define tbid_krpkr  69
4070 #define tbid_krpkq  70
4071 #define tbid_krnkp  71
4072 #define tbid_krnkn  72
4073 #define tbid_krnkb  73
4074 #define tbid_krnkr  74
4075 #define tbid_krnkq  75
4076 #define tbid_krbkp  76
4077 #define tbid_krbkn  77
4078 #define tbid_krbkb  78
4079 #define tbid_krbkr  79
4080 #define tbid_krbkq  80
4081 #define tbid_krrkp  81
4082 #define tbid_krrkn  82
4083 #define tbid_krrkb  83
4084 #define tbid_krrkr  84
4085 #define tbid_krrkq  85
4086 #define tbid_kqpkp  86
4087 #define tbid_kqpkn  87
4088 #define tbid_kqpkb  88
4089 #define tbid_kqpkr  89
4090 #define tbid_kqpkq  90
4091 #define tbid_kqnkp  91
4092 #define tbid_kqnkn  92
4093 #define tbid_kqnkb  93
4094 #define tbid_kqnkr  94
4095 #define tbid_kqnkq  95
4096 #define tbid_kqbkp  96
4097 #define tbid_kqbkn  97
4098 #define tbid_kqbkb  98
4099 #define tbid_kqbkr  99
4100 #define tbid_kqbkq 100
4101 #define tbid_kqrkp 101
4102 #define tbid_kqrkn 102
4103 #define tbid_kqrkb 103
4104 #define tbid_kqrkr 104
4105 #define tbid_kqrkq 105
4106 #define tbid_kqqkp 106
4107 #define tbid_kqqkn 107
4108 #define tbid_kqqkb 108
4109 #define tbid_kqqkr 109
4110 #define tbid_kqqkq 110
4111
4112 #if defined (T41_INCLUDE)
4113 #  define tbid_kpppk    111
4114 #  define tbid_knppk    112
4115 #  define tbid_knnpk    113
4116 #  define tbid_knnnk    114
4117 #  define tbid_kbppk    115
4118 #  define tbid_kbnpk    116
4119 #  define tbid_kbnnk    117
4120 #  define tbid_kbbpk    118
4121 #  define tbid_kbbnk    119
4122 #  define tbid_kbbbk    120
4123 #  define tbid_krppk    121
4124 #  define tbid_krnpk    122
4125 #  define tbid_krnnk    123
4126 #  define tbid_krbpk    124
4127 #  define tbid_krbnk    125
4128 #  define tbid_krbbk    126
4129 #  define tbid_krrpk    127
4130 #  define tbid_krrnk    128
4131 #  define tbid_krrbk    129
4132 #  define tbid_krrrk    130
4133 #  define tbid_kqppk    131
4134 #  define tbid_kqnpk    132
4135 #  define tbid_kqnnk    133
4136 #  define tbid_kqbpk    134
4137 #  define tbid_kqbnk    135
4138 #  define tbid_kqbbk    136
4139 #  define tbid_kqrpk    137
4140 #  define tbid_kqrnk    138
4141 #  define tbid_kqrbk    139
4142 #  define tbid_kqrrk    140
4143 #  define tbid_kqqpk    141
4144 #  define tbid_kqqnk    142
4145 #  define tbid_kqqbk    143
4146 #  define tbid_kqqrk    144
4147 #  define tbid_kqqqk    145
4148 #endif
4149
4150 #if defined (T33_INCLUDE)
4151 #  if defined (T41_INCLUDE)
4152 #    define BASE_33 145
4153 #  else
4154 #    define BASE_33 110
4155 #  endif
4156 #  define tbid_knnknn   (BASE_33 + 1)
4157 #  define tbid_kbnknn   (BASE_33 + 2)
4158 #  define tbid_kbbknn   (BASE_33 + 3)
4159 #  define tbid_kbbkbn   (BASE_33 + 4)
4160 #  define tbid_kbbkbb   (BASE_33 + 5)
4161 #  define tbid_krnknn   (BASE_33 + 6)
4162 #  define tbid_krnkbb   (BASE_33 + 7)
4163 #  define tbid_krbknn   (BASE_33 + 8)
4164 #  define tbid_krbkbb   (BASE_33 + 9)
4165 #  define tbid_krrknn   (BASE_33 + 10)
4166 #  define tbid_krrkbn   (BASE_33 + 11)
4167 #  define tbid_krrkbb   (BASE_33 + 12)
4168 #  define tbid_krrkrn   (BASE_33 + 13)
4169 #  define tbid_krrkrb   (BASE_33 + 14)
4170 #  define tbid_krrkrr   (BASE_33 + 15)
4171 #  define tbid_kqnknn   (BASE_33 + 16)
4172 #  define tbid_kqnkbb   (BASE_33 + 17)
4173 #  define tbid_kqnkrr   (BASE_33 + 18)
4174 #  define tbid_kqbknn   (BASE_33 + 19)
4175 #  define tbid_kqbkbb   (BASE_33 + 20)
4176 #  define tbid_kqbkrr   (BASE_33 + 21)
4177 #  define tbid_kqrknn   (BASE_33 + 22)
4178 #  define tbid_kqrkbb   (BASE_33 + 23)
4179 #  define tbid_kqrkrr   (BASE_33 + 24)
4180 #  define tbid_kqqknn   (BASE_33 + 25)
4181 #  define tbid_kqqkbn   (BASE_33 + 26)
4182 #  define tbid_kqqkbb   (BASE_33 + 27)
4183 #  define tbid_kqqkrn   (BASE_33 + 28)
4184 #  define tbid_kqqkrb   (BASE_33 + 29)
4185 #  define tbid_kqqkrr   (BASE_33 + 30)
4186 #  define tbid_kqqkqn   (BASE_33 + 31)
4187 #  define tbid_kqqkqb   (BASE_33 + 32)
4188 #  define tbid_kqqkqr   (BASE_33 + 33)
4189 #  define tbid_kqqkqq   (BASE_33 + 34)
4190 #  if defined (T_INDEX64)
4191 #    define tbid_kbnkbn (BASE_33 + 35)
4192 #    define tbid_krnkrn (BASE_33 + 36)
4193 #    define tbid_krbkrb (BASE_33 + 37)
4194 #    define tbid_kqnkqn (BASE_33 + 38)
4195 #    define tbid_kqbkqb (BASE_33 + 39)
4196 #    define tbid_kqrkqr (BASE_33 + 40)
4197 #    define tbid_krnkbn (BASE_33 + 41)
4198 #    define tbid_krbkbn (BASE_33 + 42)
4199 #    define tbid_krbkrn (BASE_33 + 43)
4200 #    define tbid_kqnkbn (BASE_33 + 44)
4201 #    define tbid_kqnkrn (BASE_33 + 45)
4202 #    define tbid_kqnkrb (BASE_33 + 46)
4203 #    define tbid_kqbkbn (BASE_33 + 47)
4204 #    define tbid_kqbkrn (BASE_33 + 48)
4205 #    define tbid_kqbkrb (BASE_33 + 49)
4206 #    define tbid_kqbkqn (BASE_33 + 50)
4207 #    define tbid_kqrkbn (BASE_33 + 51)
4208 #    define tbid_kqrkrn (BASE_33 + 52)
4209 #    define tbid_kqrkrb (BASE_33 + 53)
4210 #    define tbid_kqrkqn (BASE_33 + 54)
4211 #    define tbid_kqrkqb (BASE_33 + 55)
4212 #    define tbid_kppkpp (BASE_33 + 56)
4213 #    define tbid_knpkpp (BASE_33 + 57)
4214 #    define tbid_knpknp (BASE_33 + 58)
4215 #    define tbid_knnkpp (BASE_33 + 59)
4216 #    define tbid_knnknp (BASE_33 + 60)
4217 #    define tbid_kbpkpp (BASE_33 + 61)
4218 #    define tbid_kbpknp (BASE_33 + 62)
4219 #    define tbid_kbpknn (BASE_33 + 63)
4220 #    define tbid_kbpkbp (BASE_33 + 64)
4221 #    define tbid_kbnkpp (BASE_33 + 65)
4222 #    define tbid_kbnknp (BASE_33 + 66)
4223 #    define tbid_kbnkbp (BASE_33 + 67)
4224 #    define tbid_kbbkpp (BASE_33 + 68)
4225 #    define tbid_kbbknp (BASE_33 + 69)
4226 #    define tbid_kbbkbp (BASE_33 + 70)
4227 #    define tbid_krpkpp (BASE_33 + 71)
4228 #    define tbid_krpknp (BASE_33 + 72)
4229 #    define tbid_krpknn (BASE_33 + 73)
4230 #    define tbid_krpkbp (BASE_33 + 74)
4231 #    define tbid_krpkbn (BASE_33 + 75)
4232 #    define tbid_krpkbb (BASE_33 + 76)
4233 #    define tbid_krpkrp (BASE_33 + 77)
4234 #    define tbid_krnkpp (BASE_33 + 78)
4235 #    define tbid_krnknp (BASE_33 + 79)
4236 #    define tbid_krnkbp (BASE_33 + 80)
4237 #    define tbid_krnkrp (BASE_33 + 81)
4238 #    define tbid_krbkpp (BASE_33 + 82)
4239 #    define tbid_krbknp (BASE_33 + 83)
4240 #    define tbid_krbkbp (BASE_33 + 84)
4241 #    define tbid_krbkrp (BASE_33 + 85)
4242 #    define tbid_krrkpp (BASE_33 + 86)
4243 #    define tbid_krrknp (BASE_33 + 87)
4244 #    define tbid_krrkbp (BASE_33 + 88)
4245 #    define tbid_krrkrp (BASE_33 + 89)
4246 #    define tbid_kqpkpp (BASE_33 + 90)
4247 #    define tbid_kqpknp (BASE_33 + 91)
4248 #    define tbid_kqpknn (BASE_33 + 92)
4249 #    define tbid_kqpkbp (BASE_33 + 93)
4250 #    define tbid_kqpkbn (BASE_33 + 94)
4251 #    define tbid_kqpkbb (BASE_33 + 95)
4252 #    define tbid_kqpkrp (BASE_33 + 96)
4253 #    define tbid_kqpkrn (BASE_33 + 97)
4254 #    define tbid_kqpkrb (BASE_33 + 98)
4255 #    define tbid_kqpkrr (BASE_33 + 99)
4256 #    define tbid_kqpkqp (BASE_33 + 100)
4257 #    define tbid_kqnkpp (BASE_33 + 101)
4258 #    define tbid_kqnknp (BASE_33 + 102)
4259 #    define tbid_kqnkbp (BASE_33 + 103)
4260 #    define tbid_kqnkrp (BASE_33 + 104)
4261 #    define tbid_kqnkqp (BASE_33 + 105)
4262 #    define tbid_kqbkpp (BASE_33 + 106)
4263 #    define tbid_kqbknp (BASE_33 + 107)
4264 #    define tbid_kqbkbp (BASE_33 + 108)
4265 #    define tbid_kqbkrp (BASE_33 + 109)
4266 #    define tbid_kqbkqp (BASE_33 + 110)
4267 #    define tbid_kqrkpp (BASE_33 + 111)
4268 #    define tbid_kqrknp (BASE_33 + 112)
4269 #    define tbid_kqrkbp (BASE_33 + 113)
4270 #    define tbid_kqrkrp (BASE_33 + 114)
4271 #    define tbid_kqrkqp (BASE_33 + 115)
4272 #    define tbid_kqqkpp (BASE_33 + 116)
4273 #    define tbid_kqqknp (BASE_33 + 117)
4274 #    define tbid_kqqkbp (BASE_33 + 118)
4275 #    define tbid_kqqkrp (BASE_33 + 119)
4276 #    define tbid_kqqkqp (BASE_33 + 120)
4277 #    define C33 (tbid_kqqkqp - BASE_33)
4278 #  else
4279 #    define C33 (tbid_kqqkqq - BASE_33)
4280 #  endif
4281 #else
4282 #  define C33   0
4283 #endif
4284
4285 #if defined (T41_INCLUDE)
4286 #  define BASE_42   (145 + C33)
4287 #else
4288 #  define BASE_42   (110 + C33)
4289 #endif
4290
4291 #if defined (T42_INCLUDE)
4292 #  define tbid_knnnkn   (BASE_42 + 1)
4293 #  define tbid_kbnnkn   (BASE_42 + 2)
4294 #  define tbid_kbbnkn   (BASE_42 + 3)
4295 #  define tbid_kbbbkn   (BASE_42 + 4)
4296 #  define tbid_krnnkn   (BASE_42 + 5)
4297 #  define tbid_krbbkn   (BASE_42 + 6)
4298 #  define tbid_krrnkn   (BASE_42 + 7)
4299 #  define tbid_krrbkn   (BASE_42 + 8)
4300 #  define tbid_krrrkn   (BASE_42 + 9)
4301 #  define tbid_kqnnkn   (BASE_42 + 10)
4302 #  define tbid_kqbbkn   (BASE_42 + 11)
4303 #  define tbid_kqrrkn   (BASE_42 + 12)
4304 #  define tbid_kqqnkn   (BASE_42 + 13)
4305 #  define tbid_kqqbkn   (BASE_42 + 14)
4306 #  define tbid_kqqrkn   (BASE_42 + 15)
4307 #  define tbid_kqqqkn   (BASE_42 + 16)
4308 #  define tbid_knnnkb   (BASE_42 + 17)
4309 #  define tbid_kbnnkb   (BASE_42 + 18)
4310 #  define tbid_kbbnkb   (BASE_42 + 19)
4311 #  define tbid_kbbbkb   (BASE_42 + 20)
4312 #  define tbid_krnnkb   (BASE_42 + 21)
4313 #  define tbid_krbbkb   (BASE_42 + 22)
4314 #  define tbid_krrnkb   (BASE_42 + 23)
4315 #  define tbid_krrbkb   (BASE_42 + 24)
4316 #  define tbid_krrrkb   (BASE_42 + 25)
4317 #  define tbid_kqnnkb   (BASE_42 + 26)
4318 #  define tbid_kqbbkb   (BASE_42 + 27)
4319 #  define tbid_kqrrkb   (BASE_42 + 28)
4320 #  define tbid_kqqnkb   (BASE_42 + 29)
4321 #  define tbid_kqqbkb   (BASE_42 + 30)
4322 #  define tbid_kqqrkb   (BASE_42 + 31)
4323 #  define tbid_kqqqkb   (BASE_42 + 32)
4324 #  define tbid_knnnkr   (BASE_42 + 33)
4325 #  define tbid_kbnnkr   (BASE_42 + 34)
4326 #  define tbid_kbbnkr   (BASE_42 + 35)
4327 #  define tbid_kbbbkr   (BASE_42 + 36)
4328 #  define tbid_krnnkr   (BASE_42 + 37)
4329 #  define tbid_krbbkr   (BASE_42 + 38)
4330 #  define tbid_krrnkr   (BASE_42 + 39)
4331 #  define tbid_krrbkr   (BASE_42 + 40)
4332 #  define tbid_krrrkr   (BASE_42 + 41)
4333 #  define tbid_kqnnkr   (BASE_42 + 42)
4334 #  define tbid_kqbbkr   (BASE_42 + 43)
4335 #  define tbid_kqrrkr   (BASE_42 + 44)
4336 #  define tbid_kqqnkr   (BASE_42 + 45)
4337 #  define tbid_kqqbkr   (BASE_42 + 46)
4338 #  define tbid_kqqrkr   (BASE_42 + 47)
4339 #  define tbid_kqqqkr   (BASE_42 + 48)
4340 #  define tbid_knnnkq   (BASE_42 + 49)
4341 #  define tbid_kbnnkq   (BASE_42 + 50)
4342 #  define tbid_kbbnkq   (BASE_42 + 51)
4343 #  define tbid_kbbbkq   (BASE_42 + 52)
4344 #  define tbid_krnnkq   (BASE_42 + 53)
4345 #  define tbid_krbbkq   (BASE_42 + 54)
4346 #  define tbid_krrnkq   (BASE_42 + 55)
4347 #  define tbid_krrbkq   (BASE_42 + 56)
4348 #  define tbid_krrrkq   (BASE_42 + 57)
4349 #  define tbid_kqnnkq   (BASE_42 + 58)
4350 #  define tbid_kqbbkq   (BASE_42 + 59)
4351 #  define tbid_kqrrkq   (BASE_42 + 60)
4352 #  define tbid_kqqnkq   (BASE_42 + 61)
4353 #  define tbid_kqqbkq   (BASE_42 + 62)
4354 #  define tbid_kqqrkq   (BASE_42 + 63)
4355 #  define tbid_kqqqkq   (BASE_42 + 64)
4356 #  if defined (T_INDEX64)
4357 #    define tbid_krbnkn (BASE_42 + 65)
4358 #    define tbid_kqbnkn (BASE_42 + 66)
4359 #    define tbid_kqrnkn (BASE_42 + 67)
4360 #    define tbid_kqrbkn (BASE_42 + 68)
4361 #    define tbid_krbnkb (BASE_42 + 69)
4362 #    define tbid_kqbnkb (BASE_42 + 70)
4363 #    define tbid_kqrnkb (BASE_42 + 71)
4364 #    define tbid_kqrbkb (BASE_42 + 72)
4365 #    define tbid_krbnkr (BASE_42 + 73)
4366 #    define tbid_kqbnkr (BASE_42 + 74)
4367 #    define tbid_kqrnkr (BASE_42 + 75)
4368 #    define tbid_kqrbkr (BASE_42 + 76)
4369 #    define tbid_krbnkq (BASE_42 + 77)
4370 #    define tbid_kqbnkq (BASE_42 + 78)
4371 #    define tbid_kqrnkq (BASE_42 + 79)
4372 #    define tbid_kqrbkq (BASE_42 + 80)
4373
4374 #    define tbid_kpppkp (BASE_42 + 81)
4375 #    define tbid_knppkp (BASE_42 + 82)
4376 #    define tbid_knnpkp (BASE_42 + 83)
4377 #    define tbid_knnnkp (BASE_42 + 84)
4378 #    define tbid_kbppkp (BASE_42 + 85)
4379 #    define tbid_kbnpkp (BASE_42 + 86)
4380 #    define tbid_kbnnkp (BASE_42 + 87)
4381 #    define tbid_kbbpkp (BASE_42 + 88)
4382 #    define tbid_kbbnkp (BASE_42 + 89)
4383 #    define tbid_kbbbkp (BASE_42 + 90)
4384 #    define tbid_krppkp (BASE_42 + 91)
4385 #    define tbid_krnpkp (BASE_42 + 92)
4386 #    define tbid_krnnkp (BASE_42 + 93)
4387 #    define tbid_krbpkp (BASE_42 + 94)
4388 #    define tbid_krbnkp (BASE_42 + 95)
4389 #    define tbid_krbbkp (BASE_42 + 96)
4390 #    define tbid_krrpkp (BASE_42 + 97)
4391 #    define tbid_krrnkp (BASE_42 + 98)
4392 #    define tbid_krrbkp (BASE_42 + 99)
4393 #    define tbid_krrrkp (BASE_42 + 100)
4394 #    define tbid_kqppkp (BASE_42 + 101)
4395 #    define tbid_kqnpkp (BASE_42 + 102)
4396 #    define tbid_kqnnkp (BASE_42 + 103)
4397 #    define tbid_kqbpkp (BASE_42 + 104)
4398 #    define tbid_kqbnkp (BASE_42 + 105)
4399 #    define tbid_kqbbkp (BASE_42 + 106)
4400 #    define tbid_kqrpkp (BASE_42 + 107)
4401 #    define tbid_kqrnkp (BASE_42 + 108)
4402 #    define tbid_kqrbkp (BASE_42 + 109)
4403 #    define tbid_kqrrkp (BASE_42 + 110)
4404 #    define tbid_kqqpkp (BASE_42 + 111)
4405 #    define tbid_kqqnkp (BASE_42 + 112)
4406 #    define tbid_kqqbkp (BASE_42 + 113)
4407 #    define tbid_kqqrkp (BASE_42 + 114)
4408 #    define tbid_kqqqkp (BASE_42 + 115)
4409 #    define tbid_kpppkn (BASE_42 + 116)
4410 #    define tbid_knppkn (BASE_42 + 117)
4411 #    define tbid_knnpkn (BASE_42 + 118)
4412 #    define tbid_kbppkn (BASE_42 + 119)
4413 #    define tbid_kbnpkn (BASE_42 + 120)
4414 #    define tbid_kbbpkn (BASE_42 + 121)
4415 #    define tbid_krppkn (BASE_42 + 122)
4416 #    define tbid_krnpkn (BASE_42 + 123)
4417 #    define tbid_krbpkn (BASE_42 + 124)
4418 #    define tbid_krrpkn (BASE_42 + 125)
4419 #    define tbid_kqppkn (BASE_42 + 126)
4420 #    define tbid_kqnpkn (BASE_42 + 127)
4421 #    define tbid_kqbpkn (BASE_42 + 128)
4422 #    define tbid_kqrpkn (BASE_42 + 129)
4423 #    define tbid_kqqpkn (BASE_42 + 130)
4424 #    define tbid_kpppkb (BASE_42 + 131)
4425 #    define tbid_knppkb (BASE_42 + 132)
4426 #    define tbid_knnpkb (BASE_42 + 133)
4427 #    define tbid_kbppkb (BASE_42 + 134)
4428 #    define tbid_kbnpkb (BASE_42 + 135)
4429 #    define tbid_kbbpkb (BASE_42 + 136)
4430 #    define tbid_krppkb (BASE_42 + 137)
4431 #    define tbid_krnpkb (BASE_42 + 138)
4432 #    define tbid_krbpkb (BASE_42 + 139)
4433 #    define tbid_krrpkb (BASE_42 + 140)
4434 #    define tbid_kqppkb (BASE_42 + 141)
4435 #    define tbid_kqnpkb (BASE_42 + 142)
4436 #    define tbid_kqbpkb (BASE_42 + 143)
4437 #    define tbid_kqrpkb (BASE_42 + 144)
4438 #    define tbid_kqqpkb (BASE_42 + 145)
4439 #    define tbid_kpppkr (BASE_42 + 146)
4440 #    define tbid_knppkr (BASE_42 + 147)
4441 #    define tbid_knnpkr (BASE_42 + 148)
4442 #    define tbid_kbppkr (BASE_42 + 149)
4443 #    define tbid_kbnpkr (BASE_42 + 150)
4444 #    define tbid_kbbpkr (BASE_42 + 151)
4445 #    define tbid_krppkr (BASE_42 + 152)
4446 #    define tbid_krnpkr (BASE_42 + 153)
4447 #    define tbid_krbpkr (BASE_42 + 154)
4448 #    define tbid_krrpkr (BASE_42 + 155)
4449 #    define tbid_kqppkr (BASE_42 + 156)
4450 #    define tbid_kqnpkr (BASE_42 + 157)
4451 #    define tbid_kqbpkr (BASE_42 + 158)
4452 #    define tbid_kqrpkr (BASE_42 + 159)
4453 #    define tbid_kqqpkr (BASE_42 + 160)
4454 #    define tbid_kpppkq (BASE_42 + 161)
4455 #    define tbid_knppkq (BASE_42 + 162)
4456 #    define tbid_knnpkq (BASE_42 + 163)
4457 #    define tbid_kbppkq (BASE_42 + 164)
4458 #    define tbid_kbnpkq (BASE_42 + 165)
4459 #    define tbid_kbbpkq (BASE_42 + 166)
4460 #    define tbid_krppkq (BASE_42 + 167)
4461 #    define tbid_krnpkq (BASE_42 + 168)
4462 #    define tbid_krbpkq (BASE_42 + 169)
4463 #    define tbid_krrpkq (BASE_42 + 170)
4464 #    define tbid_kqppkq (BASE_42 + 171)
4465 #    define tbid_kqnpkq (BASE_42 + 172)
4466 #    define tbid_kqbpkq (BASE_42 + 173)
4467 #    define tbid_kqrpkq (BASE_42 + 174)
4468 #    define tbid_kqqpkq (BASE_42 + 175)
4469
4470 #    define C42 175
4471 #  else
4472 #    define C42 64
4473 #  endif
4474 #endif
4475
4476 #if defined (T42_INCLUDE)
4477 #  define cTb   (BASE_42 + C42 + 1)
4478 #else
4479 #  define cTb   (BASE_42 + 1)
4480 #endif
4481
4482 // Compression
4483
4484 #include "tbdecode.h"
4485
4486 #if !defined (CPUS)
4487 #  define   CPUS    1
4488 #endif
4489
4490 #if defined (SMP)
4491   static    lock_t  lockDecode;
4492 #endif
4493 extern "C" int TB_CRC_CHECK = 0;
4494 static int cCompressed = 0;
4495 static decode_block *rgpdbDecodeBlocks[CPUS];
4496
4497 // Information about tablebases
4498
4499 #define MAX_EXTENTS                 18  /* Maximum # of 2Gb file extents */
4500
4501 #if defined (T33_INCLUDE) || defined (T42_INCLUDE)
4502 #  define   MAX_TOTAL_PIECES        6   /* Maximum # of pieces on the board */
4503 #else
4504 #  define   MAX_TOTAL_PIECES        5   /* Maximum # of pieces on the board */
4505 #endif
4506 #define MAX_NON_KINGS           (MAX_TOTAL_PIECES - 2)
4507
4508 #if !defined (TB_DIRECTORY_SIZE)
4509 #  define   TB_DIRECTORY_SIZE       32  /* # of cache buckets */
4510 #endif
4511
4512 #if !defined (PFNCALCINDEX_DECLARED)
4513 typedef INDEX (TB_FASTCALL * PfnCalcIndex) (square *psqW, square *psqB,
4514                                          square sqEnP, int fInverse);
4515 #  define   PFNCALCINDEX_DECLARED
4516 #endif
4517
4518 struct CTbCache;
4519
4520 typedef struct      // Hungarian: tbcb
4521     {
4522 #if defined (SMP)
4523     lock_t                       m_lock;            // Lock on this cache bucket list
4524 #endif
4525     volatile CTbCache * volatile m_ptbcFirst;   // Cached file chunks in LRU order
4526     }
4527     CTbCacheBucket;
4528
4529 typedef struct      // Hungarian: tbd
4530     {
4531     int             m_iTbId;
4532     unsigned int    m_fSymmetric:1;
4533     unsigned int    m_f16bit:1;
4534     unsigned int    m_fSplit:1;
4535     PfnCalcIndex    m_rgpfnCalcIndex[2];
4536     char            m_rgchName[MAX_TOTAL_PIECES+1];
4537     INDEX           m_rgcbLength[2];
4538     char            *m_rgpchFileName[2][MAX_EXTENTS];
4539 #if defined (SMP)
4540     lock_t          m_rglockFiles[2];
4541 #endif
4542     FILE            *m_rgfpFiles[2][MAX_EXTENTS];
4543     decode_info     *m_rgpdiDecodeInfo[2][MAX_EXTENTS];
4544     CTbCacheBucket  *m_prgtbcbBuckets[2];   // Cached file chunks in LRU order
4545     BYTE            *m_rgpbRead[2];
4546     }
4547     CTbDesc;
4548
4549 #if defined (T_INDEX64) && defined (_MSC_VER)
4550 #  define   TB(name, fSym, f16bit, fSplit, funW, funB, cbW, cbB)\
4551                     { tbid_##name, fSym, f16bit, fSplit, { funW, funB }, #name, { cbW##ui64, cbB##ui64 } },
4552 #elif defined (T_INDEX64)
4553 #  define   TB(name, fSym, f16bit, fSplit, funW, funB, cbW, cbB)\
4554                     { tbid_##name, fSym, f16bit, fSplit, { funW, funB }, #name, { cbW##llu, cbB##llu } },
4555 #else
4556 #  define   TB(name, fSym, f16bit, fSplit, funW, funB, cbW, cbB)\
4557                     { tbid_##name, fSym, f16bit, fSplit, { funW, funB }, #name, { cbW##u, cbB##u } },
4558 #endif
4559
4560 #define P   x_piecePawn
4561 #define N   x_pieceKnight
4562 #define B   x_pieceBishop
4563 #define R   x_pieceRook
4564 #define Q   x_pieceQueen
4565
4566 CTbDesc rgtbdDesc[cTb] =
4567     {
4568     TB (kk, true, false, false, NULL, NULL, 0, 0)
4569
4570     TB (kpk, false, false, false, (T21<P>::IndCalcW), (T21<P>::IndCalcB), 81664, 84012)
4571     TB (knk, false, false, false, (T21<N>::IndCalcW), (T21<N>::IndCalcB), 26282, 28644)
4572     TB (kbk, false, false, false, (T21<B>::IndCalcW), (T21<B>::IndCalcB), 27243, 28644)
4573     TB (krk, false, false, false, (T21<R>::IndCalcW), (T21<R>::IndCalcB), 27030, 28644)
4574     TB (kqk, false, false, false, (T21<Q>::IndCalcW), (T21<Q>::IndCalcB), 25629, 28644)
4575
4576     TB (kpkp, false, false, false, (T22<P, P>::IndCalcW), (T22<P, P>::IndCalcB), 3863492, 3863492)
4577     TB (knkp, false, false, false, (T22<N, P>::IndCalcW), (T22<N, P>::IndCalcB), 4931904, 4981504)
4578     TB (knkn, true,  false, false, (T22<N, N>::IndCalcW), (T22<N, N>::IndCalcB), 1603202, 1603202)
4579     TB (kbkp, false, false, false, (T22<B, P>::IndCalcW), (T22<B, P>::IndCalcB), 5112000, 4981504)
4580     TB (kbkn, false, false, false, (T22<B, N>::IndCalcW), (T22<B, N>::IndCalcB), 1661823, 1603202)
4581     TB (kbkb, true,  false, false, (T22<B, B>::IndCalcW), (T22<B, B>::IndCalcB), 1661823, 1661823)
4582     TB (krkp, false, false, false, (T22<R, P>::IndCalcW), (T22<R, P>::IndCalcB), 5072736, 4981504)
4583     TB (krkn, false, false, false, (T22<R, N>::IndCalcW), (T22<R, N>::IndCalcB), 1649196, 1603202)
4584     TB (krkb, false, false, false, (T22<R, B>::IndCalcW), (T22<R, B>::IndCalcB), 1649196, 1661823)
4585     TB (krkr, true,  false, false, (T22<R, R>::IndCalcW), (T22<R, R>::IndCalcB), 1649196, 1649196)
4586     TB (kqkp, false, false, false, (T22<Q, P>::IndCalcW), (T22<Q, P>::IndCalcB), 4810080, 4981504)
4587     TB (kqkn, false, false, false, (T22<Q, N>::IndCalcW), (T22<Q, N>::IndCalcB), 1563735, 1603202)
4588     TB (kqkb, false, false, false, (T22<Q, B>::IndCalcW), (T22<Q, B>::IndCalcB), 1563735, 1661823)
4589     TB (kqkr, false, false, false, (T22<Q, R>::IndCalcW), (T22<Q, R>::IndCalcB), 1563735, 1649196)
4590     TB (kqkq, true,  false, false, (T22<Q, Q>::IndCalcW), (T22<Q, Q>::IndCalcB), 1563735, 1563735)
4591     TB (kppk, false, false, false, (T31<P, P>::IndCalcW), (T31<P, P>::IndCalcB), 1806671, 1912372)
4592     TB (knpk, false, false, false, (T31<N, P>::IndCalcW), (T31<N, P>::IndCalcB), 4648581, 5124732)
4593     TB (knnk, false, false, false, (T31<N, N>::IndCalcW), (T31<N, N>::IndCalcB),  735304,  873642)
4594     TB (kbpk, false, false, false, (T31<B, P>::IndCalcW), (T31<B, P>::IndCalcB), 4817128, 5124732)
4595     TB (kbnk, false, false, false, (T31<B, N>::IndCalcW), (T31<B, N>::IndCalcB), 1550620, 1747284)
4596     TB (kbbk, false, false, false, (T31<B, B>::IndCalcW), (T31<B, B>::IndCalcB),  789885,  873642)
4597     TB (krpk, false, false, false, (T31<R, P>::IndCalcW), (T31<R, P>::IndCalcB), 4779530, 5124732)
4598     TB (krnk, false, false, false, (T31<R, N>::IndCalcW), (T31<R, N>::IndCalcB), 1538479, 1747284)
4599     TB (krbk, false, false, false, (T31<R, B>::IndCalcW), (T31<R, B>::IndCalcB), 1594560, 1747284)
4600     TB (krrk, false, false, false, (T31<R, R>::IndCalcW), (T31<R, R>::IndCalcB),  777300,  873642)
4601     TB (kqpk, false, false, false, (T31<Q, P>::IndCalcW), (T31<Q, P>::IndCalcB), 4533490, 5124732)
4602     TB (kqnk, false, false, false, (T31<Q, N>::IndCalcW), (T31<Q, N>::IndCalcB), 1459616, 1747284)
4603     TB (kqbk, false, false, false, (T31<Q, B>::IndCalcW), (T31<Q, B>::IndCalcB), 1512507, 1747284)
4604     TB (kqrk, false, false, false, (T31<Q, R>::IndCalcW), (T31<Q, R>::IndCalcB), 1500276, 1747284)
4605     TB (kqqk, false, false, false, (T31<Q, Q>::IndCalcW), (T31<Q, Q>::IndCalcB),  698739,  873642)
4606
4607 #if !defined (KPPKP_16BIT)
4608     TB (kppkp, false, false, false, (T32<P, P, P>::IndCalcW), (T32<P, P, P>::IndCalcB),  84219361,  89391280)
4609 #else
4610     TB (kppkp, false, true,  false, (T32<P, P, P>::IndCalcW), (T32<P, P, P>::IndCalcB),  84219361,  89391280)
4611 #endif
4612     TB (kppkn, false, false, false, (T32<P, P, N>::IndCalcW), (T32<P, P, N>::IndCalcB), 108400260, 115899744)
4613     TB (kppkb, false, false, false, (T32<P, P, B>::IndCalcW), (T32<P, P, B>::IndCalcB), 108400260, 120132000)
4614     TB (kppkr, false, false, false, (T32<P, P, R>::IndCalcW), (T32<P, P, R>::IndCalcB), 108400260, 119209296)
4615     TB (kppkq, false, false, false, (T32<P, P, Q>::IndCalcW), (T32<P, P, Q>::IndCalcB), 108400260, 113036880)
4616     TB (knpkp, false, false, false, (T32<N, P, P>::IndCalcW), (T32<N, P, P>::IndCalcB), 219921779, 231758952)
4617     TB (knpkn, false, false, false, (T32<N, P, N>::IndCalcW), (T32<N, P, N>::IndCalcB), 278914860, 295914240)
4618     TB (knpkb, false, false, false, (T32<N, P, B>::IndCalcW), (T32<N, P, B>::IndCalcB), 278914860, 306720000)
4619     TB (knpkr, false, false, false, (T32<N, P, R>::IndCalcW), (T32<N, P, R>::IndCalcB), 278914860, 304369920)
4620     TB (knpkq, false, false, false, (T32<N, P, Q>::IndCalcW), (T32<N, P, Q>::IndCalcB), 278914860, 288610560)
4621     TB (knnkp, false, false, false, (T32<N, N, P>::IndCalcW), (T32<N, N, P>::IndCalcB), 137991648, 149445120)
4622     TB (knnkn, false, false, false, (T32<N, N, N>::IndCalcW), (T32<N, N, N>::IndCalcB),  44118240,  48096060)
4623     TB (knnkb, false, false, false, (T32<N, N, B>::IndCalcW), (T32<N, N, B>::IndCalcB),  44118240,  49854690)
4624     TB (knnkr, false, false, false, (T32<N, N, R>::IndCalcW), (T32<N, N, R>::IndCalcB),  44118240,  49475880)
4625     TB (knnkq, false, false, false, (T32<N, N, Q>::IndCalcW), (T32<N, N, Q>::IndCalcB),  44118240,  46912050)
4626     TB (kbpkp, false, false, false, (T32<B, P, P>::IndCalcW), (T32<B, P, P>::IndCalcB), 227896016, 231758952)
4627     TB (kbpkn, false, false, false, (T32<B, P, N>::IndCalcW), (T32<B, P, N>::IndCalcB), 289027680, 295914240)
4628     TB (kbpkb, false, false, false, (T32<B, P, B>::IndCalcW), (T32<B, P, B>::IndCalcB), 289027680, 306720000)
4629     TB (kbpkr, false, false, false, (T32<B, P, R>::IndCalcW), (T32<B, P, R>::IndCalcB), 289027680, 304369920)
4630     TB (kbpkq, false, false, false, (T32<B, P, Q>::IndCalcW), (T32<B, P, Q>::IndCalcB), 289027680, 288610560)
4631     TB (kbnkp, false, false, false, (T32<B, N, P>::IndCalcW), (T32<B, N, P>::IndCalcB), 290989584, 298890240)
4632     TB (kbnkn, false, false, false, (T32<B, N, N>::IndCalcW), (T32<B, N, N>::IndCalcB),  93037200,  96192120)
4633     TB (kbnkb, false, false, false, (T32<B, N, B>::IndCalcW), (T32<B, N, B>::IndCalcB),  93037200,  99709380)
4634     TB (kbnkr, false, false, false, (T32<B, N, R>::IndCalcW), (T32<B, N, R>::IndCalcB),  93037200,  98951760)
4635     TB (kbnkq, false, false, false, (T32<B, N, Q>::IndCalcW), (T32<B, N, Q>::IndCalcB),  93037200,  93824100)
4636     TB (kbbkp, false, false, false, (T32<B, B, P>::IndCalcW), (T32<B, B, P>::IndCalcB), 148223520, 149445120)
4637     TB (kbbkn, false, false, false, (T32<B, B, N>::IndCalcW), (T32<B, B, N>::IndCalcB),  47393100,  48096060)
4638     TB (kbbkb, false, false, false, (T32<B, B, B>::IndCalcW), (T32<B, B, B>::IndCalcB),  47393100,  49854690)
4639     TB (kbbkr, false, false, false, (T32<B, B, R>::IndCalcW), (T32<B, B, R>::IndCalcB),  47393100,  49475880)
4640     TB (kbbkq, false, false, false, (T32<B, B, Q>::IndCalcW), (T32<B, B, Q>::IndCalcB),  47393100,  46912050)
4641     TB (krpkp, false, false, false, (T32<R, P, P>::IndCalcW), (T32<R, P, P>::IndCalcB), 226121876, 231758952)
4642     TB (krpkn, false, false, false, (T32<R, P, N>::IndCalcW), (T32<R, P, N>::IndCalcB), 286777440, 295914240)
4643     TB (krpkb, false, false, false, (T32<R, P, B>::IndCalcW), (T32<R, P, B>::IndCalcB), 286777440, 306720000)
4644     TB (krpkr, false, false, false, (T32<R, P, R>::IndCalcW), (T32<R, P, R>::IndCalcB), 286777440, 304369920)
4645     TB (krpkq, false, false, false, (T32<R, P, Q>::IndCalcW), (T32<R, P, Q>::IndCalcB), 286777440, 288610560)
4646     TB (krnkp, false, false, false, (T32<R, N, P>::IndCalcW), (T32<R, N, P>::IndCalcB), 288692928, 298890240)
4647     TB (krnkn, false, false, false, (T32<R, N, N>::IndCalcW), (T32<R, N, N>::IndCalcB),  92308740,  96192120)
4648     TB (krnkb, false, false, false, (T32<R, N, B>::IndCalcW), (T32<R, N, B>::IndCalcB),  92308740,  99709380)
4649     TB (krnkr, false, false, false, (T32<R, N, R>::IndCalcW), (T32<R, N, R>::IndCalcB),  92308740,  98951760)
4650     TB (krnkq, false, false, false, (T32<R, N, Q>::IndCalcW), (T32<R, N, Q>::IndCalcB),  92308740,  93824100)
4651     TB (krbkp, false, false, false, (T32<R, B, P>::IndCalcW), (T32<R, B, P>::IndCalcB), 299203200, 298890240)
4652     TB (krbkn, false, false, false, (T32<R, B, N>::IndCalcW), (T32<R, B, N>::IndCalcB),  95673600,  96192120)
4653     TB (krbkb, false, false, false, (T32<R, B, B>::IndCalcW), (T32<R, B, B>::IndCalcB),  95673600,  99709380)
4654     TB (krbkr, false, false, false, (T32<R, B, R>::IndCalcW), (T32<R, B, R>::IndCalcB),  95673600,  98951760)
4655     TB (krbkq, false, false, false, (T32<R, B, Q>::IndCalcW), (T32<R, B, Q>::IndCalcB),  95673600,  93824100)
4656     TB (krrkp, false, false, false, (T32<R, R, P>::IndCalcW), (T32<R, R, P>::IndCalcB), 145901232, 149445120)
4657     TB (krrkn, false, false, false, (T32<R, R, N>::IndCalcW), (T32<R, R, N>::IndCalcB),  46658340,  48096060)
4658     TB (krrkb, false, false, false, (T32<R, R, B>::IndCalcW), (T32<R, R, B>::IndCalcB),  46658340,  49854690)
4659     TB (krrkr, false, false, false, (T32<R, R, R>::IndCalcW), (T32<R, R, R>::IndCalcB),  46658340,  49475880)
4660     TB (krrkq, false, false, false, (T32<R, R, Q>::IndCalcW), (T32<R, R, Q>::IndCalcB),  46658340,  46912050)
4661     TB (kqpkp, false, false, false, (T32<Q, P, P>::IndCalcW), (T32<Q, P, P>::IndCalcB), 214481388, 231758952)
4662     TB (kqpkn, false, false, false, (T32<Q, P, N>::IndCalcW), (T32<Q, P, N>::IndCalcB), 272015040, 295914240)
4663     TB (kqpkb, false, false, false, (T32<Q, P, B>::IndCalcW), (T32<Q, P, B>::IndCalcB), 272015040, 306720000)
4664     TB (kqpkr, false, false, false, (T32<Q, P, R>::IndCalcW), (T32<Q, P, R>::IndCalcB), 272015040, 304369920)
4665     TB (kqpkq, false, false, false, (T32<Q, P, Q>::IndCalcW), (T32<Q, P, Q>::IndCalcB), 272015040, 288610560)
4666     TB (kqnkp, false, false, false, (T32<Q, N, P>::IndCalcW), (T32<Q, N, P>::IndCalcB), 273904512, 298890240)
4667     TB (kqnkn, false, false, false, (T32<Q, N, N>::IndCalcW), (T32<Q, N, N>::IndCalcB),  87576960,  96192120)
4668     TB (kqnkb, false, false, false, (T32<Q, N, B>::IndCalcW), (T32<Q, N, B>::IndCalcB),  87576960,  99709380)
4669     TB (kqnkr, false, false, false, (T32<Q, N, R>::IndCalcW), (T32<Q, N, R>::IndCalcB),  87576960,  98951760)
4670     TB (kqnkq, false, false, false, (T32<Q, N, Q>::IndCalcW), (T32<Q, N, Q>::IndCalcB),  87576960,  93824100)
4671     TB (kqbkp, false, false, false, (T32<Q, B, P>::IndCalcW), (T32<Q, B, P>::IndCalcB), 283818240, 298890240)
4672     TB (kqbkn, false, false, false, (T32<Q, B, N>::IndCalcW), (T32<Q, B, N>::IndCalcB),  90750420,  96192120)
4673     TB (kqbkb, false, false, false, (T32<Q, B, B>::IndCalcW), (T32<Q, B, B>::IndCalcB),  90750420,  99709380)
4674     TB (kqbkr, false, false, false, (T32<Q, B, R>::IndCalcW), (T32<Q, B, R>::IndCalcB),  90750420,  98951760)
4675     TB (kqbkq, false, false, false, (T32<Q, B, Q>::IndCalcW), (T32<Q, B, Q>::IndCalcB),  90750420,  93824100)
4676     TB (kqrkp, false, false, false, (T32<Q, R, P>::IndCalcW), (T32<Q, R, P>::IndCalcB), 281568240, 298890240)
4677     TB (kqrkn, false, false, false, (T32<Q, R, N>::IndCalcW), (T32<Q, R, N>::IndCalcB),  90038460,  96192120)
4678     TB (kqrkb, false, false, false, (T32<Q, R, B>::IndCalcW), (T32<Q, R, B>::IndCalcB),  90038460,  99709380)
4679     TB (kqrkr, false, false, false, (T32<Q, R, R>::IndCalcW), (T32<Q, R, R>::IndCalcB),  90038460,  98951760)
4680     TB (kqrkq, false, false, false, (T32<Q, R, Q>::IndCalcW), (T32<Q, R, Q>::IndCalcB),  90038460,  93824100)
4681     TB (kqqkp, false, false, false, (T32<Q, Q, P>::IndCalcW), (T32<Q, Q, P>::IndCalcB), 131170128, 149445120)
4682     TB (kqqkn, false, false, false, (T32<Q, Q, N>::IndCalcW), (T32<Q, Q, N>::IndCalcB),  41944320,  48096060)
4683     TB (kqqkb, false, false, false, (T32<Q, Q, B>::IndCalcW), (T32<Q, Q, B>::IndCalcB),  41944320,  49854690)
4684     TB (kqqkr, false, false, false, (T32<Q, Q, R>::IndCalcW), (T32<Q, Q, R>::IndCalcB),  41944320,  49475880)
4685     TB (kqqkq, false, false, false, (T32<Q, Q, Q>::IndCalcW), (T32<Q, Q, Q>::IndCalcB),  41944320,  46912050)
4686
4687 #if defined (T41_INCLUDE)
4688     TB (kpppk, false, false, false, (T41<P, P, P>::IndCalcW), (T41<P, P, P>::IndCalcB),  26061704,  28388716)
4689     TB (knppk, false, false, false, (T41<N, P, P>::IndCalcW), (T41<N, P, P>::IndCalcB), 102898651, 114742320)
4690     TB (knnpk, false, false, false, (T41<N, N, P>::IndCalcW), (T41<N, N, P>::IndCalcB), 130135501, 153741960)
4691     TB (knnnk, false, false, false, (T41<N, N, N>::IndCalcW), (T41<N, N, N>::IndCalcB),  13486227,  17472840)
4692     TB (kbppk, false, false, false, (T41<B, P, P>::IndCalcW), (T41<B, P, P>::IndCalcB), 106602156, 114742320)
4693     TB (kbnpk, false, false, false, (T41<B, N, P>::IndCalcW), (T41<B, N, P>::IndCalcB), 274352939, 307483920)
4694     TB (kbnnk, false, false, false, (T41<B, N, N>::IndCalcW), (T41<B, N, N>::IndCalcB),  43406294, 52418520)
4695     TB (kbbpk, false, false, false, (T41<B, B, P>::IndCalcW), (T41<B, B, P>::IndCalcB), 139715040, 153741960)
4696     TB (kbbnk, false, false, false, (T41<B, B, N>::IndCalcW), (T41<B, B, N>::IndCalcB),  44983618,  52418520)
4697     TB (kbbbk, false, false, false, (T41<B, B, B>::IndCalcW), (T41<B, B, B>::IndCalcB),  15010230,  17472840)
4698     TB (krppk, false, false, false, (T41<R, P, P>::IndCalcW), (T41<R, P, P>::IndCalcB), 105758666, 114742320)
4699     TB (krnpk, false, false, false, (T41<R, N, P>::IndCalcW), (T41<R, N, P>::IndCalcB), 272153675, 307483920)
4700     TB (krnnk, false, false, false, (T41<R, N, N>::IndCalcW), (T41<R, N, N>::IndCalcB),  43056198,  52418520)
4701     TB (krbpk, false, false, false, (T41<R, B, P>::IndCalcW), (T41<R, B, P>::IndCalcB), 281991360, 307483920)
4702     TB (krbnk, false, false, false, (T41<R, B, N>::IndCalcW), (T41<R, B, N>::IndCalcB),  90787358, 104837040)
4703     TB (krbbk, false, false, false, (T41<R, B, B>::IndCalcW), (T41<R, B, B>::IndCalcB),  46242089,  52418520)
4704     TB (krrpk, false, false, false, (T41<R, R, P>::IndCalcW), (T41<R, R, P>::IndCalcB), 137491197, 153741960)
4705     TB (krrnk, false, false, false, (T41<R, R, N>::IndCalcW), (T41<R, R, N>::IndCalcB),  44265261,  52418520)
4706     TB (krrbk, false, false, false, (T41<R, R, B>::IndCalcW), (T41<R, R, B>::IndCalcB),  45873720,  52418520)
4707     TB (krrrk, false, false, false, (T41<R, R, R>::IndCalcW), (T41<R, R, R>::IndCalcB),  14644690,  17472840)
4708     TB (kqppk, false, false, false, (T41<Q, P, P>::IndCalcW), (T41<Q, P, P>::IndCalcB), 100347220, 114742320)
4709     TB (kqnpk, false, false, false, (T41<Q, N, P>::IndCalcW), (T41<Q, N, P>::IndCalcB), 258294639, 307483920)
4710     TB (kqnnk, false, false, false, (T41<Q, N, N>::IndCalcW), (T41<Q, N, N>::IndCalcB),  40873646,  52418520)
4711     TB (kqbpk, false, false, false, (T41<Q, B, P>::IndCalcW), (T41<Q, B, P>::IndCalcB), 267576632, 307483920)
4712     TB (kqbnk, false, false, false, (T41<Q, B, N>::IndCalcW), (T41<Q, B, N>::IndCalcB),  86166717, 104837040)
4713     TB (kqbbk, false, false, false, (T41<Q, B, B>::IndCalcW), (T41<Q, B, B>::IndCalcB),  43879679,  52418520)
4714     TB (kqrpk, false, false, false, (T41<Q, R, P>::IndCalcW), (T41<Q, R, P>::IndCalcB), 265421907, 307483920)
4715     TB (kqrnk, false, false, false, (T41<Q, R, N>::IndCalcW), (T41<Q, R, N>::IndCalcB),  85470603, 104837040)
4716     TB (kqrbk, false, false, false, (T41<Q, R, B>::IndCalcW), (T41<Q, R, B>::IndCalcB),  88557959, 104837040)
4717     TB (kqrrk, false, false, false, (T41<Q, R, R>::IndCalcW), (T41<Q, R, R>::IndCalcB),  43157690,  52418520)
4718     TB (kqqpk, false, false, false, (T41<Q, Q, P>::IndCalcW), (T41<Q, Q, P>::IndCalcB), 123688859, 153741960)
4719     TB (kqqnk, false, false, false, (T41<Q, Q, N>::IndCalcW), (T41<Q, Q, N>::IndCalcB),  39840787,  52418520)
4720     TB (kqqbk, false, false, false, (T41<Q, Q, B>::IndCalcW), (T41<Q, Q, B>::IndCalcB),  41270973,  52418520)
4721     TB (kqqrk, false, false, false, (T41<Q, Q, R>::IndCalcW), (T41<Q, Q, R>::IndCalcB),  40916820,  52418520)
4722     TB (kqqqk, false, false, false, (T41<Q, Q, Q>::IndCalcW), (T41<Q, Q, Q>::IndCalcB),  12479974,  17472840)
4723 #endif
4724
4725 #if defined (T33_INCLUDE)
4726     TB (knnknn, true,  false, false, (T33<N, N, N, N>::IndCalcW), (T33<N, N, N, N>::IndCalcB),  1301488080,  1301488080)
4727     TB (kbnknn, false, false, false, (T33<B, N, N, N>::IndCalcW), (T33<B, N, N, N>::IndCalcB),  2744597400,  2602976160)
4728     TB (kbbknn, false, false, false, (T33<B, B, N, N>::IndCalcW), (T33<B, B, N, N>::IndCalcB),  1398096450,  1301488080)
4729     TB (kbbkbn, false, false, false, (T33<B, B, B, N>::IndCalcW), (T33<B, B, B, N>::IndCalcB),  2796192900,  2744597400)
4730     TB (kbbkbb, true,  false, false, (T33<B, B, B, B>::IndCalcW), (T33<B, B, B, B>::IndCalcB),  1398096450,  1398096450)
4731     TB (krnknn, false, true,  false, (T33<R, N, N, N>::IndCalcW), (T33<R, N, N, N>::IndCalcB),  2723107830,  2602976160)
4732     TB (krnkbb, false, true,  false, (T33<R, N, B, B>::IndCalcW), (T33<R, N, B, B>::IndCalcB),  2723107830,  2796192900)
4733     TB (krbknn, false, true,  false, (T33<R, B, N, N>::IndCalcW), (T33<R, B, N, N>::IndCalcB),  2822371200,  2602976160)
4734     TB (krbkbb, false, false, false, (T33<R, B, B, B>::IndCalcW), (T33<R, B, B, B>::IndCalcB),  2822371200,  2796192900)
4735     TB (krrknn, false, false, false, (T33<R, R, N, N>::IndCalcW), (T33<R, R, N, N>::IndCalcB),  1376421030,  1301488080)
4736     TB (krrkbn, false, false, false, (T33<R, R, B, N>::IndCalcW), (T33<R, R, B, N>::IndCalcB),  2752842060,  2744597400)
4737     TB (krrkbb, false, false, false, (T33<R, R, B, B>::IndCalcW), (T33<R, R, B, B>::IndCalcB),  1376421030,  1398096450)
4738     TB (krrkrn, false, false, false, (T33<R, R, R, N>::IndCalcW), (T33<R, R, R, N>::IndCalcB),  2752842060,  2723107830)
4739     TB (krrkrb, false, false, false, (T33<R, R, R, B>::IndCalcW), (T33<R, R, R, B>::IndCalcB),  2752842060,  2822371200)
4740     TB (krrkrr, true,  false, false, (T33<R, R, R, R>::IndCalcW), (T33<R, R, R, R>::IndCalcB),  1376421030,  1376421030)
4741     TB (kqnknn, false, false, false, (T33<Q, N, N, N>::IndCalcW), (T33<Q, N, N, N>::IndCalcB),  2583520320,  2602976160)
4742     TB (kqnkbb, false, false, false, (T33<Q, N, B, B>::IndCalcW), (T33<Q, N, B, B>::IndCalcB),  2583520320,  2796192900)
4743     TB (kqnkrr, false, true,  false, (T33<Q, N, R, R>::IndCalcW), (T33<Q, N, R, R>::IndCalcB),  2583520320,  2752842060)
4744     TB (kqbknn, false, false, false, (T33<Q, B, N, N>::IndCalcW), (T33<Q, B, N, N>::IndCalcB),  2677137390,  2602976160)
4745     TB (kqbkbb, false, false, false, (T33<Q, B, B, B>::IndCalcW), (T33<Q, B, B, B>::IndCalcB),  2677137390,  2796192900)
4746     TB (kqbkrr, false, false, false, (T33<Q, B, R, R>::IndCalcW), (T33<Q, B, R, R>::IndCalcB),  2677137390,  2752842060)
4747     TB (kqrknn, false, false, false, (T33<Q, R, N, N>::IndCalcW), (T33<Q, R, N, N>::IndCalcB),  2656134570,  2602976160)
4748     TB (kqrkbb, false, false, false, (T33<Q, R, B, B>::IndCalcW), (T33<Q, R, B, B>::IndCalcB),  2656134570,  2796192900)
4749     TB (kqrkrr, false, false, false, (T33<Q, R, R, R>::IndCalcW), (T33<Q, R, R, R>::IndCalcB),  2656134570,  2752842060)
4750     TB (kqqknn, false, false, false, (T33<Q, Q, N, N>::IndCalcW), (T33<Q, Q, N, N>::IndCalcB),  1237357440,  1301488080)
4751     TB (kqqkbn, false, false, false, (T33<Q, Q, B, N>::IndCalcW), (T33<Q, Q, B, N>::IndCalcB),  2474714880,  2744597400)
4752     TB (kqqkbb, false, false, false, (T33<Q, Q, B, B>::IndCalcW), (T33<Q, Q, B, B>::IndCalcB),  1237357440,  1398096450)
4753     TB (kqqkrn, false, false, false, (T33<Q, Q, R, N>::IndCalcW), (T33<Q, Q, R, N>::IndCalcB),  2474714880,  2723107830)
4754     TB (kqqkrb, false, false, false, (T33<Q, Q, R, B>::IndCalcW), (T33<Q, Q, R, B>::IndCalcB),  2474714880,  2822371200)
4755     TB (kqqkrr, false, false, false, (T33<Q, Q, R, R>::IndCalcW), (T33<Q, Q, R, R>::IndCalcB),  1237357440,  1376421030)
4756     TB (kqqkqn, false, false, false, (T33<Q, Q, Q, N>::IndCalcW), (T33<Q, Q, Q, N>::IndCalcB),  2474714880,  2583520320)
4757     TB (kqqkqb, false, false, false, (T33<Q, Q, Q, B>::IndCalcW), (T33<Q, Q, Q, B>::IndCalcB),  2474714880,  2677137390)
4758     TB (kqqkqr, false, false, false, (T33<Q, Q, Q, R>::IndCalcW), (T33<Q, Q, Q, R>::IndCalcB),  2474714880,  2656134570)
4759     TB (kqqkqq, true,  false, false, (T33<Q, Q, Q, Q>::IndCalcW), (T33<Q, Q, Q, Q>::IndCalcB),  1237357440,  1237357440)
4760 #if defined (T_INDEX64)
4761     TB (kbnkbn, true,  false, false, (T33<B, N, B, N>::IndCalcW), (T33<B, N, B, N>::IndCalcB),  5489194800,  5489194800)
4762     TB (krnkrn, true,  false, false, (T33<R, N, R, N>::IndCalcW), (T33<R, N, R, N>::IndCalcB),  5446215660,  5446215660)
4763     TB (krbkrb, true,  false, false, (T33<R, B, R, B>::IndCalcW), (T33<R, B, R, B>::IndCalcB),  5644742400,  5644742400)
4764     TB (kqnkqn, true,  false, false, (T33<Q, N, Q, N>::IndCalcW), (T33<Q, N, Q, N>::IndCalcB),  5167040640,  5167040640)
4765     TB (kqbkqb, true,  false, false, (T33<Q, B, Q, B>::IndCalcW), (T33<Q, B, Q, B>::IndCalcB),  5354274780,  5354274780)
4766     TB (kqrkqr, true,  false, false, (T33<Q, R, Q, R>::IndCalcW), (T33<Q, R, Q, R>::IndCalcB),  5312269140,  5312269140)
4767     TB (krnkbn, false, true,  true,  (T33<R, N, B, N>::IndCalcW), (T33<R, N, B, N>::IndCalcB),  5446215660,  5489194800)
4768     TB (krbkbn, false, false, true,  (T33<R, B, B, N>::IndCalcW), (T33<R, B, B, N>::IndCalcB),  5644742400,  5489194800)
4769     TB (krbkrn, false, false, false, (T33<R, B, R, N>::IndCalcW), (T33<R, B, R, N>::IndCalcB),  5644742400,  5446215660)
4770     TB (kqnkbn, false, false, false, (T33<Q, N, B, N>::IndCalcW), (T33<Q, N, B, N>::IndCalcB),  5167040640,  5489194800)
4771     TB (kqnkrn, false, false, true,  (T33<Q, N, R, N>::IndCalcW), (T33<Q, N, R, N>::IndCalcB),  5167040640,  5446215660)
4772     TB (kqnkrb, false, false, true,  (T33<Q, N, R, B>::IndCalcW), (T33<Q, N, R, B>::IndCalcB),  5167040640,  5644742400)
4773     TB (kqbkbn, false, false, false, (T33<Q, B, B, N>::IndCalcW), (T33<Q, B, B, N>::IndCalcB),  5354274780,  5489194800)
4774     TB (kqbkrn, false, false, true,  (T33<Q, B, R, N>::IndCalcW), (T33<Q, B, R, N>::IndCalcB),  5354274780,  5446215660)
4775     TB (kqbkrb, false, false, true,  (T33<Q, B, R, B>::IndCalcW), (T33<Q, B, R, B>::IndCalcB),  5354274780,  5644742400)
4776     TB (kqbkqn, false, false, false, (T33<Q, B, Q, N>::IndCalcW), (T33<Q, B, Q, N>::IndCalcB),  5354274780,  5167040640)
4777     TB (kqrkbn, false, false, false, (T33<Q, R, B, N>::IndCalcW), (T33<Q, R, B, N>::IndCalcB),  5312269140,  5489194800)
4778     TB (kqrkrn, false, false, false, (T33<Q, R, R, N>::IndCalcW), (T33<Q, R, R, N>::IndCalcB),  5312269140,  5446215660)
4779     TB (kqrkrb, false, false, false, (T33<Q, R, R, B>::IndCalcW), (T33<Q, R, R, B>::IndCalcB),  5312269140,  5644742400)
4780     TB (kqrkqn, false, false, false, (T33<Q, R, Q, N>::IndCalcW), (T33<Q, R, Q, N>::IndCalcB),  5312269140,  5167040640)
4781     TB (kqrkqb, false, false, false, (T33<Q, R, Q, B>::IndCalcW), (T33<Q, R, Q, B>::IndCalcB),  5312269140,  5354274780)
4782
4783     TB (kppkpp, true,  true,  false, (T33<P, P, P, P>::IndCalcW), (T33<P, P, P, P>::IndCalcBF),  1917741812,  1917741812)
4784     TB (knpkpp, false, true,  true,  (T33<N, P, P, P>::IndCalcW), (T33<N, P, P, P>::IndCalcB),   5088408829,  4966717366)
4785     TB (knpknp, true,  false, true,  (T33<N, P, N, P>::IndCalcW), (T33<N, P, N, P>::IndCalcBF), 12972508017, 12972508017)
4786     TB (knnkpp, false, true,  false, (T33<N, N, P, P>::IndCalcW), (T33<N, N, P, P>::IndCalcB),   3242803728,  3197807670)
4787     TB (knnknp, false, true,  true,  (T33<N, N, N, P>::IndCalcW), (T33<N, N, N, P>::IndCalcB),   8141507232,  8227988370)
4788     TB (kbpkpp, false, true,  true,  (T33<B, P, P, P>::IndCalcW), (T33<B, P, P, P>::IndCalcB),   5272919368,  4966717366)
4789     TB (kbpknp, false, true,  true,  (T33<B, P, N, P>::IndCalcW), (T33<B, P, N, P>::IndCalcB),  13442882944, 12972508017)
4790     TB (kbpknn, false, true,  true,  (T33<B, P, N, N>::IndCalcW), (T33<B, P, N, N>::IndCalcB),   8526316560,  8141507232)
4791     TB (kbpkbp, true,  false, true,  (T33<B, P, B, P>::IndCalcW), (T33<B, P, B, P>::IndCalcBF), 13442882944, 13442882944)
4792     TB (kbnkpp, false, true,  true,  (T33<B, N, P, P>::IndCalcW), (T33<B, N, P, P>::IndCalcB),   6838255224,  6395615340)
4793     TB (kbnknp, false, true,  true,  (T33<B, N, N, P>::IndCalcW), (T33<B, N, N, P>::IndCalcB),  17168385456, 16455976740)
4794     TB (kbnkbp, false, false, true,  (T33<B, N, B, P>::IndCalcW), (T33<B, N, B, P>::IndCalcB),  17168385456, 17052633120)
4795     TB (kbbkpp, false, false, false, (T33<B, B, P, P>::IndCalcW), (T33<B, B, P, P>::IndCalcB),   3483252720,  3197807670)
4796     TB (kbbknp, false, true,  true,  (T33<B, B, N, P>::IndCalcW), (T33<B, B, N, P>::IndCalcB),   8745187680,  8227988370)
4797     TB (kbbkbp, false, false, true,  (T33<B, B, B, P>::IndCalcW), (T33<B, B, B, P>::IndCalcB),   8745187680,  8526316560)
4798     TB (krpkpp, false, true,  true,  (T33<R, P, P, P>::IndCalcW), (T33<R, P, P, P>::IndCalcB),   5231873656,  4966717366)
4799     TB (krpknp, false, true,  true,  (T33<R, P, N, P>::IndCalcW), (T33<R, P, N, P>::IndCalcB),  13338233184, 12972508017)
4800     TB (krpknn, false, true,  true,  (T33<R, P, N, N>::IndCalcW), (T33<R, P, N, N>::IndCalcB),   8459934480,  8141507232)
4801     TB (krpkbp, false, true,  true,  (T33<R, P, B, P>::IndCalcW), (T33<R, P, B, P>::IndCalcB),  13338233184, 13442882944)
4802     TB (krpkbn, false, true,  true,  (T33<R, P, B, N>::IndCalcW), (T33<R, P, B, N>::IndCalcB),  16919868960, 17168385456)
4803     TB (krpkbb, false, true,  true,  (T33<R, P, B, B>::IndCalcW), (T33<R, P, B, B>::IndCalcB),   8459934480,  8745187680)
4804     TB (krpkrp, true,  false, true,  (T33<R, P, R, P>::IndCalcW), (T33<R, P, R, P>::IndCalcBF), 13338233184, 13338233184)
4805     TB (krnkpp, false, true,  true,  (T33<R, N, P, P>::IndCalcW), (T33<R, N, P, P>::IndCalcB),   6784283808,  6395615340)
4806     TB (krnknp, false, true,  true,  (T33<R, N, N, P>::IndCalcW), (T33<R, N, N, P>::IndCalcB),  17032882752, 16455976740)
4807     TB (krnkbp, false, true,  true,  (T33<R, N, B, P>::IndCalcW), (T33<R, N, B, P>::IndCalcB),  17032882752, 17052633120)
4808     TB (krnkrp, false, false, true,  (T33<R, N, R, P>::IndCalcW), (T33<R, N, R, P>::IndCalcB),  17032882752, 16919868906)
4809     TB (krbkpp, false, true,  true,  (T33<R, B, P, P>::IndCalcW), (T33<R, B, P, P>::IndCalcB),   7031275200,  6395615340)
4810     TB (krbknp, false, true,  true,  (T33<R, B, N, P>::IndCalcW), (T33<R, B, N, P>::IndCalcB),  17652988800, 16455976740)
4811     TB (krbkbp, false, false, true,  (T33<R, B, B, P>::IndCalcW), (T33<R, B, B, P>::IndCalcB),  17652988800, 17052633120)
4812     TB (krbkrp, false, false, true,  (T33<R, B, R, P>::IndCalcW), (T33<R, B, R, P>::IndCalcB),  17652988800, 16919868906)
4813     TB (krrkpp, false, true,  false, (T33<R, R, P, P>::IndCalcW), (T33<R, R, P, P>::IndCalcB),   3428678952,  3197807670)
4814     TB (krrknp, false, true,  true,  (T33<R, R, N, P>::IndCalcW), (T33<R, R, N, P>::IndCalcB),   8608504032,  8227988370)
4815     TB (krrkbp, false, false, true,  (T33<R, R, B, P>::IndCalcW), (T33<R, R, B, P>::IndCalcB),   8608504032,  8526316560)
4816     TB (krrkrp, false, false, true,  (T33<R, R, R, P>::IndCalcW), (T33<R, R, R, P>::IndCalcB),   8608504032,  8459934426)
4817     TB (kqpkpp, false, true,  true,  (T33<Q, P, P, P>::IndCalcW), (T33<Q, P, P, P>::IndCalcB),   4962533664,  4966717366)
4818     TB (kqpknp, false, false, true,  (T33<Q, P, N, P>::IndCalcW), (T33<Q, P, N, P>::IndCalcB),  12651597608, 12972508017)
4819     TB (kqpknn, false, false, true,  (T33<Q, P, N, N>::IndCalcW), (T33<Q, P, N, N>::IndCalcB),   8024443680,  8141507232)
4820     TB (kqpkbp, false, false, true,  (T33<Q, P, B, P>::IndCalcW), (T33<Q, P, B, P>::IndCalcB),  12651597608, 13442882944)
4821     TB (kqpkbn, false, false, true,  (T33<Q, P, B, N>::IndCalcW), (T33<Q, P, B, N>::IndCalcB),  16048887360, 17168385456)
4822     TB (kqpkbb, false, false, true,  (T33<Q, P, B, B>::IndCalcW), (T33<Q, P, B, B>::IndCalcB),   8024443680,  8745187680)
4823     TB (kqpkrp, false, false, true,  (T33<Q, P, R, P>::IndCalcW), (T33<Q, P, R, P>::IndCalcB),  12651597608, 13338233184)
4824     TB (kqpkrn, false, false, true,  (T33<Q, P, R, N>::IndCalcW), (T33<Q, P, R, N>::IndCalcB),  16048887360, 17032882752)
4825     TB (kqpkrb, false, true,  true,  (T33<Q, P, R, B>::IndCalcW), (T33<Q, P, R, B>::IndCalcB),  16048887360, 17652988800)
4826     TB (kqpkrr, false, true,  true,  (T33<Q, P, R, R>::IndCalcW), (T33<Q, P, R, R>::IndCalcB),   8024443680,  8608504032)
4827     TB (kqpkqp, true,  true,  true,  (T33<Q, P, Q, P>::IndCalcW), (T33<Q, P, Q, P>::IndCalcBF), 12651597608, 12651597608)
4828     TB (kqnkpp, false, true,  true,  (T33<Q, N, P, P>::IndCalcW), (T33<Q, N, P, P>::IndCalcB),   6436756032,  6395615340)
4829     TB (kqnknp, false, false, true,  (T33<Q, N, N, P>::IndCalcW), (T33<Q, N, N, P>::IndCalcB),  16160366208, 16455976740)
4830     TB (kqnkbp, false, false, true,  (T33<Q, N, B, P>::IndCalcW), (T33<Q, N, B, P>::IndCalcB),  16160366208, 17052633120)
4831     TB (kqnkrp, false, false, true,  (T33<Q, N, R, P>::IndCalcW), (T33<Q, N, R, P>::IndCalcB),  16160366208, 16919868906)
4832     TB (kqnkqp, false, true,  true,  (T33<Q, N, Q, P>::IndCalcW), (T33<Q, N, Q, P>::IndCalcB),  16160366208, 16048887306)
4833     TB (kqbkpp, false, false, true,  (T33<Q, B, P, P>::IndCalcW), (T33<Q, B, P, P>::IndCalcB),   6669728640,  6395615340)
4834     TB (kqbknp, false, false, true,  (T33<Q, B, N, P>::IndCalcW), (T33<Q, B, N, P>::IndCalcB),  16745276160, 16455976740)
4835     TB (kqbkbp, false, false, true,  (T33<Q, B, B, P>::IndCalcW), (T33<Q, B, B, P>::IndCalcB),  16745276160, 17052633120)
4836     TB (kqbkrp, false, false, true,  (T33<Q, B, R, P>::IndCalcW), (T33<Q, B, R, P>::IndCalcB),  16745276160, 16919868906)
4837     TB (kqbkqp, false, true,  true,  (T33<Q, B, Q, P>::IndCalcW), (T33<Q, B, Q, P>::IndCalcB),  16745276160, 16048887306)
4838     TB (kqrkpp, false, false, true,  (T33<Q, R, P, P>::IndCalcW), (T33<Q, R, P, P>::IndCalcB),   6616853640,  6395615340)
4839     TB (kqrknp, false, false, true,  (T33<Q, R, N, P>::IndCalcW), (T33<Q, R, N, P>::IndCalcB),  16612871664, 16455976740)
4840     TB (kqrkbp, false, false, true,  (T33<Q, R, B, P>::IndCalcW), (T33<Q, R, B, P>::IndCalcB),  16612871664, 17052633120)
4841     TB (kqrkrp, false, false, true,  (T33<Q, R, R, P>::IndCalcW), (T33<Q, R, R, P>::IndCalcB),  16612871664, 16919868906)
4842     TB (kqrkqp, false, true,  true,  (T33<Q, R, Q, P>::IndCalcW), (T33<Q, R, Q, P>::IndCalcB),  16612871664, 16048887306)
4843     TB (kqqkpp, false, false, false, (T33<Q, Q, P, P>::IndCalcW), (T33<Q, Q, P, P>::IndCalcB),   3082498008,  3197807670)
4844     TB (kqqknp, false, false, true,  (T33<Q, Q, N, P>::IndCalcW), (T33<Q, Q, N, P>::IndCalcB),   7739363232,  8227988370)
4845     TB (kqqkbp, false, false, true,  (T33<Q, Q, B, P>::IndCalcW), (T33<Q, Q, B, P>::IndCalcB),   7739363232,  8526316560)
4846     TB (kqqkrp, false, false, true,  (T33<Q, Q, R, P>::IndCalcW), (T33<Q, Q, R, P>::IndCalcB),   7739363232,  8459934426)
4847     TB (kqqkqp, false, false, true,  (T33<Q, Q, Q, P>::IndCalcW), (T33<Q, Q, Q, P>::IndCalcB),   7739363232,  8024443626)
4848 #endif  // T_INDEX64
4849 #endif  // T33_INCLUDE
4850
4851 #if defined (T42_INCLUDE)
4852     TB (knnnkn, false, false, false, (T42<N, N, N, N>::IndCalcW), (T42<N, N, N, N>::IndCalcB),  795687393,  945889180)
4853     TB (kbnnkn, false, false, false, (T42<B, N, N, N>::IndCalcW), (T42<B, N, N, N>::IndCalcB), 2560971346, 2837667540)
4854     TB (kbbnkn, false, false, false, (T42<B, B, N, N>::IndCalcW), (T42<B, B, N, N>::IndCalcB), 2654033462, 2837667540)
4855     TB (kbbbkn, false, false, false, (T42<B, B, B, N>::IndCalcW), (T42<B, B, B, N>::IndCalcB),  885603570,  945889180)
4856     TB (krnnkn, false, false, false, (T42<R, N, N, N>::IndCalcW), (T42<R, N, N, N>::IndCalcB), 2540315682, 2837667540)
4857     TB (krbbkn, false, false, false, (T42<R, B, B, N>::IndCalcW), (T42<R, B, B, N>::IndCalcB), 2728283251, 2837667540)
4858     TB (krrnkn, false, false, false, (T42<R, R, N, N>::IndCalcW), (T42<R, R, N, N>::IndCalcB), 2611650399, 2837667540)
4859     TB (krrbkn, false, false, false, (T42<R, R, B, N>::IndCalcW), (T42<R, R, B, N>::IndCalcB), 2706549480, 2837667540)
4860     TB (krrrkn, false, false, false, (T42<R, R, R, N>::IndCalcW), (T42<R, R, R, N>::IndCalcB),  864592254,  945889180)
4861     TB (kqnnkn, false, false, false, (T42<Q, N, N, N>::IndCalcW), (T42<Q, N, N, N>::IndCalcB), 2411545114, 2837667540)
4862     TB (kqbbkn, false, false, false, (T42<Q, B, B, N>::IndCalcW), (T42<Q, B, B, N>::IndCalcB), 2588901061, 2837667540)
4863     TB (kqrrkn, false, false, false, (T42<Q, R, R, N>::IndCalcW), (T42<Q, R, R, N>::IndCalcB), 2547484064, 2837667540)
4864     TB (kqqnkn, false, false, false, (T42<Q, Q, N, N>::IndCalcW), (T42<Q, Q, N, N>::IndCalcB), 2350606433, 2837667540)
4865     TB (kqqbkn, false, false, false, (T42<Q, Q, B, N>::IndCalcW), (T42<Q, Q, B, N>::IndCalcB), 2434987407, 2837667540)
4866     TB (kqqrkn, false, false, false, (T42<Q, Q, R, N>::IndCalcW), (T42<Q, Q, R, N>::IndCalcB), 2415271436, 2837667540)
4867     TB (kqqqkn, false, false, false, (T42<Q, Q, Q, N>::IndCalcW), (T42<Q, Q, Q, N>::IndCalcB),  736854363,  945889180)
4868     TB (knnnkb, false, false, false, (T42<N, N, N, B>::IndCalcW), (T42<N, N, N, B>::IndCalcB),  795687393,  980475570)
4869     TB (kbnnkb, false, false, false, (T42<B, N, N, B>::IndCalcW), (T42<B, N, N, B>::IndCalcB), 2560971346, 2941426710)
4870     TB (kbbnkb, false, false, false, (T42<B, B, N, B>::IndCalcW), (T42<B, B, N, B>::IndCalcB), 2654033462, 2941426710)
4871     TB (kbbbkb, false, false, false, (T42<B, B, B, B>::IndCalcW), (T42<B, B, B, B>::IndCalcB),  885603570,  980475570)
4872     TB (krnnkb, false, false, false, (T42<R, N, N, B>::IndCalcW), (T42<R, N, N, B>::IndCalcB), 2540315682, 2941426710)
4873     TB (krbbkb, false, false, false, (T42<R, B, B, B>::IndCalcW), (T42<R, B, B, B>::IndCalcB), 2728283251, 2941426710)
4874     TB (krrnkb, false, false, false, (T42<R, R, N, B>::IndCalcW), (T42<R, R, N, B>::IndCalcB), 2611650399, 2941426710)
4875     TB (krrbkb, false, false, false, (T42<R, R, B, B>::IndCalcW), (T42<R, R, B, B>::IndCalcB), 2706549480, 2941426710)
4876     TB (krrrkb, false, false, false, (T42<R, R, R, B>::IndCalcW), (T42<R, R, R, B>::IndCalcB),  864592254,  980475570)
4877     TB (kqnnkb, false, false, false, (T42<Q, N, N, B>::IndCalcW), (T42<Q, N, N, B>::IndCalcB), 2411545114, 2941426710)
4878     TB (kqbbkb, false, false, false, (T42<Q, B, B, B>::IndCalcW), (T42<Q, B, B, B>::IndCalcB), 2588901061, 2941426710)
4879     TB (kqrrkb, false, false, false, (T42<Q, R, R, B>::IndCalcW), (T42<Q, R, R, B>::IndCalcB), 2547484064, 2941426710)
4880     TB (kqqnkb, false, false, false, (T42<Q, Q, N, B>::IndCalcW), (T42<Q, Q, N, B>::IndCalcB), 2350606433, 2941426710)
4881     TB (kqqbkb, false, false, false, (T42<Q, Q, B, B>::IndCalcW), (T42<Q, Q, B, B>::IndCalcB), 2434987407, 2941426710)
4882     TB (kqqrkb, false, false, false, (T42<Q, Q, R, B>::IndCalcW), (T42<Q, Q, R, B>::IndCalcB), 2415271436, 2941426710)
4883     TB (kqqqkb, false, false, false, (T42<Q, Q, Q, B>::IndCalcW), (T42<Q, Q, Q, B>::IndCalcB),  736854363,  980475570)
4884     TB (knnnkr, false, false, false, (T42<N, N, N, R>::IndCalcW), (T42<N, N, N, R>::IndCalcB),  795687393,  973025640)
4885     TB (kbnnkr, false, false, false, (T42<B, N, N, R>::IndCalcW), (T42<B, N, N, R>::IndCalcB), 2560971346, 2919076920)
4886     TB (kbbnkr, false, false, false, (T42<B, B, N, R>::IndCalcW), (T42<B, B, N, R>::IndCalcB), 2654033462, 2919076920)
4887     TB (kbbbkr, false, false, false, (T42<B, B, B, R>::IndCalcW), (T42<B, B, B, R>::IndCalcB),  885603570,  973025640)
4888     TB (krnnkr, false, false, false, (T42<R, N, N, R>::IndCalcW), (T42<R, N, N, R>::IndCalcB), 2540315682, 2919076920)
4889     TB (krbbkr, false, false, false, (T42<R, B, B, R>::IndCalcW), (T42<R, B, B, R>::IndCalcB), 2728283251, 2919076920)
4890     TB (krrnkr, false, false, false, (T42<R, R, N, R>::IndCalcW), (T42<R, R, N, R>::IndCalcB), 2611650399, 2919076920)
4891     TB (krrbkr, false, false, false, (T42<R, R, B, R>::IndCalcW), (T42<R, R, B, R>::IndCalcB), 2706549480, 2919076920)
4892     TB (krrrkr, false, false, false, (T42<R, R, R, R>::IndCalcW), (T42<R, R, R, R>::IndCalcB),  864592254,  973025640)
4893     TB (kqnnkr, false, false, false, (T42<Q, N, N, R>::IndCalcW), (T42<Q, N, N, R>::IndCalcB), 2411545114, 2919076920)
4894     TB (kqbbkr, false, false, false, (T42<Q, B, B, R>::IndCalcW), (T42<Q, B, B, R>::IndCalcB), 2588901061, 2919076920)
4895     TB (kqrrkr, false, false, false, (T42<Q, R, R, R>::IndCalcW), (T42<Q, R, R, R>::IndCalcB), 2547484064, 2919076920)
4896     TB (kqqnkr, false, false, false, (T42<Q, Q, N, R>::IndCalcW), (T42<Q, Q, N, R>::IndCalcB), 2350606433, 2919076920)
4897     TB (kqqbkr, false, false, false, (T42<Q, Q, B, R>::IndCalcW), (T42<Q, Q, B, R>::IndCalcB), 2434987407, 2919076920)
4898     TB (kqqrkr, false, false, false, (T42<Q, Q, R, R>::IndCalcW), (T42<Q, Q, R, R>::IndCalcB), 2415271436, 2919076920)
4899     TB (kqqqkr, false, false, false, (T42<Q, Q, Q, R>::IndCalcW), (T42<Q, Q, Q, R>::IndCalcB),  736854363,  973025640)
4900     TB (knnnkq, false, false, false, (T42<N, N, N, Q>::IndCalcW), (T42<N, N, N, Q>::IndCalcB),  795687393,  922603650)
4901     TB (kbnnkq, false, false, false, (T42<B, N, N, Q>::IndCalcW), (T42<B, N, N, Q>::IndCalcB), 2560971346, 2767810950)
4902     TB (kbbnkq, false, false, false, (T42<B, B, N, Q>::IndCalcW), (T42<B, B, N, Q>::IndCalcB), 2654033462, 2767810950)
4903     TB (kbbbkq, false, false, false, (T42<B, B, B, Q>::IndCalcW), (T42<B, B, B, Q>::IndCalcB),  885603570,  922603650)
4904     TB (krnnkq, false, false, false, (T42<R, N, N, Q>::IndCalcW), (T42<R, N, N, Q>::IndCalcB), 2540315682, 2767810950)
4905     TB (krbbkq, false, false, false, (T42<R, B, B, Q>::IndCalcW), (T42<R, B, B, Q>::IndCalcB), 2728283251, 2767810950)
4906     TB (krrnkq, false, false, false, (T42<R, R, N, Q>::IndCalcW), (T42<R, R, N, Q>::IndCalcB), 2611650399, 2767810950)
4907     TB (krrbkq, false, false, false, (T42<R, R, B, Q>::IndCalcW), (T42<R, R, B, Q>::IndCalcB), 2706549480, 2767810950)
4908     TB (krrrkq, false, false, false, (T42<R, R, R, Q>::IndCalcW), (T42<R, R, R, Q>::IndCalcB),  864592254,  922603650)
4909     TB (kqnnkq, false, false, false, (T42<Q, N, N, Q>::IndCalcW), (T42<Q, N, N, Q>::IndCalcB), 2411545114, 2767810950)
4910     TB (kqbbkq, false, false, false, (T42<Q, B, B, Q>::IndCalcW), (T42<Q, B, B, Q>::IndCalcB), 2588901061, 2767810950)
4911     TB (kqrrkq, false, false, false, (T42<Q, R, R, Q>::IndCalcW), (T42<Q, R, R, Q>::IndCalcB), 2547484064, 2767810950)
4912     TB (kqqnkq, false, false, false, (T42<Q, Q, N, Q>::IndCalcW), (T42<Q, Q, N, Q>::IndCalcB), 2350606433, 2767810950)
4913     TB (kqqbkq, false, false, false, (T42<Q, Q, B, Q>::IndCalcW), (T42<Q, Q, B, Q>::IndCalcB), 2434987407, 2767810950)
4914     TB (kqqrkq, false, false, false, (T42<Q, Q, R, Q>::IndCalcW), (T42<Q, Q, R, Q>::IndCalcB), 2415271436, 2767810950)
4915     TB (kqqqkq, false, false, false, (T42<Q, Q, Q, Q>::IndCalcW), (T42<Q, Q, Q, Q>::IndCalcB),  736854363,  922603650)
4916 #if defined (T_INDEX64)
4917     TB (krbnkn, false, false, false, (T42<R, B, N, N>::IndCalcW), (T42<R, B, N, N>::IndCalcB), 5356454122, 5675335080)
4918     TB (kqbnkn, false, false, false, (T42<Q, B, N, N>::IndCalcW), (T42<Q, B, N, N>::IndCalcB), 5083836303, 5675335080)
4919     TB (kqrnkn, false, false, false, (T42<Q, R, N, N>::IndCalcW), (T42<Q, R, N, N>::IndCalcB), 5042765577, 5675335080)
4920     TB (kqrbkn, false, false, false, (T42<Q, R, B, N>::IndCalcW), (T42<Q, R, B, N>::IndCalcB), 5224919581, 5675335080)
4921     TB (krbnkb, false, false, false, (T42<R, B, N, B>::IndCalcW), (T42<R, B, N, B>::IndCalcB), 5356454122, 5882853420)
4922     TB (kqbnkb, false, false, false, (T42<Q, B, N, B>::IndCalcW), (T42<Q, B, N, B>::IndCalcB), 5083836303, 5882853420)
4923     TB (kqrnkb, false, false, false, (T42<Q, R, N, B>::IndCalcW), (T42<Q, R, N, B>::IndCalcB), 5042765577, 5882853420)
4924     TB (kqrbkb, false, false, false, (T42<Q, R, B, B>::IndCalcW), (T42<Q, R, B, B>::IndCalcB), 5224919581, 5882853420)
4925     TB (krbnkr, false, false, false, (T42<R, B, N, R>::IndCalcW), (T42<R, B, N, R>::IndCalcB), 5356454122, 5838153840)
4926     TB (kqbnkr, false, false, false, (T42<Q, B, N, R>::IndCalcW), (T42<Q, B, N, R>::IndCalcB), 5083836303, 5838153840)
4927     TB (kqrnkr, false, false, false, (T42<Q, R, N, R>::IndCalcW), (T42<Q, R, N, R>::IndCalcB), 5042765577, 5838153840)
4928     TB (kqrbkr, false, false, false, (T42<Q, R, B, R>::IndCalcW), (T42<Q, R, B, R>::IndCalcB), 5224919581, 5838153840)
4929     TB (krbnkq, false, false, false, (T42<R, B, N, Q>::IndCalcW), (T42<R, B, N, Q>::IndCalcB), 5356454122, 5535621900)
4930     TB (kqbnkq, false, false, true,  (T42<Q, B, N, Q>::IndCalcW), (T42<Q, B, N, Q>::IndCalcB), 5083836303, 5535621900)
4931     TB (kqrnkq, false, false, false, (T42<Q, R, N, Q>::IndCalcW), (T42<Q, R, N, Q>::IndCalcB), 5042765577, 5535621900)
4932     TB (kqrbkq, false, false, false, (T42<Q, R, B, Q>::IndCalcW), (T42<Q, R, B, Q>::IndCalcB), 5224919581, 5535621900)
4933
4934     TB (kpppkp, false, true,  false, (T42<P, P, P, P>::IndCalcW), (T42<P, P, P, P>::IndCalcB),  1196695343,  1348100424)
4935     TB (knppkp, false, true,  true,  (T42<N, P, P, P>::IndCalcW), (T42<N, P, P, P>::IndCalcB),  4796630713,  5271860528)
4936     TB (knnpkp, false, false, true,  (T42<N, N, P, P>::IndCalcW), (T42<N, N, P, P>::IndCalcB),  6156616111,  6835422612)
4937     TB (knnnkp, false, false, false, (T42<N, N, N, P>::IndCalcW), (T42<N, N, N, P>::IndCalcB),  2531022144,  2939087360)
4938     TB (kbppkp, false, true,  true,  (T42<B, P, P, P>::IndCalcW), (T42<B, P, P, P>::IndCalcB),  4969303175,  5271860528)
4939     TB (kbnpkp, false, true,  true,  (T42<B, N, P, P>::IndCalcW), (T42<B, N, P, P>::IndCalcB), 12979462304, 13670845224)
4940     TB (kbnnkp, false, false, true,  (T42<B, N, N, P>::IndCalcW), (T42<B, N, N, P>::IndCalcB),  8146120416,  8817262080)
4941     TB (kbbpkp, false, true,  true,  (T42<B, B, P, P>::IndCalcW), (T42<B, B, P, P>::IndCalcB),  6609838740,  6835422612)
4942     TB (kbbnkp, false, false, true,  (T42<B, B, N, P>::IndCalcW), (T42<B, B, N, P>::IndCalcB),  8441899104,  8817262080)
4943     TB (kbbbkp, false, false, false, (T42<B, B, B, P>::IndCalcW), (T42<B, B, B, P>::IndCalcB),  2816801280,  2939087360)
4944     TB (krppkp, false, true,  true,  (T42<R, P, P, P>::IndCalcW), (T42<R, P, P, P>::IndCalcB),  4929998839,  5271860528)
4945     TB (krnpkp, false, true,  true,  (T42<R, N, P, P>::IndCalcW), (T42<R, N, P, P>::IndCalcB), 12875424829, 13670845224)
4946     TB (krnnkp, false, false, true,  (T42<R, N, N, P>::IndCalcW), (T42<R, N, N, P>::IndCalcB),  8079921360,  8817262080)
4947     TB (krbpkp, false, true,  true,  (T42<R, B, P, P>::IndCalcW), (T42<R, B, P, P>::IndCalcB), 13340861520, 13670845224)
4948     TB (krbnkp, false, false, true,  (T42<R, B, N, P>::IndCalcW), (T42<R, B, N, P>::IndCalcB), 17036639904, 17634524160)
4949     TB (krbbkp, false, false, true,  (T42<R, B, B, P>::IndCalcW), (T42<R, B, B, P>::IndCalcB),  8677177872,  8817262080)
4950     TB (krrpkp, false, true,  true,  (T42<R, R, P, P>::IndCalcW), (T42<R, R, P, P>::IndCalcB),  6504899238,  6835422612)
4951     TB (krrnkp, false, false, true,  (T42<R, R, N, P>::IndCalcW), (T42<R, R, N, P>::IndCalcB),  8306047872,  8817262080)
4952     TB (krrbkp, false, false, true,  (T42<R, R, B, P>::IndCalcW), (T42<R, R, B, P>::IndCalcB),  8607504960,  8817262080)
4953     TB (krrrkp, false, false, false, (T42<R, R, R, P>::IndCalcW), (T42<R, R, R, P>::IndCalcB),  2749283520,  2939087360)
4954     TB (kqppkp, false, true,  true,  (T42<Q, P, P, P>::IndCalcW), (T42<Q, P, P, P>::IndCalcB),  4677701571,  5271860528)
4955     TB (kqnpkp, false, true,  true,  (T42<Q, N, P, P>::IndCalcW), (T42<Q, N, P, P>::IndCalcB), 12219736849, 13670845224)
4956     TB (kqnnkp, false, false, true,  (T42<Q, N, N, P>::IndCalcW), (T42<Q, N, N, P>::IndCalcB),  7670559696,  8817262080)
4957     TB (kqbpkp, false, true,  true,  (T42<Q, B, P, P>::IndCalcW), (T42<Q, B, P, P>::IndCalcB), 12658882024, 13670845224)
4958     TB (kqbnkp, false, false, true,  (T42<Q, B, N, P>::IndCalcW), (T42<Q, B, N, P>::IndCalcB), 16170070752, 17634524160)
4959     TB (kqbbkp, false, false, true,  (T42<Q, B, B, P>::IndCalcW), (T42<Q, B, B, P>::IndCalcB),  8234170512,  8817262080)
4960     TB (kqrpkp, false, false, true,  (T42<Q, R, P, P>::IndCalcW), (T42<Q, R, P, P>::IndCalcB), 12557225406, 13670845224)
4961     TB (kqrnkp, false, false, true,  (T42<Q, R, N, P>::IndCalcW), (T42<Q, R, N, P>::IndCalcB), 16038464256, 17634524160)
4962     TB (kqrbkp, false, false, true,  (T42<Q, R, B, P>::IndCalcW), (T42<Q, R, B, P>::IndCalcB), 16617170832, 17634524160)
4963     TB (kqrrkp, false, false, true,  (T42<Q, R, R, P>::IndCalcW), (T42<Q, R, R, P>::IndCalcB),  8101097520,  8817262080)
4964     TB (kqqpkp, false, false, true,  (T42<Q, Q, P, P>::IndCalcW), (T42<Q, Q, P, P>::IndCalcB),  5851888362,  6835422612)
4965     TB (kqqnkp, false, false, true,  (T42<Q, Q, N, P>::IndCalcW), (T42<Q, Q, N, P>::IndCalcB),  7476276864,  8817262080)
4966     TB (kqqbkp, false, false, true,  (T42<Q, Q, B, P>::IndCalcW), (T42<Q, Q, B, P>::IndCalcB),  7744392000,  8817262080)
4967     TB (kqqrkp, false, false, true,  (T42<Q, Q, R, P>::IndCalcW), (T42<Q, Q, R, P>::IndCalcB),  7680886080,  8817262080)
4968     TB (kqqqkp, false, false, false, (T42<Q, Q, Q, P>::IndCalcW), (T42<Q, Q, Q, P>::IndCalcB),  2343300048,  2939087360)
4969     TB (kpppkn, false, false, false, (T42<P, P, P, N>::IndCalcW), (T42<P, P, P, N>::IndCalcB),  1537640536,  1777129408)
4970     TB (knppkn, false, false, true,  (T42<N, P, P, N>::IndCalcW), (T42<N, P, P, N>::IndCalcB),  6071020409,  6838084896)
4971     TB (knnpkn, false, false, true,  (T42<N, N, P, N>::IndCalcW), (T42<N, N, P, N>::IndCalcB),  7677994559,  8729470080)
4972     TB (kbppkn, false, false, true,  (T42<B, P, P, N>::IndCalcW), (T42<B, P, P, N>::IndCalcB),  6289527204,  6838084896)
4973     TB (kbnpkn, false, false, true,  (T42<B, N, P, N>::IndCalcW), (T42<B, N, P, N>::IndCalcB), 16186823401, 17458940160)
4974     TB (kbbpkn, false, false, true,  (T42<B, B, P, N>::IndCalcW), (T42<B, B, P, N>::IndCalcB),  8243187360,  8729470080)
4975     TB (krppkn, false, false, true,  (T42<R, P, P, N>::IndCalcW), (T42<R, P, P, N>::IndCalcB),  6239761412,  6838084896)
4976     TB (krnpkn, false, false, true,  (T42<R, N, P, N>::IndCalcW), (T42<R, N, P, N>::IndCalcB), 16057066825, 17458940160)
4977     TB (krbpkn, false, false, true,  (T42<R, B, P, N>::IndCalcW), (T42<R, B, P, N>::IndCalcB), 16637490240, 17458940160)
4978     TB (krrpkn, false, false, true,  (T42<R, R, P, N>::IndCalcW), (T42<R, R, P, N>::IndCalcB),  8112305064,  8729470080)
4979     TB (kqppkn, false, false, true,  (T42<Q, P, P, N>::IndCalcW), (T42<Q, P, P, N>::IndCalcB),  5920486098,  6838084896)
4980     TB (kqnpkn, false, false, true,  (T42<Q, N, P, N>::IndCalcW), (T42<Q, N, P, N>::IndCalcB), 15239383701, 17458940160)
4981     TB (kqbpkn, false, false, true,  (T42<Q, B, P, N>::IndCalcW), (T42<Q, B, P, N>::IndCalcB), 15787021288, 17458940160)
4982     TB (kqrpkn, false, false, true,  (T42<Q, R, P, N>::IndCalcW), (T42<Q, R, P, N>::IndCalcB), 15660230819, 17458940160)
4983     TB (kqqpkn, false, false, true,  (T42<Q, Q, P, N>::IndCalcW), (T42<Q, Q, P, N>::IndCalcB),  7297961576,  8729470080)
4984     TB (kpppkb, false, false, false, (T42<P, P, P, B>::IndCalcW), (T42<P, P, P, B>::IndCalcB),  1537640536,  1842024000)
4985     TB (knppkb, false, false, true,  (T42<N, P, P, B>::IndCalcW), (T42<N, P, P, B>::IndCalcB),  6071020409,  7087788000)
4986     TB (knnpkb, false, false, true,  (T42<N, N, P, B>::IndCalcW), (T42<N, N, P, B>::IndCalcB),  7677994559,  9048240000)
4987     TB (kbppkb, false, false, true,  (T42<B, P, P, B>::IndCalcW), (T42<B, P, P, B>::IndCalcB),  6289527204,  7087788000)
4988     TB (kbnpkb, false, false, true,  (T42<B, N, P, B>::IndCalcW), (T42<B, N, P, B>::IndCalcB), 16186823401, 18096480000)
4989     TB (kbbpkb, false, false, true,  (T42<B, B, P, B>::IndCalcW), (T42<B, B, P, B>::IndCalcB),  8243187360,  9048240000)
4990     TB (krppkb, false, false, true,  (T42<R, P, P, B>::IndCalcW), (T42<R, P, P, B>::IndCalcB),  6239761412,  7087788000)
4991     TB (krnpkb, false, false, true,  (T42<R, N, P, B>::IndCalcW), (T42<R, N, P, B>::IndCalcB), 16057066825, 18096480000)
4992     TB (krbpkb, false, false, true,  (T42<R, B, P, B>::IndCalcW), (T42<R, B, P, B>::IndCalcB), 16637490240, 18096480000)
4993     TB (krrpkb, false, false, true,  (T42<R, R, P, B>::IndCalcW), (T42<R, R, P, B>::IndCalcB),  8112305064,  9048240000)
4994     TB (kqppkb, false, false, true,  (T42<Q, P, P, B>::IndCalcW), (T42<Q, P, P, B>::IndCalcB),  5920486098,  7087788000)
4995     TB (kqnpkb, false, false, true,  (T42<Q, N, P, B>::IndCalcW), (T42<Q, N, P, B>::IndCalcB), 15239383701, 18096480000)
4996     TB (kqbpkb, false, false, true,  (T42<Q, B, P, B>::IndCalcW), (T42<Q, B, P, B>::IndCalcB), 15787021288, 18096480000)
4997     TB (kqrpkb, false, false, true,  (T42<Q, R, P, B>::IndCalcW), (T42<Q, R, P, B>::IndCalcB), 15660230819, 18096480000)
4998     TB (kqqpkb, false, false, true,  (T42<Q, Q, P, B>::IndCalcW), (T42<Q, Q, P, B>::IndCalcB),  7297961576,  9048240000)
4999     TB (kpppkr, false, false, false, (T42<P, P, P, R>::IndCalcW), (T42<P, P, P, R>::IndCalcB),  1537640536,  1827875872)
5000     TB (knppkr, false, false, true,  (T42<N, P, P, R>::IndCalcW), (T42<N, P, P, R>::IndCalcB),  6071020409,  7033481568)
5001     TB (knnpkr, false, false, true,  (T42<N, N, P, R>::IndCalcW), (T42<N, N, P, R>::IndCalcB),  7677994559,  8978912640)
5002     TB (kbppkr, false, true,  true,  (T42<B, P, P, R>::IndCalcW), (T42<B, P, P, R>::IndCalcB),  6289527204,  7033481568)
5003     TB (kbnpkr, false, true,  true,  (T42<B, N, P, R>::IndCalcW), (T42<B, N, P, R>::IndCalcB), 16186823401, 17957825280)
5004     TB (kbbpkr, false, true,  true,  (T42<B, B, P, R>::IndCalcW), (T42<B, B, P, R>::IndCalcB),  8243187360,  8978912640)
5005     TB (krppkr, false, false, true,  (T42<R, P, P, R>::IndCalcW), (T42<R, P, P, R>::IndCalcB),  6239761412,  7033481568)
5006     TB (krnpkr, false, false, true,  (T42<R, N, P, R>::IndCalcW), (T42<R, N, P, R>::IndCalcB), 16057066825, 17957825280)
5007     TB (krbpkr, false, false, true,  (T42<R, B, P, R>::IndCalcW), (T42<R, B, P, R>::IndCalcB), 16637490240, 17957825280)
5008     TB (krrpkr, false, false, true,  (T42<R, R, P, R>::IndCalcW), (T42<R, R, P, R>::IndCalcB),  8112305064,  8978912640)
5009     TB (kqppkr, false, false, true,  (T42<Q, P, P, R>::IndCalcW), (T42<Q, P, P, R>::IndCalcB),  5920486098,  7033481568)
5010     TB (kqnpkr, false, false, true,  (T42<Q, N, P, R>::IndCalcW), (T42<Q, N, P, R>::IndCalcB), 15239383701, 17957825280)
5011     TB (kqbpkr, false, false, true,  (T42<Q, B, P, R>::IndCalcW), (T42<Q, B, P, R>::IndCalcB), 15787021288, 17957825280)
5012     TB (kqrpkr, false, false, true,  (T42<Q, R, P, R>::IndCalcW), (T42<Q, R, P, R>::IndCalcB), 15660230819, 17957825280)
5013     TB (kqqpkr, false, false, true,  (T42<Q, Q, P, R>::IndCalcW), (T42<Q, Q, P, R>::IndCalcB),  7297961576,  8978912640)
5014     TB (kpppkq, false, true,  false, (T42<P, P, P, Q>::IndCalcW), (T42<P, P, P, Q>::IndCalcB),  1537640536,  1733232160)
5015     TB (knppkq, false, true,  true,  (T42<N, P, P, Q>::IndCalcW), (T42<N, P, P, Q>::IndCalcB),  6071020409,  6669309024)
5016     TB (knnpkq, false, false, true,  (T42<N, N, P, Q>::IndCalcW), (T42<N, N, P, Q>::IndCalcB),  7677994559,  8514011520)
5017     TB (kbppkq, false, true,  true,  (T42<B, P, P, Q>::IndCalcW), (T42<B, P, P, Q>::IndCalcB),  6289527204,  6669309024)
5018     TB (kbnpkq, false, true,  true,  (T42<B, N, P, Q>::IndCalcW), (T42<B, N, P, Q>::IndCalcB), 16186823401, 17028023040)
5019     TB (kbbpkq, false, true,  true,  (T42<B, B, P, Q>::IndCalcW), (T42<B, B, P, Q>::IndCalcB),  8243187360,  8514011520)
5020     TB (krppkq, false, true,  true,  (T42<R, P, P, Q>::IndCalcW), (T42<R, P, P, Q>::IndCalcB),  6239761412,  6669309024)
5021     TB (krnpkq, false, true,  true,  (T42<R, N, P, Q>::IndCalcW), (T42<R, N, P, Q>::IndCalcB), 16057066825, 17028023040)
5022     TB (krbpkq, false, true,  true,  (T42<R, B, P, Q>::IndCalcW), (T42<R, B, P, Q>::IndCalcB), 16637490240, 17028023040)
5023     TB (krrpkq, false, true,  true,  (T42<R, R, P, Q>::IndCalcW), (T42<R, R, P, Q>::IndCalcB),  8112305064,  8514011520)
5024     TB (kqppkq, false, true,  true,  (T42<Q, P, P, Q>::IndCalcW), (T42<Q, P, P, Q>::IndCalcB),  5920486098,  6669309024)
5025     TB (kqnpkq, false, true,  true,  (T42<Q, N, P, Q>::IndCalcW), (T42<Q, N, P, Q>::IndCalcB), 15239383701, 17028023040)
5026     TB (kqbpkq, false, true,  true,  (T42<Q, B, P, Q>::IndCalcW), (T42<Q, B, P, Q>::IndCalcB), 15787021288, 17028023040)
5027     TB (kqrpkq, false, true,  true,  (T42<Q, R, P, Q>::IndCalcW), (T42<Q, R, P, Q>::IndCalcB), 15660230819, 17028023040)
5028     TB (kqqpkq, false, false, true,  (T42<Q, Q, P, Q>::IndCalcW), (T42<Q, Q, P, Q>::IndCalcB),  7297961576,  8514011520)
5029
5030 #endif
5031 #endif
5032     };
5033
5034 #undef  P
5035 #undef  N
5036 #undef  B
5037 #undef  R
5038 #undef  Q
5039
5040 //  Helper structure
5041 //  Used to classify on-board position
5042
5043 union CUTbReference     // Hungarian: utbr
5044     {
5045     int             m_iDesc;            // Negative if have to inverse
5046     int             m_cPieces;
5047     CUTbReference   *m_utbReference;
5048     };
5049
5050 //  Root of the search tree
5051
5052 static CUTbReference rgutbReference [MAX_NON_KINGS + 2];
5053
5054 // Convert TB name (e.g. KQKR) into set of counters
5055
5056 static const char *PchSetHalfCounters
5057     (
5058     int         *piCounters,
5059     const char  *pch
5060     )
5061     {
5062     memset (piCounters, 0, 5 * sizeof (int));
5063     while ('\0' != *pch && 'k' != *pch)
5064         {
5065         piece pi;
5066
5067         pi = x_piecePawn;   // To make compiler happy
5068         switch (*pch)
5069             {
5070         case 'p':
5071             pi = x_piecePawn;
5072             break;
5073         case 'n':
5074             pi = x_pieceKnight;
5075             break;
5076         case 'b':
5077             pi = x_pieceBishop;
5078             break;
5079         case 'r':
5080             pi = x_pieceRook;
5081             break;
5082         case 'q':
5083             pi = x_pieceQueen;
5084             break;
5085         default:
5086             assert (0);
5087             }
5088         piCounters [pi-1] ++;
5089         pch ++;
5090         }
5091         return pch;
5092     };
5093
5094 static void VSetCounters
5095     (
5096     int         *piCounters,
5097     const char  *pch
5098     )
5099     {
5100     assert ('k' == *pch);
5101     pch = PchSetHalfCounters (piCounters, pch+1);
5102     assert ('k' == *pch);
5103     pch = PchSetHalfCounters (piCounters+5, pch+1);
5104     assert ('\0' == *pch);
5105     }
5106
5107 //  Following functions return TB index
5108 //  They differ by input arguments
5109
5110 extern "C" int IDescFindFromCounters
5111     (
5112     int *piCount
5113     )
5114     {
5115     CUTbReference *putbr = rgutbReference;
5116
5117     if (piCount[0] > putbr->m_cPieces)
5118         goto not_found;
5119     putbr = putbr[1 + piCount[0]].m_utbReference;
5120     if (piCount[1] > putbr->m_cPieces)
5121         goto not_found;
5122     putbr = putbr[1 + piCount[1]].m_utbReference;
5123     if (piCount[2] > putbr->m_cPieces)
5124         goto not_found;
5125     putbr = putbr[1 + piCount[2]].m_utbReference;
5126     if (piCount[3] > putbr->m_cPieces)
5127         goto not_found;
5128     putbr = putbr[1 + piCount[3]].m_utbReference;
5129     if (piCount[4] > putbr->m_cPieces)
5130         goto not_found;
5131     putbr = putbr[1 + piCount[4]].m_utbReference;
5132     if (piCount[5] > putbr->m_cPieces)
5133         goto not_found;
5134     putbr = putbr[1 + piCount[5]].m_utbReference;
5135     if (piCount[6] > putbr->m_cPieces)
5136         goto not_found;
5137     putbr = putbr[1 + piCount[6]].m_utbReference;
5138     if (piCount[7] > putbr->m_cPieces)
5139         goto not_found;
5140     putbr = putbr[1 + piCount[7]].m_utbReference;
5141     if (piCount[8] > putbr->m_cPieces)
5142         goto not_found;
5143     putbr = putbr[1 + piCount[8]].m_utbReference;
5144     if (piCount[9] <= putbr->m_cPieces)
5145         return putbr[1 + piCount[9]].m_iDesc;
5146 not_found:
5147     return 0;
5148     }
5149
5150 int IDescFind
5151     (
5152     square  *p_piW, // IN | Pointer to array of white pieces (king excluded)
5153     square  *p_piB, // IN | Pointer to array of black pieces (king excluded)
5154     int     cWhite, // IN | Counter of white pieces (king excluded)
5155     int     cBlack  // IN | Counter of black pieces (king excluded)
5156     )
5157     {
5158     int rgiCount[10];
5159
5160     // Set pieces counters
5161     rgiCount[0] =
5162     rgiCount[1] =
5163     rgiCount[2] =
5164     rgiCount[3] =
5165     rgiCount[4] =
5166     rgiCount[5] =
5167     rgiCount[6] =
5168     rgiCount[7] =
5169     rgiCount[8] =
5170     rgiCount[9] = 0;
5171     while (cWhite)
5172         {
5173         rgiCount[(*p_piW)-1] ++;
5174         p_piW ++;
5175         cWhite --;
5176         }
5177     while (cBlack)
5178         {
5179         rgiCount[5-1+(*p_piB)] ++;
5180         p_piB ++;
5181         cBlack --;
5182         }
5183     return IDescFindFromCounters (rgiCount);
5184     }
5185
5186 int IDescFindByName
5187     (
5188     char    *pchName
5189     )
5190     {
5191     int rgiCount[10];
5192
5193     VSetCounters (rgiCount, pchName);
5194     return IDescFindFromCounters (rgiCount);
5195     }
5196
5197 //-----------------------------------------------------------------------------
5198 //
5199 //  Function used during initialization
5200
5201 //  Set of functions to create search table
5202
5203 static CUTbReference *PutbrCreateSubtable
5204     (
5205     int cPieces,    //  IN | # of pieces ramaining on board
5206     int iDepth      //  IN | Recursion depth (# of piece classes left)
5207     )
5208     {
5209     CUTbReference *putbr;
5210
5211     putbr = (CUTbReference *) PvMalloc ((cPieces + 2) * sizeof (CUTbReference));
5212     putbr[0].m_cPieces = cPieces;
5213     if (0 == iDepth)
5214         {
5215         for (int i = 0; i <= cPieces; i ++)
5216             putbr[i+1].m_iDesc = 0;
5217         }
5218     else
5219         {
5220         for (int i = 0; i <= cPieces; i ++)
5221             putbr[i+1].m_utbReference = PutbrCreateSubtable (cPieces-i, iDepth-1);
5222         }
5223     return putbr;
5224     }
5225
5226 static bool fTbTableCreated = false;
5227
5228 static void VCreateEmptyTbTable (void)
5229     {
5230     if (fTbTableCreated)
5231         return;
5232     fTbTableCreated = true;
5233     rgutbReference[0].m_cPieces = MAX_NON_KINGS;
5234     for (int i = 0; i <= MAX_NON_KINGS; i ++)
5235         rgutbReference[i+1].m_utbReference = PutbrCreateSubtable (MAX_NON_KINGS - i, 8);
5236     }
5237
5238 // Insert TB (e.g. KQKR) into search table
5239
5240 static bool FRegisterHalf
5241     (
5242     int     iTb,
5243     int     *piCount
5244     )
5245     {
5246     CUTbReference   *putbr;
5247
5248     putbr = rgutbReference;
5249     for (int i = 0; i < 9; i ++)
5250         {
5251         if (piCount[i] > putbr->m_cPieces)
5252             return false;
5253         putbr = putbr[1 + piCount[i]].m_utbReference;
5254         }
5255     if (piCount[9] > putbr->m_cPieces)
5256         return false;
5257     putbr[1 + piCount[9]].m_iDesc = iTb;
5258     return true;
5259     }
5260
5261 // Insert TB (both, e.g. KQKR and KRKQ) into search table
5262
5263 static bool FRegisterTb
5264     (
5265     CTbDesc *ptbDesc
5266     )
5267     {
5268     int     rgiCount[10];
5269     bool    fInserted;
5270
5271     VSetCounters (rgiCount, ptbDesc->m_rgchName);
5272     fInserted = FRegisterHalf (ptbDesc->m_iTbId, rgiCount);
5273     if (fInserted)
5274         {
5275         if (ptbDesc->m_fSymmetric)
5276             return true;
5277         for (int i = 0; i < 5; i ++)
5278             {
5279             int iTemp;
5280
5281             iTemp = rgiCount[i];
5282             rgiCount[i] = rgiCount[i+5];
5283             rgiCount[i+5] = iTemp;
5284             }
5285         fInserted = FRegisterHalf (-ptbDesc->m_iTbId, rgiCount);
5286         assert (fInserted);
5287         }
5288     return fInserted;
5289     }
5290
5291 // File mapping - Win32 code only
5292
5293 #if defined (_WIN32) || defined(_WIN64)
5294
5295 static BYTE * PbMapFileForRead
5296     (
5297     char    *szName,
5298     HANDLE  *phFile,
5299     HANDLE  *phFileMapping
5300     )
5301     {
5302     HANDLE  hFile;
5303     HANDLE  hFileMapping;
5304     LPVOID  lpFileBase;
5305
5306     hFile = CreateFileA(szName, GENERIC_READ, FILE_SHARE_READ,
5307                         NULL, OPEN_EXISTING,
5308                         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
5309     if (INVALID_HANDLE_VALUE == hFile)
5310         {
5311         printf("*** Couldn't open file %s with CreateFile()\n", szName);
5312         exit (1);
5313         }
5314     hFileMapping = CreateFileMapping (hFile, NULL, PAGE_READONLY, 0, 0, NULL);
5315     if (0 == hFileMapping)
5316         {
5317         CloseHandle (hFile);
5318         printf ("*** Couldn't open file %s mapping with CreateFileMapping()\n", szName);
5319         exit (1);
5320         }
5321     lpFileBase = MapViewOfFile (hFileMapping, FILE_MAP_READ, 0, 0, 0);
5322     if (0 == lpFileBase)
5323         {
5324         CloseHandle (hFileMapping);
5325         CloseHandle (hFile);
5326         printf ("*** Couldn't map view of file %s with MapViewOfFile()\n", szName);
5327         exit (1);
5328         }
5329     if (NULL != phFile)
5330         *phFile = hFile;
5331     if (NULL != phFileMapping)
5332         *phFileMapping = hFileMapping;
5333     return (BYTE*) lpFileBase;
5334     }
5335
5336 static void VUnmapFile
5337     (
5338     BYTE    *pbFileBase,
5339     HANDLE  hFile,
5340     HANDLE  hFileMapping
5341     )
5342     {
5343     BOOL fFailed;
5344
5345     fFailed = (0 == UnmapViewOfFile (pbFileBase)) |
5346               (0 == CloseHandle (hFileMapping)) |
5347               (0 == CloseHandle (hFile));
5348     if (fFailed) 
5349         {
5350         printf ("*** Couldn't unmap file\n");
5351         exit (1);
5352         }
5353     }
5354
5355 #endif
5356
5357 //-----------------------------------------------------------------------------
5358 //
5359 //  TB caching
5360
5361 #if !defined (TB_CB_CACHE_CHUNK)
5362 #define TB_CB_CACHE_CHUNK           8192 /* Must be power of 2 */
5363 #define LOG2_TB_CB_CACHE_CHUNK      13
5364 #endif
5365
5366 #define TB_CHUNK(index)             ((index) >> LOG2_TB_CB_CACHE_CHUNK)
5367 #define TB_OFFSET(index)            ((index) % TB_CB_CACHE_CHUNK)
5368 #define TB_DIRECTORY_ENTRY(chunk)   ((chunk) % TB_DIRECTORY_SIZE)
5369
5370 #define WIDE_TB_CHUNK(index)        ((index) >> (LOG2_TB_CB_CACHE_CHUNK-1))
5371 #define WIDE_TB_OFFSET(index)       ((index) % (TB_CB_CACHE_CHUNK/2))*2
5372
5373 struct CTbCache         //Hungarian: tbc
5374     {
5375     int volatile                m_iTb;
5376     color volatile              m_color;
5377     unsigned volatile           m_indChunk;
5378     volatile CTbCache *volatile m_ptbcNext;     // Next element in double-linked general LRU list
5379     volatile CTbCache *volatile m_ptbcPrev;     // Previous element in double-linked general LRU list
5380     volatile CTbCache *volatile m_ptbcTbNext;   // Next element in double-linked cache bucket LRU list
5381     volatile CTbCache *volatile m_ptbcTbPrev;   // Previous element in double-linked cache bucket LRU list
5382     BYTE                        *m_pbData;
5383     };
5384
5385 static CTbCache *ptbcTbCache;   // Cache memory
5386 static ULONG    ctbcTbCache;    // Cache size (in entries)
5387
5388 static volatile CTbCache * volatile ptbcHead;       // Head of that list
5389 static volatile CTbCache * volatile ptbcTail;       // Last element in that list
5390 static volatile CTbCache * volatile ptbcFree;       // First free cache header
5391
5392 static INLINE void VTbCloseFile
5393     (
5394     int     iTb,
5395     color   side
5396     )
5397     {
5398     for (int iExtent = 0; iExtent < MAX_EXTENTS; iExtent ++) {
5399         if (NULL != rgtbdDesc[iTb].m_rgfpFiles[side][iExtent])
5400             {
5401             Lock (rgtbdDesc[iTb].m_rglockFiles[side]);
5402             if (NULL != rgtbdDesc[iTb].m_rgfpFiles[side][iExtent])
5403                 {
5404                 fclose (rgtbdDesc[iTb].m_rgfpFiles[side][iExtent]);
5405                 rgtbdDesc[iTb].m_rgfpFiles[side][iExtent] = NULL;
5406                 }
5407             Unlock (rgtbdDesc[iTb].m_rglockFiles[side]);
5408             }
5409         }
5410     }
5411
5412 extern "C" void VTbCloseFiles (void)
5413     {
5414     // Initialized?
5415     if (0 == ctbcTbCache)
5416         return;
5417
5418     // Walk through TB cache and close all opened files
5419     for (int iTb = 1; iTb < cTb; iTb ++)
5420         {
5421         VTbCloseFile (iTb, x_colorWhite);
5422         VTbCloseFile (iTb, x_colorBlack);
5423         }
5424     }
5425
5426 void VTbClearCache (void)
5427     {
5428     CTbCacheBucket  *prgtbcbBuckets;
5429     CTbCache *ptbc;
5430     BYTE *pb;
5431     ULONG i;
5432
5433     // Initialized?
5434     if (0 == ctbcTbCache)
5435         return;
5436     VTbCloseFiles();
5437     
5438     // Initialize all lists
5439     pb = (BYTE *) & ptbcTbCache [ctbcTbCache];
5440     for (i = 0, ptbc = ptbcTbCache; i < ctbcTbCache; i ++, ptbc ++)
5441         {
5442         ptbc->m_pbData = pb + i*(TB_CB_CACHE_CHUNK+32+4);
5443         ptbc->m_ptbcTbPrev =
5444         ptbc->m_ptbcTbNext =
5445         ptbc->m_ptbcPrev = NULL;
5446         ptbc->m_ptbcNext = (ptbc + 1);
5447         }
5448     ptbc[-1].m_ptbcNext = NULL;
5449
5450     // Clear references from TBs
5451     for (int iTb = 1; iTb < cTb; iTb ++)
5452         {
5453         for (color sd=x_colorWhite; sd <= x_colorBlack; sd ++)
5454             {
5455             prgtbcbBuckets = rgtbdDesc[iTb].m_prgtbcbBuckets[sd];
5456             if (NULL != prgtbcbBuckets)
5457                 {
5458 #if defined (SMP)
5459                 for (i = 0; i < TB_DIRECTORY_SIZE; i ++)
5460                     LockFree (prgtbcbBuckets[i].m_lock);
5461 #endif
5462                 memset (prgtbcbBuckets, 0, TB_DIRECTORY_SIZE * sizeof (CTbCacheBucket));
5463 #if defined (SMP)
5464                 for (i = 0; i < TB_DIRECTORY_SIZE; i ++)
5465                     LockInit (prgtbcbBuckets[i].m_lock);
5466 #endif
5467                 }
5468             }
5469         }
5470
5471     // Set globals
5472     ptbcHead = ptbcTail = NULL;
5473     ptbcFree = ptbcTbCache;
5474     }
5475
5476 extern "C" int FTbSetCacheSize
5477     (
5478     void    *pv,
5479     ULONG   cbSize
5480     )
5481     {
5482     VTbCloseFiles();
5483     ctbcTbCache = 0;
5484     ptbcHead = NULL;
5485     if (cbSize < sizeof (CTbCache))
5486         return false;
5487     ptbcTbCache = (CTbCache*) pv;
5488     ctbcTbCache = cbSize / (sizeof (CTbCache) + TB_CB_CACHE_CHUNK+32+4);
5489     VTbClearCache();
5490     return true;
5491     }
5492
5493 // Table registered
5494
5495 INLINE int FRegisteredExtent
5496     (
5497     int     iTb,
5498     color   side,
5499     int     iExtent
5500     )
5501     {
5502     if (rgtbdDesc[iTb].m_fSymmetric)
5503         side = x_colorWhite;
5504     return (NULL != rgtbdDesc[iTb].m_rgpchFileName[side][iExtent]);
5505     }
5506
5507 INLINE int FRegistered
5508     (
5509     int     iTb,
5510     color   side
5511     )
5512     {
5513     int iExtent, cExtents;
5514     INDEX cBytes;
5515
5516     if (rgtbdDesc[iTb].m_fSplit)
5517         {
5518         cBytes = rgtbdDesc[iTb].m_rgcbLength[side];
5519         if (rgtbdDesc[iTb].m_f16bit)
5520             cBytes *= 2;
5521         cExtents = (int) (cBytes >> 31) + 1;
5522         }
5523     else
5524         cExtents = 1;
5525     for (iExtent = 0; iExtent < cExtents; iExtent ++)
5526         {
5527         if (FRegisteredExtent (iTb, side, iExtent))
5528             return true;
5529         }
5530     return false;
5531     }
5532
5533 extern "C" int FRegisteredFun
5534     (
5535     int     iTb,
5536     color   side
5537     )
5538     {
5539     return FRegistered (iTb, side);
5540     }
5541
5542 // Return function that calculates the necessary index:
5543
5544 #define PfnIndCalc(iTb, side)   (rgtbdDesc[iTb].m_rgpfnCalcIndex[side])
5545 extern "C" PfnCalcIndex PfnIndCalcFun
5546     (
5547     int     iTb,
5548     color   side
5549     )
5550     {
5551     return PfnIndCalc (iTb, side);
5552     }
5553
5554 // Read whole file into memory
5555
5556 extern "C" int FReadTableToMemory
5557     (
5558     int     iTb,    // IN | Tablebase
5559     color   side,   // IN | Side to move
5560     BYTE    *pb     // IN | Either buffer or NULL
5561     )
5562     {
5563     char    *pszName;
5564     INDEX   cb;
5565     FILE    *fp;
5566
5567     if (rgtbdDesc[iTb].m_fSymmetric)
5568         side = x_colorWhite;
5569     if (!FRegistered (iTb, side))
5570         return false;
5571     if (rgtbdDesc[iTb].m_fSplit)
5572         return false;
5573     for (int iExtent = 0; iExtent < MAX_EXTENTS; iExtent ++)
5574         {
5575         if (NULL != rgtbdDesc[iTb].m_rgpdiDecodeInfo[side][iExtent])
5576             return false;
5577         }
5578     if (NULL != rgtbdDesc[iTb].m_rgpbRead[side])
5579         return true;
5580     pszName = rgtbdDesc[iTb].m_rgpchFileName[side][0];
5581     fp = fopen (pszName, "rb");
5582     if (NULL == fp)
5583         return false;
5584
5585     // Find database size
5586 #if defined (NEW)
5587     cb = rgtbdDesc[iTb].m_rgcbLength[side];
5588     if (0 == cb)
5589         {
5590 #endif
5591         if (0 != fseek (fp, 0L, SEEK_END))
5592             {
5593             printf ("*** Seek in %s failed\n", pszName);
5594             exit (1);
5595             }
5596         cb = ftell (fp);
5597         if (-1 == (int) cb)
5598             {
5599             printf ("*** Cannot find length of %s\n", pszName);
5600             exit (1);
5601             }
5602         if (0 != fseek (fp, 0L, SEEK_SET))
5603             {
5604             printf ("*** Seek in %s failed\n", pszName);
5605             exit (1);
5606             }
5607 #if defined (NEW)
5608         }
5609 #if defined (T33_INCLUDE) || defined (KPPKP_16BIT)
5610     else if (rgtbdDesc[iTb].m_f16bit)
5611         {
5612         if ((size_t) cb != cb)   // Overflow
5613             {
5614             printf ("*** %s too big to read into memory\n", pszName);
5615             exit (1);
5616             }
5617         }
5618 #endif
5619 #endif
5620     
5621     // If buffer not specified, allocate memory for it
5622     if (NULL == pb)
5623         pb = (BYTE*) PvMalloc (cb);
5624
5625     // Read file into memory
5626     if (cb != (INDEX) fread (pb, 1, cb, fp))
5627         {
5628         printf ("*** Read from %s failed\n", pszName);
5629         exit (1);
5630         }
5631     fclose (fp);
5632
5633     // All done
5634     rgtbdDesc[iTb].m_rgpbRead[side] = pb;
5635     return true;
5636     }
5637
5638 #if defined (_WIN32) || defined(_WIN64)
5639
5640 // Map whole file into memory
5641
5642 extern "C" int FMapTableToMemory
5643     (
5644     int     iTb,    // IN | Tablebase
5645     color   side    // IN | Side to move
5646     )
5647     {
5648     char *pszName;
5649
5650     if (rgtbdDesc[iTb].m_fSymmetric)
5651         side = x_colorWhite;
5652     if (!FRegistered (iTb, side))
5653         return false;
5654     if (rgtbdDesc[iTb].m_fSplit)
5655         return false;
5656     for (int iExtent = 0; iExtent < MAX_EXTENTS; iExtent ++)
5657         {
5658         if (NULL != rgtbdDesc[iTb].m_rgpdiDecodeInfo[side][iExtent])
5659             return false;
5660         }
5661     pszName = rgtbdDesc[iTb].m_rgpchFileName[side][0];
5662     if (NULL == rgtbdDesc[iTb].m_rgpbRead[side])
5663         {
5664         rgtbdDesc[iTb].m_rgpbRead[side] = PbMapFileForRead (pszName, NULL, NULL);
5665         if (fVerbose)
5666             printf ("%s mapped\n", pszName);
5667         }
5668     return true;
5669     }
5670
5671 // Map whole file into memory
5672
5673 int FMapTableToMemory
5674     (
5675     int     iTb,            // IN  | Tablebase
5676     color   side,           // IN  | Side to move
5677     HANDLE  *phFile,        // OUT | File handle will be written here
5678     HANDLE  *phFileMapping  // OUT | File mapping handle will be written here
5679     )
5680     {
5681     char *pszName;
5682
5683     if (rgtbdDesc[iTb].m_fSymmetric)
5684         side = x_colorWhite;
5685     if (!FRegistered (iTb, side))
5686         return false;
5687     if (rgtbdDesc[iTb].m_fSplit)
5688         return false;
5689     pszName = rgtbdDesc[iTb].m_rgpchFileName[side][0];
5690     if (NULL == rgtbdDesc[iTb].m_rgpbRead[side])
5691         {
5692         rgtbdDesc[iTb].m_rgpbRead[side] = PbMapFileForRead (pszName, phFile, phFileMapping);
5693         if (fVerbose)
5694             printf ("%s mapped\n", pszName);
5695         }
5696     return true;
5697     }
5698
5699 // Unmap whole file from memory
5700
5701 int FUnMapTableFromMemory
5702     (
5703     int     iTb,            // IN | Tablebase
5704     color   side,           // IN | Side to move
5705     HANDLE  hFile,          // IN | File handle will be written here
5706     HANDLE  hFileMapping    // IN | File mapping handle will be written here
5707     )
5708     {
5709     char *pszName;
5710
5711     if (rgtbdDesc[iTb].m_fSymmetric)
5712         side = x_colorWhite;
5713     if (!FRegistered (iTb, side))
5714         return false;
5715     if (rgtbdDesc[iTb].m_fSplit)
5716         return false;
5717     pszName = rgtbdDesc[iTb].m_rgpchFileName[side][0];
5718     if (NULL != rgtbdDesc[iTb].m_rgpbRead[side])
5719         {
5720         VUnmapFile (rgtbdDesc[iTb].m_rgpbRead[side], hFile, hFileMapping);
5721         rgtbdDesc[iTb].m_rgpbRead[side] = NULL;
5722         if (fVerbose)
5723             printf ("%s unmapped\n", pszName);
5724         }
5725     return true;
5726     }
5727
5728 #endif
5729
5730 // Probe TB - lower level (not exportable) function
5731
5732 static int TB_FASTCALL TbtProbeTable
5733     (
5734     int      iTb,
5735     color    side,
5736     unsigned indChunk,
5737     unsigned indInChunk
5738     )
5739     {
5740     CTbDesc *ptbd;
5741     int iDirectory, iExtent, iPhysicalChunk;
5742     volatile CTbCache * ptbc;
5743     volatile CTbCache * ptbcTbFirst;
5744     const char *pszFileName;
5745
5746     ptbd = & rgtbdDesc[iTb];
5747     iDirectory = TB_DIRECTORY_ENTRY (indChunk);
5748
5749     // Head of the cache bucket LRU list
5750     Lock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock);
5751     ptbcTbFirst = ptbd->m_prgtbcbBuckets[side][iDirectory].m_ptbcFirst;
5752
5753     // First, search entry in the cache
5754     for (ptbc = ptbcTbFirst; NULL != ptbc; ptbc = ptbc->m_ptbcTbNext)
5755         {
5756         if (indChunk == ptbc->m_indChunk)
5757             {
5758             // Found - move cache entry to the head of the general LRU list
5759             Lock (lockLRU);
5760             if (ptbc != ptbcHead)
5761                 {
5762                 // Remove it from its current position
5763                 ptbc->m_ptbcPrev->m_ptbcNext = ptbc->m_ptbcNext;
5764                 if (NULL == ptbc->m_ptbcNext)
5765                     ptbcTail = ptbc->m_ptbcPrev;
5766                 else
5767                     ptbc->m_ptbcNext->m_ptbcPrev = ptbc->m_ptbcPrev;
5768                 // Insert it at the head
5769                 ptbc->m_ptbcPrev = NULL;
5770                 ptbc->m_ptbcNext = ptbcHead;
5771                 ptbcHead->m_ptbcPrev = ptbc;
5772                 ptbcHead = ptbc;
5773                 }
5774             Unlock (lockLRU);
5775             // Move cache entry to the head of the cache bucket LRU list
5776             if (ptbc != ptbcTbFirst)
5777                 {
5778                 // Remove it from list
5779                 ptbc->m_ptbcTbPrev->m_ptbcTbNext = ptbc->m_ptbcTbNext;
5780                 if (NULL != ptbc->m_ptbcTbNext)
5781                     ptbc->m_ptbcTbNext->m_ptbcTbPrev = ptbc->m_ptbcTbPrev;
5782                 // Insert it at head
5783                 ptbc->m_ptbcTbPrev = NULL;
5784                 ptbc->m_ptbcTbNext = ptbcTbFirst;
5785                 ptbcTbFirst->m_ptbcTbPrev = ptbc;
5786                 ptbd->m_prgtbcbBuckets[side][iDirectory].m_ptbcFirst = ptbc;
5787                 }
5788             int tb;
5789
5790             tb = (tb_t) (ptbc->m_pbData[(ULONG)indInChunk]);
5791             Unlock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock);
5792             return tb;
5793             }
5794         }
5795     // Not in the cache - have to read it from disk.
5796     // I decided to write simple code - so sometimes it's possible that
5797     // 2 threads will simultaneously read exactly the same chunk into 2
5798     // different cache entries. In that case, all subsequent cache probes
5799     // will hit the first cache entry, so the second one will 'drift' to
5800     // the end of general LRU list and will be reused.
5801
5802     // Unlock cache bucket, so other threads can continue execution
5803     Unlock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock);
5804     // First, find cache entry we can use
5805     Lock (lockLRU);
5806     // Get it either from a free list, or reuse last element of the LRU list
5807     if (NULL != ptbcFree)
5808         {
5809         ptbc = ptbcFree;
5810         ptbcFree = ptbc->m_ptbcNext;
5811         Unlock (lockLRU);
5812         }
5813     else
5814         {
5815         unsigned iTailDirectory;
5816         int      iTailTb;
5817         color    colorTail;
5818
5819         assert (NULL != ptbcTail);
5820 #if defined (SMP)
5821         // "Optimistic" model - assuming that there is low content
5822         // (not hundreds of threads)
5823         for (;;)
5824             {
5825             ptbc = ptbcTail;
5826             iTailTb = ptbc->m_iTb;
5827             iTailDirectory = TB_DIRECTORY_ENTRY (ptbc->m_indChunk);
5828             colorTail = ptbc->m_color;
5829             // To avoid deadlocks, have to first acquire cache buckets lock,
5830             // and only then general LRU lock. So, free general LRU lock and
5831             // acquire 2 locks in a proper order.
5832             Unlock (lockLRU);
5833             Lock (rgtbdDesc[iTailTb].m_prgtbcbBuckets[colorTail][iTailDirectory].m_lock);
5834             Lock (lockLRU);
5835             // Have structures been modified while we re-acquired locks? 
5836             // (to be more precise, it's Ok, if structures were modified,
5837             // but cache entry again become the last element of the list,
5838             // and TB, color, and cache bucket did not changed, so we locked
5839             // proper locks).
5840             if (ptbc == ptbcTail && ptbc->m_iTb == iTailTb &&
5841                 ptbc->m_color == colorTail &&
5842                 TB_DIRECTORY_ENTRY (ptbc->m_indChunk) == iTailDirectory)
5843                 break;
5844             // Sorry - try once again...
5845             Unlock (rgtbdDesc[iTailTb].m_prgtbcbBuckets[colorTail][iTailDirectory].m_lock);
5846             }
5847 #else
5848         ptbc = ptbcTail;
5849         iTailTb = ptbc->m_iTb;
5850         iTailDirectory = TB_DIRECTORY_ENTRY (ptbc->m_indChunk);
5851         colorTail = ptbc->m_color;
5852 #endif
5853
5854         // Remove cache entry from the general LRU list
5855         ptbcTail = ptbc->m_ptbcPrev;
5856         if (NULL == ptbcTail)
5857             ptbcHead = NULL;
5858         else
5859             ptbcTail->m_ptbcNext = NULL;
5860         Unlock (lockLRU);
5861         
5862         // Remove it from cache bucket list
5863         if (NULL != ptbc->m_ptbcTbNext)
5864             ptbc->m_ptbcTbNext->m_ptbcTbPrev = ptbc->m_ptbcTbPrev;
5865         if (NULL == ptbc->m_ptbcTbPrev)
5866             rgtbdDesc[iTailTb].m_prgtbcbBuckets[colorTail][iTailDirectory].m_ptbcFirst = ptbc->m_ptbcTbNext;
5867         else
5868             ptbc->m_ptbcTbPrev->m_ptbcTbNext = ptbc->m_ptbcTbNext;
5869         Unlock (rgtbdDesc[iTailTb].m_prgtbcbBuckets[colorTail][iTailDirectory].m_lock);
5870         }
5871
5872     // Ok, now we have "orphan" cache entry - it's excluded from all lists,
5873     // so other threads will never touch it.
5874     ptbc->m_iTb = iTb;
5875     ptbc->m_color = side;
5876     ptbc->m_indChunk = indChunk;
5877
5878     // Now read it from the disk
5879     FILE    *fp;
5880     size_t  cb;
5881
5882     // First, check: is necessary file opened?
5883     // As files are not thread-safe, lock file
5884     Lock (ptbd->m_rglockFiles[side]);
5885     if (ptbd->m_fSplit)
5886         {
5887         iExtent = indChunk >> (31 - LOG2_TB_CB_CACHE_CHUNK);
5888         iPhysicalChunk = indChunk - (iExtent << (31 - LOG2_TB_CB_CACHE_CHUNK));
5889         }
5890     else
5891         {
5892         iExtent = 0;
5893         iPhysicalChunk = indChunk;
5894         }
5895     fp = ptbd->m_rgfpFiles[side][iExtent];
5896     if (NULL == fp)
5897         {
5898         // Not - try to open it
5899         pszFileName = ptbd->m_rgpchFileName[side][iExtent];
5900         if (NULL != pszFileName)
5901             {
5902             fp = fopen (pszFileName, "rb");
5903             if (NULL == fp)
5904                 {
5905                 // Failed. Close all the opened files and retry
5906                 Unlock (ptbd->m_rglockFiles[side]);
5907                 VTbCloseFiles ();
5908                 Lock (ptbd->m_rglockFiles[side]);
5909                 // Theoretically, it's possible that other threads opened a lot of
5910                 // files in the interval between VTbCloseFiles() and Lock(). If
5911                 // so, we'll fail - I don't like to have one more global lock
5912                 // especially for file open, at least not in first version.
5913                 // Problem can happen only on systems with small limit of
5914                 // simultaneously open files and high number of threads - unlikely
5915                 // combination.
5916                 fp = ptbd->m_rgfpFiles[side][iExtent];
5917                 if (NULL == fp)
5918                     {
5919                     fp = fopen (pszFileName, "rb");
5920                     if (NULL == fp)
5921                         {
5922 #if defined (STOP_ON_ERROR)
5923                         printf ("*** Unable to open file %s\n", pszFileName);
5924                         fflush (stdout);
5925                         exit(1);
5926 #endif
5927                         goto ERROR_LABEL;
5928                         }
5929                     }
5930                 }
5931             ptbd->m_rgfpFiles[side][iExtent] = fp;
5932             }
5933         else
5934             goto ERROR_LABEL;
5935         }
5936
5937     // File opened. Now seek and read necessary chunk
5938     if (NULL == ptbd->m_rgpdiDecodeInfo[side][iExtent])
5939         {
5940         long lPos;
5941         int  iResult;
5942
5943         lPos = (long) (iPhysicalChunk*TB_CB_CACHE_CHUNK);
5944 #if defined (T33_INCLUDE) || defined (T42_INCLUDE)
5945         if (lPos < 0)
5946             {
5947             iResult = fseek (fp, 0L, SEEK_SET);
5948             if (iResult)
5949                 {
5950 #if defined (STOP_ON_ERROR)
5951                 printf ("*** Unable to seek file %s offset %08X\n",
5952                         pszFileName, 0);
5953                 fflush (stdout);
5954                 exit(1);
5955 #endif
5956                 goto ERROR_LABEL;
5957                 }
5958             do
5959                 {
5960                 iResult = fseek (fp, 0x40000000, SEEK_CUR);
5961                 if (iResult)
5962                     {
5963 #if defined (STOP_ON_ERROR)
5964                     printf ("*** Unable to seek file %s offset %08X\n",
5965                             pszFileName, 0x40000000);
5966                     fflush (stdout);
5967                     exit(1);
5968 #endif
5969                     goto ERROR_LABEL;
5970                     }
5971                 lPos -= 0x40000000;
5972                 } while (lPos < 0);
5973             iResult = fseek (fp, lPos, SEEK_CUR);
5974             }
5975         else
5976 #endif
5977             iResult = fseek (fp, lPos, SEEK_SET);
5978         // Read uncompressed file
5979         if (iResult)
5980             {
5981 #if defined (STOP_ON_ERROR)
5982             printf ("*** Unable to seek file %s offset %08X\n",
5983                     pszFileName, lPos);
5984             fflush (stdout);
5985             exit(1);
5986 #endif
5987             goto ERROR_LABEL;
5988             }
5989         cb = fread (ptbc->m_pbData, 1, TB_CB_CACHE_CHUNK, fp);
5990         if (cb != TB_CB_CACHE_CHUNK)
5991             {
5992             // Could not read TB_CB_CACHE_CHUNK - check for error
5993             if (ferror (fp) || ((size_t) -1 == cb))
5994                 {
5995 #if defined (STOP_ON_ERROR)
5996                 printf ("*** Read error, file %s\n", pszFileName);
5997                 fflush (stdout);
5998                 exit(1);
5999 #endif
6000                 goto ERROR_LABEL;
6001                 }
6002             }
6003         Unlock (ptbd->m_rglockFiles[side]);
6004         }
6005     else
6006         {
6007         // Read compressed file
6008         int fWasError;
6009         decode_block    *block;
6010         decode_info     *info = ptbd->m_rgpdiDecodeInfo[side][iExtent];
6011
6012 #if defined (SMP)
6013         // Find free decode block
6014         decode_block    **pBlock;
6015
6016         Lock (lockDecode);
6017         pBlock = rgpdbDecodeBlocks;
6018         while (NULL == *pBlock)
6019             pBlock ++;
6020         block = *pBlock;
6021         *pBlock = NULL;
6022         Unlock (lockDecode);
6023 #else
6024         block = rgpdbDecodeBlocks[0];
6025 #endif
6026
6027         // Initialize decode block and read chunk
6028         fWasError = 0 != comp_init_block (block, TB_CB_CACHE_CHUNK, ptbc->m_pbData) ||
6029                     0 != comp_read_block (block, info, fp, iPhysicalChunk);
6030         
6031         // Release lock on file, so other threads can proceed with that file
6032         Unlock (ptbd->m_rglockFiles[side]);
6033
6034         // Decompress chunk
6035         if (!fWasError)
6036             fWasError |= (0 != comp_decode_and_check_crc (block, info, block->orig.size, TB_CRC_CHECK));
6037
6038         // Release block
6039 #if defined (SMP)
6040         Lock (lockDecode);
6041         *pBlock = block;
6042         Unlock (lockDecode);
6043 #endif
6044
6045         // Read Ok?
6046         if (fWasError)
6047             {
6048 #if defined (STOP_ON_ERROR)
6049             printf ("*** Decompression error, file %s\n", pszFileName);
6050             fflush (stdout);
6051             exit(1);
6052 #endif
6053             goto ERROR_LABEL_2;
6054             }
6055         }
6056
6057     // Read - now acquire locks and insert cache entry in both lists
6058     Lock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock);
6059     Lock (lockLRU);
6060
6061     // Insert cache entry into general LRU list
6062     ptbc->m_ptbcPrev = NULL;
6063     ptbc->m_ptbcNext = ptbcHead;
6064     if (NULL == ptbcHead)
6065         ptbcTail = ptbc;
6066     else
6067         ptbcHead->m_ptbcPrev = ptbc;
6068     ptbcHead = ptbc;
6069
6070     // Insert cache entry into cache bucket LRU list
6071     ptbc->m_ptbcTbPrev = NULL;
6072     ptbc->m_ptbcTbNext = ptbd->m_prgtbcbBuckets[side][iDirectory].m_ptbcFirst;
6073     if (NULL != ptbc->m_ptbcTbNext)
6074         ptbc->m_ptbcTbNext->m_ptbcTbPrev = ptbc;
6075     ptbd->m_prgtbcbBuckets[side][iDirectory].m_ptbcFirst = ptbc;
6076
6077     // All done
6078     int tb;
6079
6080     tb = (tb_t) (ptbc->m_pbData[indInChunk]);
6081     // Release locks
6082     Unlock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock);
6083     Unlock (lockLRU);
6084     return tb;
6085
6086     // I/O error. Here I don't want to halt the program, because that can
6087     // happen in the middle of the important game. Just return failure.
6088 ERROR_LABEL:
6089     Unlock (ptbd->m_rglockFiles[side]);
6090 ERROR_LABEL_2:
6091     Lock (lockLRU);
6092     ptbd->m_rgpchFileName[side][iExtent] = NULL;
6093     ptbc->m_ptbcNext = ptbcFree;
6094     ptbcFree = ptbc;
6095     Unlock (lockLRU);
6096     return L_bev_broken;
6097     }
6098
6099 // Probe TB - upper level function
6100
6101 static int  TB_FASTCALL TbtProbeTable
6102     (
6103     int     iTb,
6104     color   side,
6105     INDEX   indOffset
6106     )
6107     {
6108     CTbDesc *ptbd;
6109
6110     assert (iTb > 0 && iTb < cTb);
6111     ptbd = & rgtbdDesc[iTb];
6112     if (ptbd->m_fSymmetric)
6113         side = x_colorWhite;
6114
6115     // It's better for offset be smaller than TB size
6116     assert (!FRegistered (iTb, side) || indOffset < ptbd->m_rgcbLength[side]);
6117
6118     // Entire file read/mapped to memory?
6119     if (NULL != ptbd->m_rgpbRead[side])
6120         return (tb_t) ptbd->m_rgpbRead[side][indOffset];
6121
6122     // Cache initialized? TB registered?
6123     if (0 == ctbcTbCache || NULL == ptbd->m_prgtbcbBuckets[side])
6124         return bev_broken;
6125
6126 #if defined (T33_INCLUDE) || defined (KPPKP_16BIT)
6127     if (ptbd->m_f16bit)
6128         return bev_broken;
6129 #endif
6130
6131     int tb;
6132
6133     tb = TbtProbeTable (iTb, side,(unsigned) TB_CHUNK (indOffset), (unsigned) TB_OFFSET (indOffset));
6134     return (L_bev_broken == tb) ? bev_broken : (tb_t) tb;
6135     }
6136
6137 // 16-bit version (recommended)
6138
6139 #define FOutOfBound(iTb, side, indOffset)\
6140         (tbid_kppkp == iTb && x_colorBlack == side &&\
6141          (indOffset == 0x0362BC7C || indOffset == 0x0362DE44 || indOffset == 0x03637648 ||\
6142           indOffset == 0x03639810 || indOffset == 0x038D4F29 || indOffset == 0x040A2CAB ||\
6143           indOffset == 0x043C778C))
6144
6145 extern "C" int TB_FASTCALL L_TbtProbeTable
6146     (
6147     int     iTb,
6148     color   side,
6149     INDEX   indOffset
6150     )
6151     {
6152     int tbtScore;
6153     CTbDesc *ptbd;
6154
6155     assert (iTb > 0 && iTb < cTb);
6156     ptbd = & rgtbdDesc[iTb];
6157     if (ptbd->m_fSymmetric)
6158         side = x_colorWhite;
6159
6160     // Entire file read/mapped to memory?
6161     if (NULL != ptbd->m_rgpbRead[side])
6162         {
6163 #if defined (KPPKP_16BIT)
6164         if (!ptbd->m_f16bit)
6165             {
6166             tbtScore = (tb_t) ptbd->m_rgpbRead[side][indOffset];
6167             return S_to_L (tbtScore);
6168             }
6169         else
6170             return (((int) (((signed char) ptbd->m_rgpbRead[side][indOffset*2+1]))) << 8) +
6171                     ptbd->m_rgpbRead[side][indOffset*2];
6172 #elif defined (T33_INCLUDE)
6173         if (!ptbd->m_f16bit)
6174             {
6175             if (FOutOfBound (iTb, side, indOffset))
6176                 return -32639;
6177             else
6178                 {
6179                 tbtScore = (tb_t) ptbd->m_rgpbRead[side][indOffset];
6180                 return S_to_L (tbtScore);
6181                 }
6182             }
6183         else
6184             return (((int) (((signed char) ptbd->m_rgpbRead[side][indOffset*2+1]))) << 8) +
6185                     ptbd->m_rgpbRead[side][indOffset*2];
6186 #else
6187         if (FOutOfBound (iTb, side, indOffset))
6188             return -32639;
6189         else
6190             {
6191             tbtScore = (tb_t) ptbd->m_rgpbRead[side][indOffset];
6192             return S_to_L (tbtScore);
6193             }
6194 #endif
6195         }
6196
6197     // Cache initialized? TB registered?
6198     if (0 == ctbcTbCache || NULL == ptbd->m_prgtbcbBuckets[side])
6199         return L_bev_broken;
6200
6201 #if defined (T33_INCLUDE) || defined (T42_INCLUDE)
6202     if (ptbd->m_f16bit)
6203         {
6204         // Inefficient, but very simple, code
6205         int iLo;
6206         int iHi;
6207         
6208         iLo = TbtProbeTable (iTb, side, (unsigned) WIDE_TB_CHUNK (indOffset), (unsigned) WIDE_TB_OFFSET (indOffset));
6209         iHi = TbtProbeTable (iTb, side, (unsigned) WIDE_TB_CHUNK (indOffset), (unsigned) WIDE_TB_OFFSET (indOffset)+1);
6210         tbtScore = (L_bev_broken == iLo || L_bev_broken == iHi) ? L_bev_broken : ((iHi << 8) + (iLo & 0xFF));
6211         }
6212     else
6213         {
6214 #if !defined (KPPKP_16BIT)
6215         if (FOutOfBound (iTb, side, indOffset))
6216             return -32639;
6217 #endif
6218         tbtScore = TbtProbeTable (iTb, side, (unsigned) TB_CHUNK (indOffset), (unsigned) TB_OFFSET (indOffset));
6219         tbtScore = L_bev_broken == tbtScore ? L_bev_broken : S_to_L (tbtScore);
6220         }
6221 #elif !defined (KPPKP_16BIT)
6222     if (FOutOfBound (iTb, side, indOffset))
6223         return -32639;
6224     tbtScore = TbtProbeTable (iTb, side, (unsigned) TB_CHUNK (indOffset), (unsigned) TB_OFFSET (indOffset));
6225     tbtScore = L_bev_broken == tbtScore ? L_bev_broken : S_to_L (tbtScore);
6226 #else
6227     if (tbid_kppkp != iTb)
6228         {
6229         // All tables but kppkp are 8-bit tables
6230         tbtScore = TbtProbeTable (iTb, side, (unsigned) TB_CHUNK (indOffset), (unsigned) TB_OFFSET (indOffset));
6231         tbtScore = L_bev_broken == tbtScore ? L_bev_broken : S_to_L (tbtScore);
6232         }
6233     else
6234         {
6235         // Special handling of kppkp - it's 16-bit table
6236         // Inefficient, but very simple, code
6237         int iLo;
6238         int iHi;
6239         
6240         iLo = TbtProbeTable (iTb, side, (unsigned) WIDE_TB_CHUNK (indOffset), (unsigned) WIDE_TB_OFFSET (indOffset));
6241         iHi = TbtProbeTable (iTb, side, (unsigned) WIDE_TB_CHUNK (indOffset), (unsigned) WIDE_TB_OFFSET (indOffset)+1);
6242         tbtScore = (L_bev_broken == iLo || L_bev_broken == iHi) ? L_bev_broken : ((iHi << 8) + (iLo & 0xFF));
6243         }
6244 #endif
6245     return tbtScore;
6246     }
6247
6248 //-----------------------------------------------------------------------------
6249 //
6250 //  Global initialization
6251
6252 // TODO: Check size of split tables, too
6253
6254 static void VCheckSize
6255     (
6256     int     iTb,
6257     color   side,
6258     int     iExtent,
6259     INDEX   cb,
6260     char    *rgchTbName
6261     )
6262     {
6263 #if defined (NEW)
6264     INDEX   cbOk1, cbOk2;
6265
6266     if (0 == rgtbdDesc[iTb].m_rgcbLength[side])
6267         return;
6268
6269     cbOk1 = rgtbdDesc[iTb].m_rgcbLength[side];
6270     cbOk2 = cbOk1;
6271 #if defined (T_INDEX64)
6272     if (rgtbdDesc[iTb].m_fSplit)
6273         {
6274         cbOk1 = (1u << (rgtbdDesc[iTb].m_f16bit ? 30 : 31));
6275         cbOk2 = cbOk2 % (1u << (rgtbdDesc[iTb].m_f16bit ? 30 : 31));
6276         }
6277 #endif
6278
6279     if (cb != cbOk1 && cb != cbOk2)
6280         {
6281         printf ("*** %s corrupted "
6282                 DEC_INDEX_FORMAT " " DEC_INDEX_FORMAT " " DEC_INDEX_FORMAT "\n",
6283                 rgchTbName, cbOk1, cbOk2, cb);
6284         exit (1);
6285         }
6286 #endif
6287     }
6288
6289
6290 #if defined (_WIN32) || defined (_WIN64)
6291 int     iDrivesMap;
6292 BOOL    rgfAccessed[26];
6293 BOOL    rgfNotReady[26];
6294 #endif
6295
6296 static int FCheckExtentExistance
6297     (
6298     char    *pszPath,
6299     int     iTb,
6300     color   side,
6301     int     iExtent
6302     )
6303     {
6304     FILE            *fp;
6305     char            *pchCopy;
6306     const char      *pchExt = PchExt (side);
6307     char            rgchTbName[1024];
6308     char            rgchExtent[4];
6309     CTbCacheBucket  *prgtbcbBuckets;
6310     INDEX           cb;
6311     decode_info     *comp_info = NULL;
6312     int             fWasError;
6313     decode_block    *block;
6314     BYTE            rgbBuffer[TB_CB_CACHE_CHUNK+32+4];
6315
6316     if (FRegisteredExtent (iTb, side, iExtent) || NULL != rgtbdDesc[iTb].m_rgpbRead[side])
6317         return true;
6318
6319 #if defined (_WIN32) || defined (_WIN64)
6320     // Do not repeatedely probe device that is not ready
6321     // (i.e. unmapped disk or CD-ROM that does not contain the disk).
6322     if (NULL != pszPath && 0 != pszPath[0] && ':' == pszPath[1])
6323         {
6324         int  iDrive;
6325         char szRoot[5];
6326         WIN32_FIND_DATAA fd;
6327         HANDLE hResult;
6328
6329         iDrive = tolower(pszPath[0]) - 'a';
6330         if (iDrive >= 0 && iDrive < 26)
6331             {
6332             if (rgfNotReady[iDrive])
6333                 return false;
6334             if (!rgfAccessed[iDrive])
6335                 {
6336                 if (iDrivesMap && 0 == (iDrivesMap & (1 << iDrive)))
6337                     return false;
6338                 szRoot[0] = pszPath[0];
6339                 szRoot[1] = pszPath[1];
6340                 szRoot[2] = '\\';
6341                 szRoot[3] = '*';
6342                 szRoot[4] = 0;
6343                 hResult = FindFirstFileA (szRoot, &fd);
6344                 if (INVALID_HANDLE_VALUE == hResult)
6345                     {
6346                     if (ERROR_NOT_READY == GetLastError())
6347                         {
6348                         rgfNotReady[iDrive] = true;
6349                         return false;
6350                         }
6351                     }
6352                 else
6353                     FindClose (hResult);
6354                 rgfAccessed[iDrive] = true;
6355                 }
6356             }
6357         }
6358 #endif
6359
6360     strcpy (rgchTbName, pszPath);
6361     if (0 != pszPath[0] && DELIMITER[0] != pszPath[strlen(pszPath)-1])
6362         strcat (rgchTbName, DELIMITER);
6363     strcat (rgchTbName, rgtbdDesc[iTb].m_rgchName);
6364     if (rgtbdDesc[iTb].m_fSplit)
6365         {
6366         rgchExtent[0] = '.';
6367         if (iExtent >= 10)
6368             rgchExtent[1] = (char) (iExtent + 'a' - 10);
6369         else
6370             rgchExtent[1] = (char) (iExtent + '0');
6371         rgchExtent[2] = '\0';
6372         strcat (rgchTbName, rgchExtent);
6373         }
6374     strcat (rgchTbName, pchExt);
6375     cOpenFilesAttempts ++;
6376     fp = fopen (rgchTbName, "rb");
6377     //printf (">>> Opening %s\n", rgchTbName);
6378     cOpenFilesSuceed += (NULL != fp);
6379 #if !defined (NEW) && !defined (_WIN32) && !defined(_WIN64)
6380     // For case-sensitive systems, have to try once more
6381     if (NULL == fp)
6382         {
6383         for (int i = strchr(rgchTbName,'.')-rgchTbName-1; i>=0 && isalpha(rgchTbName[i]); i--)
6384             rgchTbName[i] = toupper (rgchTbName[i]);
6385         cOpenFilesAttempts ++;
6386         fp = fopen (rgchTbName, "rb");
6387         //printf (">>> Opening %s\n", rgchTbName);
6388         cOpenFilesSuceed += (NULL != fp);
6389         }
6390 #endif
6391     if (NULL != fp)
6392         {
6393         // Found uncompressed table
6394         if (rgtbdDesc[iTb].m_f16bit ||
6395             ((int)(cb = rgtbdDesc[iTb].m_rgcbLength[side])) < 0 ||
6396             cb != (unsigned) cb)
6397             {
6398             // Do not check the length for too large files
6399             cb = rgtbdDesc[iTb].m_rgcbLength[side];
6400             }
6401         else
6402             {
6403             if (0 != fseek (fp, 0L, SEEK_END))
6404                 {
6405                 printf ("*** Seek in %s failed\n", rgchTbName);
6406                 exit (1);
6407                 }
6408             cb = (INDEX) ftell (fp);
6409             VCheckSize (iTb, side, iExtent, cb, rgchTbName);
6410             }
6411         }
6412     else
6413         {
6414         // Check for compressed table.
6415         // First, check for kxykz.nb?.emd
6416         strcat (rgchTbName, ".emd");
6417         cOpenFilesAttempts ++;
6418         fp = fopen (rgchTbName, "rb");
6419         //printf (">>> Opening %s\n", rgchTbName);
6420         cOpenFilesSuceed += (NULL != fp);
6421         if ((NULL == fp) && !rgtbdDesc[iTb].m_fSplit)
6422             {
6423             // Check for kxykz_nb?.emd
6424             rgchTbName [strlen(rgchTbName)-8] = '_';
6425             cOpenFilesAttempts ++;
6426             fp = fopen (rgchTbName, "rb");
6427             //printf (">>> Opening %s\n", rgchTbName);
6428             cOpenFilesSuceed += (NULL != fp);
6429             }
6430         if ((NULL == fp) && !rgtbdDesc[iTb].m_fSplit)
6431             {
6432             // Check for kxykz_nb?_emd
6433             rgchTbName [strlen(rgchTbName)-4] = '_';
6434             cOpenFilesAttempts ++;
6435             fp = fopen (rgchTbName, "rb");
6436             //printf (">>> Opening %s\n", rgchTbName);
6437             cOpenFilesSuceed += (NULL != fp);
6438             }
6439 #if defined (T41_INCLUDE)
6440         if ((NULL == fp) && (iTb <= tbid_kqqqk))
6441 #else
6442         if ((NULL == fp) && (iTb <= tbid_kqqkq))
6443 #endif
6444             {
6445             // Check for kxykznb?.emd (8+3 format)
6446             int cch;
6447             
6448             rgchTbName [strlen(rgchTbName)-4] = '.';
6449             cch = strlen (rgchTbName);
6450             memmove (rgchTbName+cch-8, rgchTbName+cch-7, 8);
6451             cOpenFilesAttempts ++;
6452             fp = fopen (rgchTbName, "rb");
6453             //printf (">>> Opening %s\n", rgchTbName);
6454             cOpenFilesSuceed += (NULL != fp);
6455             }
6456         if (NULL == fp)
6457             return false;
6458         cCompressed ++;
6459         int iResult = comp_open_file (&comp_info, fp, TB_CRC_CHECK);
6460         if (0 != iResult)
6461             {
6462             printf ("*** Unable to read %s - ", rgchTbName);
6463             switch (iResult & 0xFF)
6464                 {
6465             case COMP_ERR_READ:
6466                 printf ("read error\n");
6467                 break;
6468             case COMP_ERR_NOMEM:
6469                 printf ("out of memory\n");
6470                 break;
6471             case COMP_ERR_BROKEN:
6472                 printf ("file broken\n");
6473                 break;
6474             default:
6475                 printf ("error %d\n", iResult);
6476                 break;
6477                 }
6478             exit (1);
6479             }
6480         if (comp_info->block_size != TB_CB_CACHE_CHUNK)
6481             {
6482             printf ("*** %s: Unsupported block size %d\n", rgchTbName, comp_info->block_size);
6483             exit (1);
6484             }
6485         if (rgtbdDesc[iTb].m_f16bit)
6486             {
6487             cb = ((INDEX)comp_info->block_size/2)*(comp_info->n_blk-1) +
6488                   (INDEX)comp_info->last_block_size/2;
6489             VCheckSize (iTb, side, iExtent, cb, rgchTbName);
6490             }
6491         else
6492             {
6493             cb = ((INDEX)comp_info->block_size)*(comp_info->n_blk-1) +
6494                  (INDEX)comp_info->last_block_size;
6495             VCheckSize (iTb, side, iExtent, cb, rgchTbName);
6496             }
6497
6498 #if 0
6499         block = rgpdbDecodeBlocks[0];
6500         if (NULL == block)
6501             {
6502             int iResult = comp_alloc_block (&rgpdbDecodeBlocks[0], TB_CB_CACHE_CHUNK);
6503             if (0 != iResult)
6504                 {
6505                 printf ("*** Cannot allocate decode block: error code %d\n", iResult);
6506                 exit (1);
6507                 }
6508             block = rgpdbDecodeBlocks[0];
6509             }
6510         // Initialize decode block and read chunk
6511         fWasError = 0 != comp_init_block (block, TB_CB_CACHE_CHUNK, rgbBuffer) ||
6512                     0 != comp_read_block (block, comp_info, fp, TB_CHUNK (cb-1)) ||
6513                     0 != comp_decode_and_check_crc (block, comp_info, block->orig.size, TB_CRC_CHECK);
6514         if (fWasError)
6515             {
6516             printf ("*** Sanity check on %s failed\n", rgchTbName);
6517             exit (1);
6518             }
6519 #endif
6520         }
6521
6522     fclose (fp);
6523     if (FRegisterTb (& (rgtbdDesc[iTb])))
6524         {
6525         pchCopy = (char*) PvMalloc (strlen(rgchTbName)+1);
6526         strcpy (pchCopy, rgchTbName);
6527         free (rgtbdDesc[iTb].m_rgpchFileName[side][iExtent]);
6528         rgtbdDesc[iTb].m_rgpchFileName[side][iExtent] = pchCopy;
6529         if (NULL == rgtbdDesc[iTb].m_prgtbcbBuckets[side])
6530             {
6531             prgtbcbBuckets = (CTbCacheBucket*) PvMalloc (TB_DIRECTORY_SIZE*sizeof(CTbCacheBucket));
6532             memset (prgtbcbBuckets, 0, TB_DIRECTORY_SIZE*sizeof(CTbCacheBucket));
6533 #if defined (SMP)
6534             for (int i = 0; i < TB_DIRECTORY_SIZE; i ++)
6535                 LockInit (prgtbcbBuckets[i].m_lock);
6536 #endif
6537             rgtbdDesc[iTb].m_prgtbcbBuckets[side] = prgtbcbBuckets;
6538             if (fVerbose)
6539                 printf ("%s registered\n", pchCopy);
6540             }
6541         else
6542             {
6543             if (fVerbose)
6544                 printf ("%s found\n", pchCopy);
6545             }
6546         rgtbdDesc[iTb].m_rgpdiDecodeInfo[side][iExtent] = comp_info;
6547         return true;
6548         }
6549     else
6550         {
6551         printf ("*** Unable to register %s\n", rgchTbName);
6552         exit (1);
6553         }
6554     return false;
6555     }
6556
6557 int FCheckExistance
6558     (
6559     char    *pszPath,
6560     int     iTb,
6561     color   side
6562     )
6563     {
6564     int  fFound;
6565     int  cExtents;
6566     INDEX cBytes;
6567
6568     if (rgtbdDesc[iTb].m_fSplit)
6569         {
6570         cBytes = rgtbdDesc[iTb].m_rgcbLength[side];
6571         if (rgtbdDesc[iTb].m_f16bit)
6572             cBytes *= 2;
6573         cExtents = (int) (cBytes >> 31) + 1;
6574         }
6575     else
6576         cExtents = 1;
6577     fFound = false;
6578     for (int iExtent = 0; iExtent < cExtents; iExtent++)
6579         {
6580         if (!FCheckExtentExistance (pszPath, iTb, side, iExtent))
6581             break;
6582         fFound = true;
6583         }
6584     return fFound;
6585     }
6586
6587 extern "C" int IInitializeTb
6588     (
6589     char *pszPath
6590     )
6591     {
6592     char    szTemp[1024];
6593     color   sd;
6594     int     iTb, iMaxTb, iExtent, i;
6595     CTbCacheBucket  *prgtbcbBuckets;
6596
6597 #if defined (_WIN32) || defined (_WIN64)
6598     // For Windows, get bit map of ready devices
6599     iDrivesMap = GetLogicalDrives();
6600     memset (rgfAccessed, 0, sizeof(rgfAccessed));
6601     memset (rgfNotReady, 0, sizeof(rgfNotReady));
6602 #endif
6603
6604     cOpenFilesAttempts = cOpenFilesSuceed = 0;
6605     cbAllocated = cbEGTBCompBytes = 0;
6606     // If there are open files, close those
6607     VTbCloseFiles ();
6608 #if defined (SMP)
6609     // Init all locks
6610     LockInit (lockLRU);
6611     LockInit (lockDecode);
6612     for (iTb = 1; iTb < cTb; iTb ++)
6613         {
6614         LockInit (rgtbdDesc[iTb].m_rglockFiles[x_colorWhite]);
6615         LockInit (rgtbdDesc[iTb].m_rglockFiles[x_colorBlack]);
6616         }
6617 #endif
6618 #if defined (NEW)
6619     // Create enumeration tables
6620     VInitEnumerations ();
6621 #endif
6622     // Create empty TB search table
6623     VCreateEmptyTbTable ();
6624     // Free memory from TB table
6625     for (iTb = 1; iTb < cTb; iTb ++)
6626         {
6627         for (sd = x_colorWhite; sd <= x_colorBlack; sd = (color) (sd + 1))
6628             {
6629             if (NULL != rgtbdDesc[iTb].m_prgtbcbBuckets[sd] &&
6630                 NULL == rgtbdDesc[iTb].m_rgpbRead[sd])
6631                 {
6632                 prgtbcbBuckets = rgtbdDesc[iTb].m_prgtbcbBuckets[sd];
6633 #if defined (SMP)
6634                 for (i = 0; i < TB_DIRECTORY_SIZE; i ++)
6635                     LockFree (prgtbcbBuckets[i].m_lock);
6636 #endif
6637                 free (prgtbcbBuckets);
6638                 rgtbdDesc[iTb].m_prgtbcbBuckets[sd] = NULL;
6639                 }
6640             for (iExtent = 0; iExtent < MAX_EXTENTS; iExtent ++)
6641                 {
6642                 if (NULL != rgtbdDesc[iTb].m_rgpchFileName[sd][iExtent])
6643                     {
6644                     free (rgtbdDesc[iTb].m_rgpchFileName[sd][iExtent]);
6645                     rgtbdDesc[iTb].m_rgpchFileName[sd][iExtent] = NULL;
6646                     }
6647                 if (NULL != rgtbdDesc[iTb].m_rgpdiDecodeInfo[sd][iExtent])
6648                     {
6649                     free (rgtbdDesc[iTb].m_rgpdiDecodeInfo[sd][iExtent]);
6650                     rgtbdDesc[iTb].m_rgpdiDecodeInfo[sd][iExtent] = NULL;
6651                     }
6652                 }
6653             }
6654         }
6655     // Free compressed blocks
6656     for (i = 0; i < CPUS; i ++)
6657         {
6658         if (NULL != rgpdbDecodeBlocks[i])
6659             {
6660             free (rgpdbDecodeBlocks[i]);
6661             rgpdbDecodeBlocks[i] = NULL;
6662             }
6663         }
6664
6665     if(pszPath == NULL)
6666         return 0;
6667
6668     // Search for existing TBs
6669     iMaxTb = 0;
6670     for (;;)
6671         {
6672         for (i = 0; pszPath[i] != '\0' && pszPath[i] != ',' && pszPath[i] != ';'
6673 #if !defined (_WIN32) && !defined (__MWERKS__) && !defined(_WIN64)
6674              && pszPath[i] != ':'
6675 #endif
6676              ; i ++)
6677             {
6678             szTemp[i] = pszPath[i];
6679             }
6680         szTemp[i] = '\0';
6681         for (iTb = 1; iTb < cTb; iTb ++)
6682             {
6683             if (FCheckExistance (szTemp, iTb, x_colorWhite))
6684                 {
6685                 if (iTb > iMaxTb)
6686                     iMaxTb = iTb;
6687                 }
6688         if (! rgtbdDesc[iTb].m_fSymmetric && FCheckExistance (szTemp, iTb, x_colorBlack))
6689                 {
6690                 if (iTb > iMaxTb)
6691                     iMaxTb = iTb;
6692                 }
6693             }
6694         pszPath += i;
6695         if ('\0' == *pszPath)
6696             break;
6697         pszPath ++;
6698         }
6699     
6700     // If there were compressed files, have to allocate buffer(s)
6701     if (0 != cCompressed)
6702         {
6703         for (i = 0; i < CPUS; i ++)
6704             {
6705             if (NULL == rgpdbDecodeBlocks[i])
6706                 {
6707                 int iResult = comp_alloc_block (&rgpdbDecodeBlocks[i], TB_CB_CACHE_CHUNK);
6708                 if (0 != iResult)
6709                     {
6710                     printf ("*** Cannot allocate decode block: error code %d\n", iResult);
6711                     exit (1);
6712                     }
6713                 }
6714             }
6715         if (fVerbose)
6716             printf ("Allocated %dKb for decompression tables, indices, and buffers.\n",
6717                     (cbEGTBCompBytes+1023)/1024);
6718         }
6719
6720     if (fVerbose)
6721         printf ("Tried to open %d files. Opened %d files.\n",
6722                 cOpenFilesAttempts, cOpenFilesSuceed);
6723     // All done!
6724 #if defined T33_INCLUDE
6725     if (iMaxTb >= tbid_knnknn)
6726         return 6;
6727 #elif defined (T42_INCLUDE)
6728     if (iMaxTb >= tbid_knnnkn)
6729         return 6;
6730 #endif
6731     if (iMaxTb >= tbid_kppkp)
6732         return 5;
6733     if (iMaxTb >= tbid_kpkp)
6734         return 4;
6735     if (iMaxTb >= tbid_kpk)
6736         return 3;
6737     return 0;
6738     }