Update codebase to remove clang warnings (and a couple of legit errors
[typhoon.git] / src / chess.hbak
1 /**
2
3 Copyright (c) Scott Gasch
4
5 Module Name:
6
7     chess.h
8
9 Abstract:
10
11 Author:
12
13     Scott Gasch ([email protected]) 7 Apr 2004
14
15 Revision History:
16
17     $Id: chess.h 344 2007-11-30 06:49:50Z scott $
18
19 **/
20
21 #ifndef CHESS_
22 #define CHESS_
23
24 #include "compiler.h"
25
26 //
27 // Datatype wrappers
28 //
29 #define MIN_CHAR                   (0x80)
30 #define MAX_CHAR                   (0x7f)
31 typedef char                       CHAR;
32
33 #define MIN_BYTE                   (0x00)
34 #define MAX_BYTE                   (0xff)
35 typedef unsigned char              BYTE;
36
37 #define MIN_UCHAR                  (0x00)
38 #define MAX_UCHAR                  (0xff)
39 typedef unsigned char              UCHAR;
40 #define CAN_FIT_IN_UCHAR(x)        ((x) <= MAX_UCHAR)
41
42 #define MIN_SHORT                  (0x8000)
43 #define MAX_SHORT                  (0x7fff)
44 typedef signed short               SHORT;
45
46 #define MIN_USHORT                 (0x0000)
47 #define MAX_USHORT                 (0xffff)
48 typedef unsigned short             USHORT;
49 #define CAN_FIT_IN_USHORT(x)       ((x) <= MAX_USHORT)
50
51 #define MIN_WORD                   (0x0000)
52 #define MAX_WORD                   (0xffff)
53 typedef unsigned short             WORD;
54
55 #define MIN_INT                    (0x80000000)
56 #define MAX_INT                    (0x7fffffff)
57 typedef signed int                 INT;
58
59 #define MIN_DWORD                  (0x00000000)
60 #define MAX_DWORD                  (0xffffffff)
61 typedef unsigned int               DWORD;
62
63 #define MIN_UINT                   (0x00000000)
64 #define MAX_UINT                   (0xffffffff)
65 typedef unsigned int               UINT;
66
67 #define MIN_ULONG                  (0x00000000)
68 #define MAX_ULONG                  (0xffffffff)
69 typedef unsigned int               ULONG;
70
71 #define MIN_INT64                  (0x8000000000000000)
72 #define MAX_INT64                  (0x7fffffffffffffff)
73 typedef signed COMPILER_LONGLONG   INT64;
74
75 #define MIN_UINT64                 (0x0000000000000000)
76 #define MAX_UINT64                 (0xffffffffffffffff)
77 typedef unsigned COMPILER_LONGLONG UINT64;
78
79 #define MIN_BITBOARD               (0x0000000000000000)
80 #define MAX_BITBOARD               (0xffffffffffffffff)
81 typedef UINT64                     BITBOARD;
82
83 #define MIN_BITV                   MIN_UINT
84 #define MAX_BITV                   MAX_UINT
85 typedef unsigned int               BITV;
86
87 #define MIN_FLAG                   MIN_UINT
88 #define MAX_FLAG                   MAX_UINT
89 typedef unsigned int               FLAG;
90 #define IS_VALID_FLAG(x)           (((x) == TRUE) || ((x) == FALSE))
91
92 typedef unsigned int               COOR;
93 typedef unsigned int               PIECE;
94 typedef signed int                 SCORE;
95
96 #define BIT1                              (0x1)
97 #define BIT2                              (0x2)
98 #define BIT3                              (0x4)
99 #define BIT4                              (0x8)
100 #define BIT5                             (0x10)
101 #define BIT6                             (0x20)
102 #define BIT7                             (0x40)
103 #define BIT8                             (0x80)
104 #define BIT9                            (0x100)
105 #define BIT10                           (0x200)
106 #define BIT11                           (0x400)
107 #define BIT12                           (0x800)
108 #define BIT13                          (0x1000)
109 #define BIT14                          (0x2000)
110 #define BIT15                          (0x4000)
111 #define BIT16                          (0x8000)
112 #define BIT17                         (0x10000)
113 #define BIT18                         (0x20000)
114 #define BIT19                         (0x40000)
115 #define BIT20                         (0x80000)
116 #define BIT21                        (0x100000)
117 #define BIT22                        (0x200000)
118 #define BIT23                        (0x400000)
119 #define BIT24                        (0x800000)
120 #define BIT25                       (0x1000000)
121 #define BIT26                       (0x2000000)
122 #define BIT27                       (0x4000000)
123 #define BIT28                       (0x8000000)
124 #define BIT29                      (0x10000000)
125 #define BIT30                      (0x20000000)
126 #define BIT31                      (0x40000000)
127 #define BIT32                      (0x80000000)
128
129 typedef struct _DLIST_ENTRY
130 {
131     struct _DLIST_ENTRY *pFlink;
132     struct _DLIST_ENTRY *pBlink;
133 } DLIST_ENTRY;
134
135 //
136 // Constants
137 //
138 #define YES                        (1)
139 #define NO                         (0)
140 #ifndef TRUE
141 #define TRUE                       (YES)
142 #endif
143 #ifndef FALSE
144 #define FALSE                      (NO)
145 #endif
146
147 //
148 // Calculate the length of an array (i.e. number of elements)
149 //
150 #define ARRAY_LENGTH(x)            (sizeof(x) / sizeof((x)[0]))
151 #define COMMAND(x) \
152     void (x)(CHAR *szInput, ULONG argc, CHAR *argv[], POSITION *pos)
153 #define MB (1024 * 1024)
154
155 //
156 // Calculate the address of the base of the structure given its type, and an
157 // address of a field within the structure.
158 //
159 #ifndef OFFSET_OF
160 #define OFFSET_OF(field, type) \
161     (ULONG)(&((type *)0)->field)
162 #endif
163 #ifndef CONTAINING_STRUCT
164 #define CONTAINING_STRUCT(address, type, field) \
165     ((type *)((BYTE *)(address) - (BYTE *)(OFFSET_OF(field, type))))
166 #endif
167
168 #define WHITE                      (1)
169 #define BLACK                      (0)
170 #define BAD_COLOR                  (2)
171 #define IS_VALID_COLOR(x)          (((x) == WHITE) || ((x) == BLACK))
172 #define FOREACH_COLOR(x)           for((x) = BLACK; (x) < BAD_COLOR; (x)++)
173 #define RANDOM_COLOR               (rand() & 1)
174 #define FLIP(color)                ((color) ^ 1)
175 #define COLOR_NAME(color)          (((color) == WHITE) ? "white" : "black")
176
177 #define MAX_MOVES_PER_PLY          (218)
178 #define MAX_PLY_PER_SEARCH         (64)
179 #define MAX_MOVES_PER_GAME         (1024)
180 #define SMALL_STRING_LEN_CHAR      (256)
181 #define MEDIUM_STRING_LEN_CHAR     (8192)
182 #define BIG_STRING_LEN_CHAR        (16384)
183
184 #define QUARTER_PLY                16
185 #define HALF_PLY                   32
186 #define THREE_QUARTERS_PLY         48
187 #define ONE_PLY                    64
188 #define TWO_PLY                    128
189 #define THREE_PLY                  192
190 #define FOUR_PLY                   256
191 #define MAX_DEPTH_PER_SEARCH       (MAX_PLY_PER_SEARCH * ONE_PLY)
192
193 #define IS_VALID_DEPTH(x)          (((x) >= 0) && \
194                                    ((x) <= MAX_DEPTH_PER_SEARCH) && \
195                                    (((x) & 0xfffff00f) == 0))
196
197 #define INFINITY                   (MAX_SHORT)
198 #define INVALID_SCORE              (INFINITY + 1)
199 #define IS_VALID_SCORE(x)          (((x) >= -INFINITY) && \
200                                     ((x) <= +INFINITY))
201 #define NMATE                      (+INFINITY - 200)
202 #define MATED_SCORE(ply)           (-INFINITY + (ply))
203
204 #define IS_A_POWER_OF_2(x)         (((x) & (x - 1)) == 0)
205 //
206 // Program version number
207 //
208 #define VERSION                    "1.00"
209 #define REVISION                   "$Id: chess.h 344 2007-11-30 06:49:50Z scott $\n"
210
211 //
212 // Function decorators
213 //
214 #define IN
215 #define OUT
216 #define INOUT
217 #define UNUSED
218 #define NOTHING
219
220 // ----------------------------------------------------------------------
221 //
222 // PIECE:
223 //
224 // a piece (4 bits) = type (3 bits) + color (1 bit)
225 //
226 //  3   1 0
227 //  . . . .
228 // |     | |
229 //  type  C
230 //
231 #define KING                       (6)        // 110X
232 #define QUEEN                      (5)        // 101X
233 #define ROOK                       (4)        // 100X
234 #define BISHOP                     (3)        // 011X
235 #define KNIGHT                     (2)        // 010X
236 #define PAWN                       (1)        // 001X
237 #define EMPTY                      (0)        // 000X
238
239 // (WHATEVER << 1)
240 #define BLACK_PAWN                 (2)        // 0010
241 #define BLACK_KNIGHT               (4)        // 0100
242 #define BLACK_BISHOP               (6)        // 0110
243 #define BLACK_ROOK                 (8)        // 1000
244 #define BLACK_QUEEN                (10)       // 1010
245 #define BLACK_KING                 (12)       // 1100
246
247 // (WHATEVER << 1) | WHITE
248 #define WHITE_PAWN                 (3)        // 0011
249 #define WHITE_KNIGHT               (5)        // 0101
250 #define WHITE_BISHOP               (7)        // 0111
251 #define WHITE_ROOK                 (9)        // 1001
252 #define WHITE_QUEEN                (11)       // 1011
253 #define WHITE_KING                 (13)       // 1101
254
255 #define PIECE_TYPE(p)              ((p) >> 1)
256 #define PIECE_COLOR(p)             ((p) & WHITE)
257 #define RANDOM_PIECE               (rand() % 12) + 2;
258 #define IS_PAWN(p)                 (((p) & 0xE) == BLACK_PAWN)
259 #define IS_KNIGHT(p)               (((p) & 0xE) == BLACK_KNIGHT)
260 #define IS_BISHOP(p)               (((p) & 0xE) == BLACK_BISHOP)
261 #define IS_ROOK(p)                 (((p) & 0xE) == BLACK_ROOK)
262 #define IS_QUEEN(p)                (((p) & 0xE) == BLACK_QUEEN)
263 #define IS_KING(p)                 (((p) & 0xE) == BLACK_KING)
264 #define IS_KNIGHT_OR_KING(p)       (((p) & 0x6) == 0x4)
265 #define IS_VALID_PIECE(p)          ((PIECE_TYPE((p)) >= PAWN) && \
266                                     (PIECE_TYPE((p)) <= KING))
267 #define IS_WHITE_PIECE(p)          ((p) & WHITE)
268 #define IS_BLACK_PIECE(p)          (!IS_WHITE(p))
269 #define OPPOSITE_COLORS(p, q)      (((p) ^ (q)) & WHITE)
270 #define SAME_COLOR(p,q)            (!OPPOSITE_COLORS(p, q))
271 #define GET_COLOR(p)               ((p) & WHITE)
272
273 // ----------------------------------------------------------------------
274 //
275 // a coordinate (8 bits) = rank + file (0x88)
276 //
277 //  7     4 3     0
278 //  . . . . . . . .
279 // |       |       |
280 //   rank     file
281 //     |        |
282 //     |        +--- 0-7 = file A thru file H
283 //     |
284 //     +------------ 0-7 = rank 1 thru rank 8
285 //
286 // given a coordinate, C, if C & 0x88 then it is illegal (off board)
287 //
288 //
289 //     0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
290 //    +---------------------------------------+
291 //  8 | 00 |:01:| 02 |:03:| 04 |:05:| 06 |:07:| 0x00
292 //  7 |:10:| 11 |:12:| 13 |:14:| 15 |:16:| 17 | 0x10
293 //  6 | 20 |:21:| 22 |:23:| 24 |:25:| 26 |:27:| 0x20
294 //  5 |:30:| 31 |:32:| 33 |:34:| 35 |:36:| 37 | 0x30
295 //  4 | 40 |:41:| 42 |:43:| 44 |:45:| 46 |:47:| 0x40
296 //  3 |:50:| 51 |:52:| 53 |:54:| 55 |:56:| 57 | 0x50
297 //  2 | 60 |:61:| 62 |:63:| 64 |:65:| 66 |:67:| 0x60
298 //  1 |:70:| 71 |:72:| 73 |:74:| 75 |:76:| 77 | 0x70
299 //    +---------------------------------------+
300 //       A    B    C    D    E    F    G    H
301 //
302 #define A                          (0)
303 #define B                          (1)
304 #define C                          (2)
305 #define D                          (3)
306 #define E                          (4)
307 #define F                          (5)
308 #define G                          (6)
309 #define H                          (7)
310
311 #define A8                         (0x00)
312 #define B8                         (0x01)
313 #define C8                         (0x02)
314 #define D8                         (0x03)
315 #define E8                         (0x04)
316 #define F8                         (0x05)
317 #define G8                         (0x06)
318 #define H8                         (0x07)
319
320 #define A7                         (0x10)
321 #define B7                         (0x11)
322 #define C7                         (0x12)
323 #define D7                         (0x13)
324 #define E7                         (0x14)
325 #define F7                         (0x15)
326 #define G7                         (0x16)
327 #define H7                         (0x17)
328
329 #define A6                         (0x20)
330 #define B6                         (0x21)
331 #define C6                         (0x22)
332 #define D6                         (0x23)
333 #define E6                         (0x24)
334 #define F6                         (0x25)
335 #define G6                         (0x26)
336 #define H6                         (0x27)
337
338 #define A5                         (0x30)
339 #define B5                         (0x31)
340 #define C5                         (0x32)
341 #define D5                         (0x33)
342 #define E5                         (0x34)
343 #define F5                         (0x35)
344 #define G5                         (0x36)
345 #define H5                         (0x37)
346
347 #define A4                         (0x40)
348 #define B4                         (0x41)
349 #define C4                         (0x42)
350 #define D4                         (0x43)
351 #define E4                         (0x44)
352 #define F4                         (0x45)
353 #define G4                         (0x46)
354 #define H4                         (0x47)
355
356 #define A3                         (0x50)
357 #define B3                         (0x51)
358 #define C3                         (0x52)
359 #define D3                         (0x53)
360 #define E3                         (0x54)
361 #define F3                         (0x55)
362 #define G3                         (0x56)
363 #define H3                         (0x57)
364
365 #define A2                         (0x60)
366 #define B2                         (0x61)
367 #define C2                         (0x62)
368 #define D2                         (0x63)
369 #define E2                         (0x64)
370 #define F2                         (0x65)
371 #define G2                         (0x66)
372 #define H2                         (0x67)
373
374 #define A1                         (0x70)
375 #define B1                         (0x71)
376 #define C1                         (0x72)
377 #define D1                         (0x73)
378 #define E1                         (0x74)
379 #define F1                         (0x75)
380 #define G1                         (0x76)
381 #define H1                         (0x77)
382
383 // TODO: if use this anywhere that matters, consider double loop
384 // and unrolling the inside loop to prevent the multiple
385 // continue for invalid squares
386 #define FOREACH_SQUARE(x)          for((x) = (A8); (x) <= (H1); (x)++)
387
388 #define IS_ON_BOARD(c)             (!((c) & 0x88))
389 #define RANDOM_COOR                (rand() & 0x77)
390 #define FILE_RANK_TO_COOR(f, r)    (((8 - (r)) << 4) | (f))
391 #define RANK(c)                    (8 - ((c) >> 4))
392 #define RANK1(c)                   (((c) & 0xF0) == 0x70)
393 #define RANK2(c)                   (((c) & 0xF0) == 0x60)
394 #define RANK3(c)                   (((c) & 0xF0) == 0x50)
395 #define RANK4(c)                   (((c) & 0xF0) == 0x40)
396 #define RANK5(c)                   (((c) & 0xF0) == 0x30)
397 #define RANK6(c)                   (((c) & 0xF0) == 0x20)
398 #define RANK7(c)                   (((c) & 0xF0) == 0x10)
399 #define RANK8(c)                   (((c) & 0xF0) == 0x00)
400 #define FILE(c)                    ((c) & 0x0F)
401 #define FILEA(c)                   (((c) & 0x0F) == 0x00)
402 #define FILEB(c)                   (((c) & 0x0F) == 0x01)
403 #define FILEC(c)                   (((c) & 0x0F) == 0x02)
404 #define FILED(c)                   (((c) & 0x0F) == 0x03)
405 #define FILEE(c)                   (((c) & 0x0F) == 0x04)
406 #define FILEF(c)                   (((c) & 0x0F) == 0x05)
407 #define FILEG(c)                   (((c) & 0x0F) == 0x06)
408 #define FILEH(c)                   (((c) & 0x0F) == 0x07)
409 #define IS_WHITE_SQUARE_FR(f, r)   (((f) + (r) - 1) & 1)
410 #define IS_WHITE_SQUARE_COOR(c)    (IS_WHITE_SQUARE_FR(FILE(c), RANK(c)))
411 #define VALID_EP_SQUARE(c)         (((c) == ILLEGAL_COOR) || ((c) == 0) || \
412                                     (RANK3(c)) || \
413                                     (RANK6(c)))
414
415 // ----------------------------------------------------------------------
416 //
417 // a move (4 bytes) = from/to, moved, captured, promoted and special
418 //
419 //  31           24 23           16 15   12 11    8 7     4 3     0
420 //  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
421 // |     from      |       to      | moved | capt  | prom  | flags |
422 //         |               |          |       |       |
423 //         |               |          |       |       |
424 //         |               |          |       |       |
425 //         |               |          +-------+-------+-- type and
426 //         |               |                              color of
427 //         |               |                              piece moved
428 //         |               |                              captured and
429 //         |               |                              promote targ
430 //         +---------------+-- board location where
431 //                             move begins and ends
432 //
433 //
434 // Special flag asserted on special move types:
435 //
436 // if (special)
437 // {
438 //    if (moved == PAWN)
439 //    {
440 //       if (promotion)
441 //       {
442 //          move is a promote (w/ or w/o capture)
443 //       }
444 //       else if (capture)
445 //       {
446 //          move is an en passant catpure
447 //       }
448 //       else
449 //       {
450 //          move is a double jump
451 //       }
452 //    }
453 //    else if (moved == KING)
454 //    {
455 //       move is a castle (long or short)
456 //    }
457 //    else
458 //    {
459 //       invalid use of special flag
460 //    }
461 // }
462 //
463 typedef union _MOVE
464 {
465     ULONG uMove;
466     struct
467     {
468         UCHAR cFrom        : 8;
469         UCHAR cTo          : 8;
470         UCHAR pMoved       : 4;
471         UCHAR pCaptured    : 4;
472         UCHAR pPromoted    : 4;
473         UCHAR bvFlags      : 4;
474     };
475 } MOVE;
476
477 #define IS_SAME_MOVE(a, b) \
478     (((a).uMove & 0x0FFFFFFF) == (((b).uMove & 0x0FFFFFFF)))
479
480 #define MAKE_MOVE(from,to,piece,cap,prom,flags) \
481     (((ULONG)(from)) | \
482      ((ULONG)(to) << 8) | \
483      ((ULONG)(piece) << 16) | \
484      ((ULONG)(cap) << 20) | \
485      ((ULONG)(prom) << 24) | \
486      ((ULONG)(flags) << 28))
487
488 #define MAKE_MOVE_WITH_NO_PROM_OR_FLAGS(from,to,piece,cap) \
489     (((ULONG)(from)) | \
490      ((ULONG)(to) << 8) | \
491      ((ULONG)(piece) << 16) | \
492      ((ULONG)(cap) << 20))
493
494 //
495 // Move flag values:
496 //
497 #define MOVE_FLAG_SPECIAL          (1)        // en pass, prom, castle, double
498 #define IS_SPECIAL_MOVE(mv)         \
499     ((mv).uMove & 0x10000000)
500
501 #define IS_CASTLE(mv)               \
502     (IS_SPECIAL_MOVE(mv) && IS_KING((mv).pMoved))
503
504 #ifdef DEBUG
505 #define IS_PROMOTION(mv)            \
506     (IS_SPECIAL_MOVE(mv) && ((mv).pPromoted))
507 #else
508 #define IS_PROMOTION(mv)            \
509     ((mv).pPromoted)
510 #endif
511
512 #define IS_CAPTURE_OR_PROMOTION(mv) \
513     ((mv).uMove & 0x0FF00000)
514
515 #define IS_ENPASSANT(mv)            \
516     (IS_SPECIAL_MOVE(mv) && (mv.pCaptured) && !IS_PROMOTION(mv))
517
518 #define IS_DOUBLE_JUMP(mv)          \
519     (IS_SPECIAL_MOVE(mv) && !IS_CAPTURE_OR_PROMOTION(mv))
520
521 #define MOVE_FLAG_KILLERMATE       (2)        // killer mate
522 #define IS_KILLERMATE_MOVE(mv)     ((mv).uMove & 0x20000000)
523
524 #define MOVE_FLAG_ESCAPING_CHECK   (4)        // escaping check
525 #define IS_ESCAPING_CHECK(mv)      ((mv).uMove & 0x40000000)
526
527 #define MOVE_FLAG_CHECKING         (8)        // checking move
528 #define IS_CHECKING_MOVE(mv)       ((mv).uMove & 0x80000000)
529
530 // ----------------------------------------------------------------------
531 //
532 // Move list
533 //
534 #define MAX_MOVE_LIST              (MAX_MOVES_PER_GAME + MAX_PLY_PER_SEARCH)
535
536 // ----------------------------------------------------------------------
537
538 #pragma pack(1)
539 typedef union _ATTACK_BITV
540 {
541     ULONG uWholeThing;
542     struct
543     {
544         union
545         {
546             UCHAR uSmall;
547             struct
548             {
549                 UCHAR uNumAttacks : 3;            // 0..2
550                 UCHAR uKing : 1;                  // 4..7
551                 UCHAR uQueen : 1;
552                 UCHAR uRook : 1;
553                 UCHAR uMinor : 1;
554                 UCHAR uPawn : 1;
555             } small;
556         };
557
558         // --------------------
559         union
560         {
561             USHORT uBig;
562             struct
563             {
564                 USHORT uKing : 1;                  // 8..23
565                 USHORT uQueens : 4;
566                 USHORT uRooks : 4;
567                 USHORT uMinors : 4;
568                 USHORT uPawns : 2;
569                 USHORT uUnusedFlag1 : 1;
570             } big;
571         };
572
573         // -------------------
574         union
575         {
576             UCHAR uXray;
577             struct
578             {
579                 UCHAR uNumXrays : 3;
580                 UCHAR uUnusedFlag2 : 1;
581                 UCHAR uQueen : 1;                 // 24..28
582                 UCHAR uRook : 1;
583                 UCHAR uBishop : 1;
584                 UCHAR uUnusedFlag3 : 1;
585             } xray;
586         };
587     };
588 }
589 ATTACK_BITV;
590
591 #define UNSAFE_FOR_MINOR(x) ((ULONG)((x).uWholeThing) & 0x00000080UL)
592 #define UNSAFE_FOR_ROOK(x)  ((ULONG)((x).uWholeThing) & 0x000000C0UL)
593 #define UNSAFE_FOR_QUEEN(x) ((ULONG)((x).uWholeThing) & 0x000000E0UL)
594
595 #define PAWN_BIT       0x00000080UL
596 #define MINOR_BIT      0x00000040UL
597 #define MINOR_XRAY_BIT 0x40000000UL
598 #define ROOK_BIT       0x00000020UL
599 #define ROOK_XRAY_BIT  0x20000000UL
600 #define QUEEN_BIT      0x00000010UL
601 #define QUEEN_XRAY_BIT 0x10000000UL
602
603 #define INVALID_PIECE_INDEX (17)
604 #define IS_VALID_PIECE_INDEX(x) ((x) < INVALID_PIECE_INDEX)
605
606 typedef union _SQUARE
607 {
608     struct
609     {
610         PIECE pPiece;
611         ULONG uIndex;
612     };
613     ATTACK_BITV bvAttacks[2];
614 }
615 SQUARE;
616 #pragma pack()
617
618 //
619 // POSITION
620 //
621 typedef struct _POSITION
622 {
623     SQUARE rgSquare[128];                  // where the pieces are,
624                                            // also, the attack table
625     UINT64 u64NonPawnSig;                  // hash signature
626     UINT64 u64PawnSig;                     // pawn hash signature
627     ULONG uToMove;                         // whose turn?
628     ULONG uFifty;                          // 50 moves w/o progress = draw
629     FLAG fCastled[2];                      // record when sides have castled
630     BITV bvCastleInfo;                     // who can castle how?
631     COOR cEpSquare;                        // en-passant capture square
632
633     COOR cPawns[2][8];                     // location of pawns on the board
634     ULONG uPawnMaterial[2];                // pawn material of each side
635     ULONG uPawnCount[2];                   // number of pawns for each side
636
637     COOR cNonPawns[2][16];                 // location of pieces on the board
638     ULONG uNonPawnMaterial[2];             // piece material of each side
639     ULONG uNonPawnCount[2][8];             // number of non-pawns / type
640                                            // 0 and 1 are the sum,
641                                            // 2..6 are per PIECE_TYPE
642
643     ULONG uWhiteSqBishopCount[2];          // num bishops on white squares
644     SCORE iMaterialBalance[2];             // material balance
645
646     // temporary storage space for use in eval
647     COOR cTrapped[2];
648     ULONG uArmyScaler[2];
649     ULONG uClosedScaler;
650     SCORE iScore[2];
651     SCORE iReducedMaterialDownScaler[2];
652     SCORE iTempScore;
653     ULONG uMinMobility[2];
654     COOR cPiece;
655     ULONG uMinorsAtHome[2];
656     BITBOARD bb;
657     ULONG uPiecesPointingAtKing[2];
658 }
659 POSITION;
660
661 //
662 // Castling permission bitvector flags.
663 //
664 #define CASTLE_WHITE_SHORT                (1)
665 #define CASTLE_WHITE_LONG                 (2)
666 #define WHITE_CAN_CASTLE                  \
667     (CASTLE_WHITE_SHORT | CASTLE_WHITE_LONG)
668 #define CASTLE_BLACK_SHORT                (4)
669 #define CASTLE_BLACK_LONG                 (8)
670 #define BLACK_CAN_CASTLE                  \
671     (CASTLE_BLACK_SHORT | CASTLE_BLACK_LONG)
672 #define CASTLE_NONE_POSSIBLE              (0)
673 #define CASTLE_ALL_POSSIBLE               \
674     (WHITE_CAN_CASTLE | BLACK_CAN_CASTLE)
675
676 // ----------------------------------------------------------------------
677 //
678 // Move stack
679 //
680 #define MAX_MOVE_STACK             (MAX_PLY_PER_SEARCH * \
681                                     MAX_MOVES_PER_PLY)
682
683 //
684 // Main part of the move stack, triads of moves, their values and flags
685 // that denote where the values came from
686 //
687 #define MVF_MOVE_SEARCHED    (1)
688 #define MVF_EXTEND_MOVE      (2)
689 #define MVF_REDUCE_MOVE      (4)
690 #define MVF_PRUNE_SUBTREE    (8)
691
692 typedef struct _MOVE_STACK_MOVE_VALUE_FLAGS
693 {
694     SCORE iValue;
695     MOVE mv;
696     BITV bvFlags;
697 }
698 MOVE_STACK_MOVE_VALUE_FLAGS;
699
700 typedef struct _KEY_POINTER
701 {
702     int iPointer;
703     ULONG uKey;
704 }
705 KEY_POINTER;
706
707 typedef union _GENERATOR_FLAGS 
708 {
709     struct {
710         UCHAR uMoveCount;
711         UCHAR uKingMoveCount;
712         UCHAR uCheckingPieces;
713         UCHAR uUnused;
714     };
715     ULONG uAllGenFlags;
716 }
717 GENERATOR_FLAGS;
718
719 //
720 // A move stack
721 //
722 typedef struct _MOVE_STACK
723 {
724 #ifdef DEBUG
725     POSITION board[MAX_PLY_PER_SEARCH];
726 #endif
727     //
728     // Unblocked squares map, used for check detection
729     //
730     ULONG uUnblockedKeyValue[MAX_PLY_PER_SEARCH];
731     KEY_POINTER sUnblocked[MAX_PLY_PER_SEARCH][128];
732
733     //
734     // The main move list, a long series of moves, their values and some
735     // flag bits to tell search what the values are based upon.
736     //
737     MOVE_STACK_MOVE_VALUE_FLAGS mvf[MAX_MOVE_STACK];
738
739     //
740     // uBegin[ply] and uEnd[ply] specify the start and end of moves gen-
741     // erated for a position at ply distance from the root.
742     //
743     ULONG uPly;
744     ULONG uBegin[MAX_PLY_PER_SEARCH];
745     ULONG uEnd[MAX_PLY_PER_SEARCH];
746     MOVE mvHash[MAX_PLY_PER_SEARCH];
747     GENERATOR_FLAGS sGenFlags[MAX_PLY_PER_SEARCH];
748 }
749 MOVE_STACK;
750
751 #define GENERATE_NO_MOVES                              \
752     ctx->sMoveStack.uEnd[ctx->uPly] =                  \
753         ctx->sMoveStack.uBegin[ctx->uPly] + 1;         \
754     ctx->sMoveStack.uBegin[ctx->uPly + 1] =            \
755         ctx->sMoveStack.uEnd[ctx->uPly]
756
757 #define GENERATE_ALL_MOVES             (1)
758 #define GENERATE_ESCAPES               (2)
759 #define GENERATE_CAPTURES_PROMS_CHECKS (3)
760 #define GENERATE_CAPTURES_PROMS        (4)
761 #define GENERATE_DONT_SCORE            (5)
762 #ifdef TEST
763 #define GENERATE_ALL_MOVES_CHECK_OK    (6)
764 #endif
765
766 #define MOVE_COUNT(ctx, x)             \
767     (((ctx)->sMoveStack.uEnd[(x)]) - (ctx)->sMoveStack.uBegin[(x)])
768 #define ONE_LEGAL_MOVE(ctx, x) \
769     (MOVE_COUNT(ctx, x) == 1)
770 #define NUM_KING_MOVES(ctx, x) \
771     ((ctx)->sMoveStack.sGenFlags[(x)].uKingMoveCount)
772 #define NUM_CHECKING_PIECES(ctx, x) \
773     ((ctx)->sMoveStack.sGenFlags[(x)].uCheckingPieces)
774
775
776 // ----------------------------------------------------------------------
777 //
778 // Accumulators
779 //
780 typedef struct _COUNTERS
781 {
782     struct
783     {
784         UINT64 u64Probes;
785         UINT64 u64OverallHits;
786         UINT64 u64UsefulHits;
787         UINT64 u64UpperBoundHits;
788         UINT64 u64LowerBoundHits;
789         UINT64 u64ExactScoreHits;
790     }
791     hash;
792
793     struct
794     {
795         UINT64 u64Probes;
796         UINT64 u64Hits;
797     }
798     pawnhash;
799
800     struct
801     {
802         UINT64 u64TotalNodeCount;
803         UINT64 u64QNodeCount;
804         UINT64 u64LeafCount;
805         UINT64 u64TerminalPositionCount;
806         UINT64 u64BetaCutoffs;
807         UINT64 u64BetaCutoffsOnFirstMove;
808         UINT64 u64NullMoves;
809         UINT64 u64NullMoveSuccess;
810 #ifdef TEST_NULL
811         UINT64 u64QuickNullSuccess;
812         UINT64 u64QuickNullDeferredSuccess;
813         UINT64 u64QuickNullFailures;
814         UINT64 u64AvoidNullSuccess;
815         UINT64 u64AvoidNullFailures;
816 #endif
817         UINT64 u64EvalHashHits;
818         UINT64 u64LazyEvals;
819         UINT64 u64FullEvals;
820         UINT64 u64CyclesInEval;
821     }
822     tree;
823
824     struct
825     {
826         ULONG uNumSplits;
827         ULONG uNumSplitsTerminated;
828     }
829     parallel;
830
831     struct
832     {
833         ULONG uPawnPush;
834         ULONG uCheck;
835         ULONG uMateThreat;
836         ULONG uRecapture;
837         ULONG uOneLegalMove;
838         ULONG uNoLegalKingMoves;
839         ULONG uMultiCheck;
840         ULONG uSingularMove;
841         ULONG uZugzwang;
842         ULONG uSingularReplyToCheck;
843         ULONG uEndgame;
844         ULONG uBotvinnikMarkoff;
845         ULONG uQExtend;
846     }
847     extension;
848
849     struct
850     {
851         ULONG uProbes;
852         ULONG uHits;
853     }
854     egtb;
855 }
856 COUNTERS;
857
858 typedef struct _CUMULATIVE_SEARCH_FLAGS
859 {
860     // search
861     ULONG uNumChecks[2];                      // not used
862     FLAG fInSuspiciousBranch;                 // not used
863     FLAG fInReducedDepthBranch;               // not used
864     FLAG fAvoidNullmove;                      // restore
865     FLAG fVerifyNullmove;                     // restore
866
867     // qsearch
868     ULONG uQsearchDepth;                      // restore
869     ULONG uQsearchNodes;                      // incremental
870     ULONG uQsearchCheckDepth;                 // restore
871     FLAG fCouldStandPat[2];                   // restore
872 }
873 CUMULATIVE_SEARCH_FLAGS;
874
875 // ----------------------------------------------------------------------
876 //
877 // Searcher thread record
878 //
879 typedef struct _SPLIT_INFO
880 {
881     // locks / counters
882     volatile ULONG uLock;                     // lock for this split node
883     volatile ULONG uNumThreadsHelping;        // num threads in this node
884     volatile FLAG fTerminate;                 // signal helpers to terminate
885
886     // moves in the split node
887     ULONG uRemainingMoves;                    // num moves remaining to do
888     ULONG uOnDeckMove;                        // next move to do
889     ULONG uNumMoves;
890     ULONG uAlreadyDone;
891     MOVE_STACK_MOVE_VALUE_FLAGS
892         mvf[MAX_MOVES_PER_PLY];               // the moves to search
893
894     // input to the split node
895     POSITION sRootPosition;                   // the root position
896     MOVE mvPathToHere[MAX_PLY_PER_SEARCH];    // path from root to split
897     MOVE mvLast;                              // last move before split
898     ULONG uDepth;                             // remaining depth at split
899     INT iPositionExtend;                      // positional extension
900     SCORE iAlpha;                             // original alpha at split
901     SCORE iBeta;                              // beta at split
902     ULONG uSplitPositional;                   // pos->uPositional at split
903     CUMULATIVE_SEARCH_FLAGS sSearchFlags;     // flags at split time
904
905     // output from the split node
906     MOVE mvBest;                              // the best move
907     SCORE iBestScore;                         // it's score
908     COUNTERS sCounters;                       // updated counters
909     MOVE PV[MAX_PLY_PER_SEARCH];
910
911 #ifdef DEBUG
912     ULONG uSplitPly;
913     POSITION sSplitPosition;
914 #endif
915 }
916 SPLIT_INFO;
917
918 typedef struct _PLY_INFO
919 {
920 #ifdef DEBUG
921     POSITION sPosition;
922     SCORE iAlpha;
923     SCORE iBeta;
924 #endif
925     SCORE iEval;
926     INT iExtensionAmount;
927     FLAG fInCheck;
928     FLAG fInQsearch;
929     MOVE mv;
930     MOVE mvBest;
931     MOVE PV[MAX_PLY_PER_SEARCH];
932
933     SCORE iKingScore[2];
934     ULONG uMinMobility[2];
935     UINT64 u64NonPawnSig;
936     UINT64 u64PawnSig;
937     UINT64 u64Sig;
938     ULONG uFifty;
939     FLAG fCastled[2];
940     ULONG uTotalNonPawns;
941     BITV bvCastleInfo;
942     COOR cEpSquare;
943 }
944 PLY_INFO;
945
946 #define EVAL_HASH
947 #ifdef EVAL_HASH
948 #define EVAL_HASH_TABLE_SIZE (2097152) // 32Mb (per thread)
949 typedef struct _EVAL_HASH_ENTRY
950 {
951     UINT64 u64Key;
952     SCORE iEval;
953     ULONG uPositional;
954     COOR cTrapped[2];
955
956 } EVAL_HASH_ENTRY;
957 #endif
958
959 #define PAWN_HASH_TABLE_SIZE (131072) // 5.5Mb (per thread)
960 typedef struct _PAWN_HASH_ENTRY
961 {
962     UINT64 u64Key;
963     BITBOARD bbPawnLocations[2];
964     BITBOARD bbPasserLocations[2];
965     BITBOARD bbStationaryPawns[2];
966     SHORT iScore[2];
967     UCHAR uCountPerFile[2][10];
968     UCHAR uNumRammedPawns;
969     UCHAR uNumUnmovedPawns[2];
970 }
971 PAWN_HASH_ENTRY;
972
973 #define NUM_SPLIT_PTRS_IN_CONTEXT (8)
974
975 typedef struct _SEARCHER_THREAD_CONTEXT
976 {
977     ULONG uPly;                               // its distance from root
978     ULONG uPositional;                        // positional component of score
979     POSITION sPosition;                       // the board
980     MOVE_STACK sMoveStack;                    // the move stack
981     CUMULATIVE_SEARCH_FLAGS sSearchFlags;
982     PLY_INFO sPlyInfo[MAX_PLY_PER_SEARCH+1];
983     MOVE mvKiller[MAX_PLY_PER_SEARCH][2];
984     MOVE mvKillerEscapes[MAX_PLY_PER_SEARCH][2];
985     MOVE mvNullmoveRefutations[MAX_PLY_PER_SEARCH];
986     COUNTERS sCounters;
987     ULONG uThreadNumber;
988     SPLIT_INFO *pSplitInfo[NUM_SPLIT_PTRS_IN_CONTEXT];
989     MOVE mvRootMove;
990     SCORE iRootScore;
991     ULONG uRootDepth;
992     PAWN_HASH_ENTRY rgPawnHash[PAWN_HASH_TABLE_SIZE];
993 #ifdef EVAL_HASH
994     EVAL_HASH_ENTRY rgEvalHash[EVAL_HASH_TABLE_SIZE];
995 #endif
996     CHAR szLastPV[SMALL_STRING_LEN_CHAR];
997 }
998 SEARCHER_THREAD_CONTEXT;
999
1000 //
1001 // When I added the pawn hash table and eval hash tables to searcher
1002 // thread contexts they became too heavy to just allocate on the fly
1003 // for things like checking the legality of SAN moves or seeing if an
1004 // opening book line leads to a draw.  This
1005 // LIGHTWEIGHT_SEARCHER_CONTEXT structure can be cast into a full
1006 // SEARCHER_THREAD_CONTEXT and passed safely into the Generate,
1007 // MakeMove and UnMakeMove functions because they presently only
1008 // need:
1009 //
1010 //     1. uPly
1011 //     2. sPosition
1012 //     3. sPlyInfo
1013 //     4. sMoveStack
1014 //
1015 typedef struct _LIGHTWEIGHT_SEARCHER_CONTEXT
1016 {
1017     ULONG uPly;
1018     ULONG uPositional;
1019     POSITION sPosition;
1020     MOVE_STACK sMoveStack;
1021     CUMULATIVE_SEARCH_FLAGS sSearchFlags;
1022     PLY_INFO sPlyInfo[MAX_PLY_PER_SEARCH+1];
1023 }
1024 LIGHTWEIGHT_SEARCHER_CONTEXT;
1025
1026 // ----------------------------------------------------------------------
1027 //
1028 // Global game options
1029 //
1030 typedef struct _GAME_OPTIONS
1031 {
1032     ULONG uMyClock;
1033     ULONG uOpponentsClock;
1034     FLAG fGameIsRated;
1035     FLAG fOpponentIsComputer;
1036     ULONG uSecPerMove;
1037     ULONG uMaxDepth;
1038     FLAG fShouldPonder;
1039     FLAG fPondering;
1040     FLAG fThinking;
1041     FLAG fSuccessfulPonder;
1042     MOVE mvPonder;
1043     FLAG fShouldPost;
1044     FLAG fForceDrawWorthZero;
1045     ULONG uMyIncrement;
1046     ULONG uMovesPerTimePeriod;
1047     CHAR szAnalyzeProgressReport[SMALL_STRING_LEN_CHAR];
1048     FLAG fShouldAnnounceOpening;
1049     SCORE iLastEvalScore;
1050     UINT64 u64NodesSearched;
1051     CHAR szLogfile[SMALL_STRING_LEN_CHAR];
1052     CHAR szEGTBPath[SMALL_STRING_LEN_CHAR];
1053     CHAR szBookName[SMALL_STRING_LEN_CHAR];
1054     ULONG uNumProcessors;
1055     ULONG uNumHashTableEntries;
1056     FLAG fNoInputThread;
1057     FLAG fVerbosePosting;
1058     FLAG fRunningUnderXboard;
1059     FLAG fStatusLine;
1060     FLAG fFastScript;
1061
1062     enum
1063     {
1064         CLOCK_NORMAL               = 0,
1065         CLOCK_FIXED,
1066         CLOCK_INCREMENT,
1067         CLOCK_NONE
1068     }
1069     eClock;
1070
1071     enum
1072     {
1073         GAME_UNKNOWN               = 0,
1074         GAME_BULLET,
1075         GAME_BLITZ,
1076         GAME_STANDARD
1077     }
1078     eGameType;
1079
1080     enum
1081     {
1082         I_PLAY_WHITE               = 0,
1083         I_PLAY_BLACK,
1084         FORCE_MODE,
1085         EDIT_MODE,
1086         ANALYZE_MODE
1087     }
1088     ePlayMode;
1089 }
1090 GAME_OPTIONS;
1091 extern GAME_OPTIONS g_Options;
1092
1093 // ----------------------------------------------------------------------
1094 //
1095 // Move timer
1096 //
1097
1098 #define TIMER_SEARCHING_FIRST_MOVE       (0x1)
1099 #define TIMER_SEARCHING_IMPORTANT_MOVE   (0x2)
1100 #define TIMER_RESOLVING_ROOT_FL          (0x4)
1101 #define TIMER_RESOLVING_ROOT_FH          (0x8)
1102 #define TIMER_JUST_OUT_OF_BOOK           (0x10)
1103 #define TIMER_CURRENT_OBVIOUS            (0x20)
1104 #define TIMER_CURRENT_WONT_UNBLOCK       (0x40)
1105 #define TIMER_ROOT_POSITION_CRITICAL     (0x80)
1106 #define TIMER_MOVE_IMMEDIATELY           (0x100)
1107 #define TIMER_MANY_ROOT_FLS              (0x200)
1108 #define TIMER_STOPPING                   (0x400)
1109 #define TIMER_SPLIT_FAILED               (0x800)
1110
1111 typedef struct _MOVE_TIMER
1112 {
1113     double dStartTime;
1114     double dEndTime;
1115     double dSoftTimeLimit;
1116     double dHardTimeLimit;
1117     ULONG uNodeCheckMask;
1118     volatile BITV bvFlags;
1119 }
1120 MOVE_TIMER;
1121
1122 // ----------------------------------------------------------------------
1123 //
1124 // Special move tag literals
1125 //
1126 #define ILLEGALMOVE                ((ULONG)0x1DDD8888)
1127
1128 //
1129 // useful macros
1130 //
1131 #ifdef DEBUG
1132 void
1133 _assert(CHAR *szFile, ULONG uLine);
1134
1135 #define ASSERT(x)                  if (x)    \
1136                                    { ; }     \
1137                                    else      \
1138                                    { _assert(__FILE__, __LINE__); }
1139 #define VERIFY(x)                  ASSERT(x)
1140 #else
1141 #define ASSERT(x)                   ;
1142 #define VERIFY(x)                  x;
1143 #endif // DEBUG
1144
1145 #ifdef PERF_COUNTERS
1146 #define INC(x)                     ((x) += 1)
1147 #else
1148 #define INC(x)
1149 #endif
1150
1151 #define BREAKPOINT                 SystemDebugBreakpoint()
1152
1153 #define MIN(x, y)                  (((x) < (y)) ? (x) : (y))
1154 #define MAX(x, y)                  (((x) > (y)) ? (x) : (y))
1155
1156 #ifdef _X86_
1157 //
1158 // Note: MAXU, MINU and ABS_DIFF require arguments with the high order
1159 // bit CLEAR to work right.
1160 //
1161 // These are branchless constructs.  MAXU and MINU are equivalent to
1162 // MIN and MAX (with the above restriction on inputs)
1163 //
1164 // MIN0 and MAX0 are equivalent to MAX(0, x) and MIN(0, x).  These
1165 // macros have no restiction on argument type.
1166 //
1167 // ABS_DIFF is equivalent to abs(x - y).  Again, x and y must have
1168 // their high-order bits CLEAR for this to work.
1169 //
1170 // Note: gcc generates code with cmovs so no need for MAXU/MINU on
1171 // that compiler.
1172 //
1173 //#ifndef __GNUC__
1174 #define MINU(x, y)                 \
1175     (((((int)((x)-(y)))>>31) & ((x)-(y)))+(y))
1176 #define MAXU(x, y)                 \
1177     (((((int)((x)-(y)))>>31) & ((y)-(x)))+(x))
1178 //#endif
1179 #ifndef DEBUG
1180
1181 #define MIN0(x)                    \
1182     ((x) & (((int)(x)) >> 31))
1183
1184 #define MAX0(x)                    \
1185     ((x) & ~(((int)(x)) >> 31))
1186
1187 #else // !DEBUG
1188 extern INLINE int MIN0(int x)
1189 {
1190     int y = MIN(x, 0);
1191     int z = ((x) & (((int)(x)) >> 31));
1192     ASSERT(y == z);
1193     return(z);
1194 }
1195
1196 extern INLINE int MAX0(int x)
1197 {
1198     int y = MAX(x, 0);
1199     int z = ((x) & ~(((int)(x)) >> 31));
1200     ASSERT(y == z);
1201     return(z);
1202 }
1203 #endif // DEBUG
1204
1205 #define ABS_DIFF(a, b)             \
1206     (((b)-(a)) - ((((b) - (a)) & (((int)((b) - (a))) >> 31) ) << 1))
1207
1208 #endif // _X86_
1209
1210 #ifndef MINU
1211 #define MINU(x, y)                 (MIN((x), (y)))
1212 #endif
1213
1214 #ifndef MAXU
1215 #define MAXU(x, y)                 (MAX((x), (y)))
1216 #endif
1217
1218 #ifndef MIN0
1219 #define MIN0(x)                    (MIN((x), 0))
1220 #endif
1221
1222 #ifndef MAX0
1223 #define MAX0(x)                    (MAX((x), 0))
1224 #endif
1225
1226 #ifndef ABS_DIFF
1227 #define ABS_DIFF(a, b)             (abs((a) - (b)))
1228 #endif
1229
1230 #define FILE_DISTANCE(a, b)        (ABS_DIFF(FILE((a)), FILE((b))))
1231 #define RANK_DISTANCE(a, b)        (ABS_DIFF(((a) & 0xF0), ((b) & 0xF0)) >> 4)
1232 #define REAL_DISTANCE(a, b)        (MAXU(FILE_DISTANCE((a), (b)), \
1233                                          RANK_DISTANCE((a), (b))))
1234 #ifdef DEBUG
1235 #define DISTANCE(a, b)             DistanceBetweenSquares((a), (b))
1236 #else
1237 #define DISTANCE(a, b)             g_pDistance[(a) - (b)]
1238 #endif // DEBUG
1239
1240 #define    IS_EMPTY( square )      (!(square))
1241 #define IS_OCCUPIED( square )      ((square))
1242
1243 #define IS_DEAD( listindex )       ((listindex) > 119)
1244 #define IS_ALIVE( listindex )      ((listindex) <= 119)
1245 #define ILLEGAL_COOR               (0x88)
1246 #define EDGE_DISTANCE(c)           (MIN(MIN(abs(RANK(c) - 7), RANK(c)), \
1247                                         MIN(abs(FILE(c) - 7), FILE(c))))
1248 #define NOT_ON_EDGE(c)             ((((c) & 0xF0) != 0x00) && \
1249                                        (((c) & 0xF0) != 0x70) && \
1250                                        (((c) & 0x0F) != 0x00) && \
1251                                        (((c) & 0x0F) != 0x07))
1252 #define ON_EDGE(c)                 (RANK8(c) || \
1253                                     RANK1(c) || \
1254                                     FILEA(c) || \
1255                                     FILEH(c))
1256 #define CORNER_DISTANCE(c)         (MAX(MIN((ULONG)abs(RANK(c) - 7), RANK(c)),\
1257                                         MIN((ULONG)abs(FILE(c) - 7), FILE(c))))
1258 #define IN_CORNER(c)               (((c) == A8) || \
1259                                        ((c) == A1) || \
1260                                        ((c) == H8) || \
1261                                        ((c) == H1))
1262 #define WHITE_CORNER_DISTANCE(c)   (MIN(DISTANCE((c), A8), \
1263                                         DISTANCE((c), H1)))
1264 #define BLACK_CORNER_DISTANCE(c)   (MIN(DISTANCE((c), H8), \
1265                                         DISTANCE((c), A1)))
1266 #define SYM_SQ(c)                  ((7 - (((c) & 0xF0) >> 4)) << 4) \
1267                                        | (7 - ((c) & 0x0F))
1268 #define ARRAY_SIZE(a)              (sizeof((a)) / sizeof((a[0])))
1269 #define MAKE_PSQT(a, b, c, d)      (((a) << 24) | ((b) << 16) | \
1270                                        ((c) << 8) | (d))
1271 #define TO64(x)                    ((x) & 0x7) + ((0x7 - ((x)>>4)) << 3)
1272 #define COOR_TO_BIT_NUMBER(c)      (((((c) & 0x70) >> 1) | ((c) & 0x7)))
1273 #define SLOWCOOR_TO_BB(c)          (1ULL << COOR_TO_BIT_NUMBER(c))
1274 #define COOR_TO_BB(c)              (BBSQUARE[COOR_TO_BIT_NUMBER(c)])
1275 #define SLOW_BIT_NUMBER_TO_COOR(b) ((((b) / 8) << 4) + ((b) & 7))
1276 #define BIT_NUMBER_TO_COOR(b)      ((((b) & 0xF8) << 1) | ((b) & 7))
1277
1278 #define BBRANK88 \
1279     SLOWCOOR_TO_BB(A8) | SLOWCOOR_TO_BB(B8) | SLOWCOOR_TO_BB(C8) | \
1280     SLOWCOOR_TO_BB(D8) | SLOWCOOR_TO_BB(E8) | SLOWCOOR_TO_BB(F8) | \
1281     SLOWCOOR_TO_BB(G8) | SLOWCOOR_TO_BB(H8)
1282
1283 #define BBRANK77 \
1284     SLOWCOOR_TO_BB(A7) | SLOWCOOR_TO_BB(B7) | SLOWCOOR_TO_BB(C7) | \
1285     SLOWCOOR_TO_BB(D7) | SLOWCOOR_TO_BB(E7) | SLOWCOOR_TO_BB(F7) | \
1286     SLOWCOOR_TO_BB(G7) | SLOWCOOR_TO_BB(H7)
1287
1288 #define BBRANK66 \
1289     SLOWCOOR_TO_BB(A6) | SLOWCOOR_TO_BB(B6) | SLOWCOOR_TO_BB(C6) | \
1290     SLOWCOOR_TO_BB(D6) | SLOWCOOR_TO_BB(E6) | SLOWCOOR_TO_BB(F6) | \
1291     SLOWCOOR_TO_BB(G6) | SLOWCOOR_TO_BB(H6)
1292
1293 #define BBRANK55 \
1294     SLOWCOOR_TO_BB(A5) | SLOWCOOR_TO_BB(B5) | SLOWCOOR_TO_BB(C5) | \
1295     SLOWCOOR_TO_BB(D5) | SLOWCOOR_TO_BB(E5) | SLOWCOOR_TO_BB(F5) | \
1296     SLOWCOOR_TO_BB(G5) | SLOWCOOR_TO_BB(H5)
1297
1298 #define BBRANK44 \
1299     SLOWCOOR_TO_BB(A4) | SLOWCOOR_TO_BB(B4) | SLOWCOOR_TO_BB(C4) | \
1300     SLOWCOOR_TO_BB(D4) | SLOWCOOR_TO_BB(E4) | SLOWCOOR_TO_BB(F4) | \
1301     SLOWCOOR_TO_BB(G4) | SLOWCOOR_TO_BB(H4)
1302
1303 #define BBRANK33 \
1304     SLOWCOOR_TO_BB(A3) | SLOWCOOR_TO_BB(B3) | SLOWCOOR_TO_BB(C3) | \
1305     SLOWCOOR_TO_BB(D3) | SLOWCOOR_TO_BB(E3) | SLOWCOOR_TO_BB(F3) | \
1306     SLOWCOOR_TO_BB(G3) | SLOWCOOR_TO_BB(H3)
1307
1308 #define BBRANK22 \
1309     SLOWCOOR_TO_BB(A2) | SLOWCOOR_TO_BB(B2) | SLOWCOOR_TO_BB(C2) | \
1310     SLOWCOOR_TO_BB(D2) | SLOWCOOR_TO_BB(E2) | SLOWCOOR_TO_BB(F2) | \
1311     SLOWCOOR_TO_BB(G2) | SLOWCOOR_TO_BB(H2)
1312
1313 #define BBRANK11 \
1314     SLOWCOOR_TO_BB(A1) | SLOWCOOR_TO_BB(B1) | SLOWCOOR_TO_BB(C1) | \
1315     SLOWCOOR_TO_BB(D1) | SLOWCOOR_TO_BB(E1) | SLOWCOOR_TO_BB(F1) | \
1316     SLOWCOOR_TO_BB(G1) | SLOWCOOR_TO_BB(H1)
1317
1318 #define BBFILEA \
1319     SLOWCOOR_TO_BB(A1) | SLOWCOOR_TO_BB(A2) | SLOWCOOR_TO_BB(A3) | \
1320     SLOWCOOR_TO_BB(A4) | SLOWCOOR_TO_BB(A5) | SLOWCOOR_TO_BB(A6) | \
1321     SLOWCOOR_TO_BB(A7) | SLOWCOOR_TO_BB(A8)
1322
1323 #define BBFILEB \
1324     SLOWCOOR_TO_BB(B1) | SLOWCOOR_TO_BB(B2) | SLOWCOOR_TO_BB(B3) | \
1325     SLOWCOOR_TO_BB(B4) | SLOWCOOR_TO_BB(B5) | SLOWCOOR_TO_BB(B6) | \
1326     SLOWCOOR_TO_BB(B7) | SLOWCOOR_TO_BB(B8)
1327
1328 #define BBFILEC \
1329     SLOWCOOR_TO_BB(C1) | SLOWCOOR_TO_BB(C2) | SLOWCOOR_TO_BB(C3) | \
1330     SLOWCOOR_TO_BB(C4) | SLOWCOOR_TO_BB(C5) | SLOWCOOR_TO_BB(C6) | \
1331     SLOWCOOR_TO_BB(C7) | SLOWCOOR_TO_BB(C8)
1332
1333 #define BBFILED \
1334     SLOWCOOR_TO_BB(D1) | SLOWCOOR_TO_BB(D2) | SLOWCOOR_TO_BB(D3) | \
1335     SLOWCOOR_TO_BB(D4) | SLOWCOOR_TO_BB(D5) | SLOWCOOR_TO_BB(D6) | \
1336     SLOWCOOR_TO_BB(D7) | SLOWCOOR_TO_BB(D8)
1337
1338 #define BBFILEE \
1339     SLOWCOOR_TO_BB(E1) | SLOWCOOR_TO_BB(E2) | SLOWCOOR_TO_BB(E3) | \
1340     SLOWCOOR_TO_BB(E4) | SLOWCOOR_TO_BB(E5) | SLOWCOOR_TO_BB(E6) | \
1341     SLOWCOOR_TO_BB(E7) | SLOWCOOR_TO_BB(E8)
1342
1343 #define BBFILEF \
1344     SLOWCOOR_TO_BB(F1) | SLOWCOOR_TO_BB(F2) | SLOWCOOR_TO_BB(F3) | \
1345     SLOWCOOR_TO_BB(F4) | SLOWCOOR_TO_BB(F5) | SLOWCOOR_TO_BB(F6) | \
1346     SLOWCOOR_TO_BB(F7) | SLOWCOOR_TO_BB(F8)
1347
1348 #define BBFILEG \
1349     SLOWCOOR_TO_BB(G1) | SLOWCOOR_TO_BB(G2) | SLOWCOOR_TO_BB(G3) | \
1350     SLOWCOOR_TO_BB(G4) | SLOWCOOR_TO_BB(G5) | SLOWCOOR_TO_BB(G6) | \
1351     SLOWCOOR_TO_BB(G7) | SLOWCOOR_TO_BB(G8)
1352
1353 #define BBFILEH \
1354     SLOWCOOR_TO_BB(H1) | SLOWCOOR_TO_BB(H2) | SLOWCOOR_TO_BB(H3) | \
1355     SLOWCOOR_TO_BB(H4) | SLOWCOOR_TO_BB(H5) | SLOWCOOR_TO_BB(H6) | \
1356     SLOWCOOR_TO_BB(H7) | SLOWCOOR_TO_BB(H8)
1357
1358 #define BBRANK72 \
1359     BBRANK77 | BBRANK66 | BBRANK55 | BBRANK44 | BBRANK33 | BBRANK22
1360
1361 #define BBRANK62 \
1362     BBRANK66 | BBRANK55 | BBRANK44 | BBRANK33 | BBRANK22
1363
1364 #define BBRANK52 \
1365     BBRANK55 | BBRANK44 | BBRANK33 | BBRANK22
1366
1367 #define BBRANK42 \
1368     BBRANK44 | BBRANK33 | BBRANK22
1369
1370 #define BBRANK32 \
1371     BBRANK33 | BBRANK22
1372
1373 #define BBRANK27 \
1374     BBRANK22 | BBRANK33 | BBRANK44 | BBRANK55 | BBRANK66 | BBRANK77
1375
1376 #define BBRANK37 \
1377     BBRANK33 | BBRANK44 | BBRANK55 | BBRANK66 | BBRANK77
1378
1379 #define BBRANK47 \
1380     BBRANK44 | BBRANK55 | BBRANK66 | BBRANK77
1381
1382 #define BBRANK57 \
1383     BBRANK55 | BBRANK66 | BBRANK77
1384
1385 #define BBRANK67 \
1386     BBRANK66 | BBRANK77
1387
1388 #include <stdlib.h>
1389 #include <stdio.h>
1390 #include <stdarg.h>
1391 #include <string.h>
1392 #include <ctype.h>
1393 #include <time.h>
1394 #include <sys/types.h>
1395 #include <sys/stat.h>
1396 #include <fcntl.h>
1397
1398 //
1399 // util.c
1400 //
1401 COMMAND(LearnPsqtFromPgn);
1402
1403 COMMAND(GeneratePositionAndBestMoveSuite);
1404
1405 CHAR *
1406 WalkPV(SEARCHER_THREAD_CONTEXT *ctx);
1407
1408 CHAR *
1409 ReadNextGameFromPgnFile(FILE *pf);
1410
1411 COOR
1412 DistanceBetweenSquares(COOR a, COOR b);
1413
1414 void CDECL
1415 Trace(CHAR *szMessage, ...);
1416
1417 void CDECL
1418 Log(CHAR *szMessage, ...);
1419
1420 void CDECL
1421 Bug(CHAR *szMessage, ...);
1422
1423 char *
1424 FindChunk(char *sz, ULONG uTargetChunk);
1425
1426 FLAG
1427 BufferIsZeroed(BYTE *p, ULONG u);
1428
1429 char *
1430 ColorToString(ULONG u);
1431
1432 char *
1433 CoorToString(COOR c);
1434
1435 char *
1436 ScoreToString(SCORE iScore);
1437
1438 char *
1439 TimeToString(double d);
1440
1441 ULONG
1442 AcquireSpinLock(volatile ULONG *pSpinlock);
1443
1444 FLAG
1445 TryAcquireSpinLock(volatile ULONG *pSpinlock);
1446
1447 void
1448 ReleaseSpinLock(volatile ULONG *pSpinLock);
1449
1450 BYTE
1451 Checksum(BYTE *p, ULONG uSize);
1452
1453 FLAG
1454 BackupFile(CHAR *szFile);
1455
1456 void
1457 UtilPrintPV(SEARCHER_THREAD_CONTEXT *ctx,
1458             SCORE iAlpha,
1459             SCORE iBeta,
1460             SCORE iScore,
1461             MOVE mv);
1462
1463 #define CANNOT_INITIALIZE_SPLIT           (1)
1464 #define INCONSISTENT_POSITION             (2)
1465 #define UNEXPECTED_SYSTEM_CALL_FAILURE    (3)
1466 #define SHOULD_NOT_GET_HERE               (4)
1467 #define GOT_ILLEGAL_MOVE_WHILE_PONDERING  (5)
1468 #define CANNOT_OFFICIALLY_MAKE_MOVE       (6)
1469 #define DETECTED_INCORRECT_INITIALIZATION (7)
1470 #define INCONSISTENT_STATE                (8)
1471 #define FATAL_ACCESS_DENIED               (9)
1472 #define TESTCASE_FAILURE                  (10)
1473 #define INITIALIZATION_FAILURE            (11)
1474
1475 void
1476 UtilPanic(ULONG uPanicCode,
1477           POSITION *pos,
1478           void *a1,
1479           void *a2,
1480           void *a3,
1481           char *file, ULONG line);
1482
1483
1484 //
1485 // main.c
1486 //
1487 #define LOGFILE_NAME                "typhoon.log"
1488 extern FILE *g_pfLogfile;
1489
1490 void
1491 Banner(void);
1492
1493 FLAG
1494 PreGameReset(FLAG fResetBoard);
1495
1496 //
1497 // system dependent exports (see win32.c or fbsd.c)
1498 //
1499 typedef ULONG (THREAD_ENTRYPOINT)(ULONG);
1500
1501 #ifdef DEBUG
1502 ULONG
1503 GetHeapMemoryUsage(void);
1504 #endif
1505
1506 void
1507 SystemDebugBreakpoint(void);
1508
1509 CHAR *
1510 SystemStrDup(CHAR *p);
1511
1512 double
1513 SystemTimeStamp(void);
1514
1515 FLAG
1516 SystemDoesFileExist(CHAR *szFilename);
1517
1518 void
1519 SystemDeferExecution(ULONG uMs);
1520
1521 void
1522 SystemFreeMemory(void *pMem);
1523
1524 void *
1525 SystemAllocateMemory(ULONG dwSizeBytes);
1526
1527 FLAG
1528 SystemMakeMemoryReadOnly(void *pMemory, ULONG dwSizeBytes);
1529
1530 FLAG
1531 SystemMakeMemoryNoAccess(void *pMemory, ULONG dwSizeBytes);
1532
1533 FLAG
1534 SystemMakeMemoryReadWrite(void *pMemory, ULONG dwSizeBytes);
1535
1536 FLAG
1537 SystemDependentInitialization(void);
1538
1539 UINT64 FASTCALL
1540 SystemReadTimeStampCounter(void);
1541
1542 //
1543 // This routine _must_ implement a full memory fence -- it is used in
1544 // util.c to implement spinlocks.
1545 //
1546 FLAG
1547 SystemCreateThread(THREAD_ENTRYPOINT *pEntry, ULONG uParam, ULONG *puHandle);
1548
1549 FLAG
1550 SystemWaitForThreadToExit(ULONG uThreadHandle);
1551
1552 FLAG
1553 SystemGetThreadExitCode(ULONG uThreadHandle, ULONG *puCode);
1554
1555 FLAG
1556 SystemDeleteThread(ULONG uThreadHandle);
1557
1558 CHAR *
1559 SystemGetDateString(void);
1560
1561 CHAR *
1562 SystemGetTimeString(void);
1563
1564 FLAG
1565 SystemCopyFile(CHAR *szSource, CHAR *szDest);
1566
1567 FLAG
1568 SystemDeleteFile(CHAR *szFile);
1569
1570 ULONG
1571 SystemCreateLock(void);
1572
1573 FLAG
1574 SystemDeleteLock(ULONG u);
1575
1576 FLAG
1577 SystemBlockingWaitForLock(ULONG u);
1578
1579 FLAG
1580 SystemReleaseLock(ULONG u);
1581
1582 ULONG
1583 SystemCreateSemaphore(ULONG u);
1584
1585 FLAG
1586 SystemDeleteSemaphore(ULONG u);
1587
1588 void
1589 SystemReleaseSemaphoreResource(ULONG u);
1590
1591 void
1592 SystemObtainSemaphoreResource(ULONG u);
1593
1594
1595 //
1596 // fen.c
1597 //
1598 #define STARTING_POSITION_IN_FEN \
1599     "rnbqkbnr/pppppppp/--------/8/8/--------/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
1600
1601 FLAG
1602 LooksLikeFen(char *szFen);
1603
1604 char *
1605 PositionToFen(POSITION *p);
1606
1607 FLAG
1608 FenToPosition(POSITION *p, char *szFen);
1609
1610 //
1611 // testfen.c
1612 //
1613 #ifdef TEST
1614 void
1615 TestFenCode(void);
1616 #endif
1617
1618 //
1619 // piece.c
1620 //
1621 // INVERTED VALUE == (VALUE_QUEEN / VALUE_PIECE) * VALUE_PAWN;
1622 #define VALUE_PAWN            100
1623 #define INVERT_PAWN           900
1624 #define VALUE_KNIGHT          300
1625 #define INVERT_KNIGHT         300
1626 #define VALUE_BISHOP          300
1627 #define INVERT_BISHOP         300
1628 #define VALUE_ROOK            500
1629 #define INVERT_ROOK           180
1630 #define VALUE_QUEEN           975
1631 #define INVERT_QUEEN          100
1632 #define VALUE_KING            (INFINITY)
1633 #define INVERT_KING           1
1634
1635 #define VALUE_FULL_ARMY       (8 * VALUE_PAWN) + (2 * VALUE_KNIGHT) + \
1636                               (2 * VALUE_BISHOP) + (2 * VALUE_ROOK) + \
1637                               VALUE_QUEEN + VALUE_KING
1638 #define VALUE_MAX_ARMY        (9 * VALUE_QUEEN) + (2 * VALUE_KNIGHT) + \
1639                               (2 * VALUE_BISHOP) + (2 * VALUE_ROOK) + \
1640                               VALUE_KING
1641
1642 typedef struct _PIECE_DATA
1643 {
1644     ULONG uValue;
1645     ULONG uValueOver100;
1646     ULONG uInvertedValue;
1647     CHAR *szName;
1648 } PIECE_DATA;
1649
1650 extern PIECE_DATA g_PieceData[8];
1651
1652 #define PIECE_VALUE_OVER_100(p) (g_PieceData[PIECE_TYPE(p)].uValueOver100)
1653 extern ULONG
1654 PieceValueOver100(PIECE p);
1655
1656 #define PIECE_VALUE(p)          (g_PieceData[PIECE_TYPE(p)].uValue)
1657 extern ULONG
1658 PieceValue(PIECE p);
1659
1660 #define INVERTED_PIECE_VALUE(p) (g_PieceData[PIECE_TYPE(p)].uInvertedValue)
1661 extern ULONG
1662 PieceInvertedValue(PIECE p);
1663
1664 CHAR *
1665 PieceAbbrev(PIECE p);
1666
1667 //
1668 // board.c
1669 //
1670 FLAG
1671 VerifyPositionConsistency(POSITION *pos, FLAG fContinueOnError);
1672
1673 FLAG
1674 PositionsAreEquivalent(POSITION *p1, POSITION *p2);
1675
1676 CHAR *
1677 DrawTextBoardFromPosition(POSITION *pos);
1678
1679 void
1680 DumpPosition(POSITION *pos);
1681
1682 CHAR *
1683 CastleInfoString(BITV bv);
1684
1685 void
1686 SetRootToInitialPosition(void);
1687
1688 //
1689 // move.c
1690 //
1691 void
1692 SlidePiece(POSITION *pos, COOR cFrom, COOR cTo);
1693
1694 PIECE
1695 LiftPiece(POSITION *pos, COOR cSquare);
1696
1697 void
1698 PlacePiece(POSITION *pos, COOR cSquare, PIECE pPiece);
1699
1700 FLAG
1701 MakeMove(SEARCHER_THREAD_CONTEXT *ctx,
1702          MOVE mv);
1703
1704 void
1705 UnmakeMove(SEARCHER_THREAD_CONTEXT *ctx,
1706            MOVE mv);
1707
1708 FLAG
1709 MakeUserMove(SEARCHER_THREAD_CONTEXT *ctx, MOVE mvUser);
1710
1711 void
1712 DumpMove(ULONG u);
1713
1714 //
1715 // movesup.c
1716 //
1717 #define MOVE_TO_INDEX(mv)  (((mv).uMove & 0xFFFF) + \
1718                             (0x10000 * GET_COLOR(mv.pMoved)))
1719
1720 COOR
1721 FasterExposesCheck(POSITION *pos,
1722                    COOR cRemove,
1723                    COOR cLocation);
1724
1725 COOR
1726 ExposesCheck(POSITION *pos,
1727              COOR cRemove,
1728              COOR cLocation);
1729
1730 COOR
1731 ExposesCheckEp(POSITION *pos,
1732                COOR cTest,
1733                COOR cIgnore,
1734                COOR cBlock,
1735                COOR cKing);
1736
1737 FLAG
1738 IsAttacked(COOR cTest, POSITION *pos, ULONG uSide);
1739
1740 FLAG
1741 InCheck(POSITION *pos, ULONG uSide);
1742
1743 FLAG
1744 SanityCheckMove(POSITION *pos, MOVE mv);
1745
1746 FLAG
1747 LooksLikeFile(CHAR c);
1748
1749 FLAG
1750 LooksLikeRank(CHAR c);
1751
1752 FLAG
1753 LooksLikeCoor(CHAR *szData);
1754
1755 CHAR *
1756 StripMove(CHAR *szMove);
1757
1758 ULONG
1759 LooksLikeMove(CHAR *szData);
1760
1761 void FASTCALL
1762 SelectBestWithHistory(SEARCHER_THREAD_CONTEXT *ctx, ULONG u);
1763
1764 void FASTCALL
1765 SelectBestNoHistory(SEARCHER_THREAD_CONTEXT *ctx, ULONG u);
1766
1767 void FASTCALL
1768 SelectMoveAtRoot(SEARCHER_THREAD_CONTEXT *ctx, ULONG u);
1769
1770 #define NOT_MOVE 0
1771 #define MOVE_ICS 1
1772 #define MOVE_SAN 2
1773
1774 COMMAND(PerftCommand);
1775
1776
1777 //
1778 // testmove.c
1779 //
1780 #ifdef TEST
1781 void
1782 TestLiftPlaceSlidePiece(void);
1783
1784 void
1785 TestExposesCheck(void);
1786
1787 void
1788 TestIsAttacked(void);
1789
1790 void
1791 TestMakeUnmakeMove(void);
1792 #endif
1793
1794 //
1795 // generate.c
1796 //
1797 #define SORT_THESE_FIRST (0x40000000)
1798 #define FIRST_KILLER     (0x20000000)
1799 #define SECOND_KILLER    (0x10000000)
1800 #define THIRD_KILLER     (0x08000000)
1801 #define FOURTH_KILLER    (0x04000000)
1802 #define GOOD_MOVE        (0x02000000)
1803 #define STRIP_OFF_FLAGS  (0x00FFFFFF)
1804
1805 extern const int g_iQKDeltas[9];
1806 extern const int g_iNDeltas[9];
1807 extern const int g_iBDeltas[5];
1808 extern const int g_iRDeltas[5];
1809
1810 void
1811 GenerateMoves(SEARCHER_THREAD_CONTEXT *ctx,
1812               MOVE mvOrderFirst,
1813               ULONG uType);
1814
1815 FLAG
1816 WouldGiveCheck(IN SEARCHER_THREAD_CONTEXT *ctx,
1817                IN MOVE mv);
1818
1819 //
1820 // testgenerate.c
1821 //
1822 #ifdef TEST
1823
1824 void
1825 PlyTest(SEARCHER_THREAD_CONTEXT *ctx,
1826         ULONG uDepth,
1827         FLAG fRootPositionInCheck);
1828
1829 void
1830 TestMoveGenerator(void);
1831
1832 void
1833 TestLegalMoveGenerator(void);
1834
1835 #endif
1836
1837 //
1838 // sig.c
1839 //
1840 extern UINT64 g_u64SigSeeds[128][7][2];
1841 extern UINT64 g_u64PawnSigSeeds[128][2];
1842 extern UINT64 g_u64CastleSigSeeds[16];
1843 extern UINT64 g_u64EpSigSeeds[9];
1844
1845 void
1846 InitializeSigSystem(void);
1847
1848 UINT64
1849 ComputePawnSig(POSITION *pos);
1850
1851 UINT64
1852 ComputeSig(POSITION *pos);
1853
1854 //
1855 // mersenne.c
1856 //
1857 void
1858 seedMT(unsigned int seed);
1859
1860 unsigned int
1861 reloadMT(void);
1862
1863 unsigned int
1864 randomMT(void);
1865
1866 //
1867 // data.c
1868 //
1869 typedef struct _VECTOR_DELTA
1870 {
1871     UCHAR iVector[2];
1872     signed char iDelta;
1873     signed char iNegDelta;
1874 }
1875 VECTOR_DELTA;
1876
1877 extern ULONG g_uDistance[256];
1878 extern ULONG *g_pDistance;
1879 extern VECTOR_DELTA g_VectorDelta[256];
1880 extern VECTOR_DELTA *g_pVectorDelta;
1881 extern CHAR g_SwapTable[14][32][32];
1882 extern SCORE _PSQT[14][128];
1883 extern ULONG g_uSearchSortLimits[];
1884 extern MOVE NULLMOVE;
1885 extern MOVE HASHMOVE;
1886 extern MOVE RECOGNMOVE;
1887 extern MOVE DRAWMOVE;
1888 extern MOVE MATEMOVE;
1889 extern FLAG g_fIsWhiteSquare[128];
1890 extern BITBOARD BBFILE[8];
1891 extern BITBOARD BBRANK[9];
1892 extern BITBOARD BBWHITESQ;
1893 extern BITBOARD BBBLACKSQ;
1894 extern BITBOARD BBLEFTSIDE;
1895 extern BITBOARD BBRIGHTSIDE;
1896 extern BITBOARD BBSQUARE[64];
1897 extern BITBOARD BBROOK_PAWNS;
1898 extern BITBOARD BBPRECEEDING_RANKS[8][2];
1899 extern BITBOARD BBADJACENT_FILES[8];
1900 extern BITBOARD BBADJACENT_RANKS[9];
1901
1902 void
1903 InitializeWhiteSquaresTable(void);
1904
1905 void
1906 InitializeVectorDeltaTable(void);
1907
1908 void
1909 InitializeSwapTable(void);
1910
1911 void
1912 InitializeDistanceTable(void);
1913
1914 void
1915 InitializeSearchDepthArray(void);
1916
1917 ULONG
1918 GetSearchSortLimit(ULONG);
1919
1920 #ifdef DEBUG
1921 #define SEARCH_SORT_LIMIT(x)    (GetSearchSortLimit((x)))
1922 #else
1923 #define SEARCH_SORT_LIMIT(x)    (g_uSearchSortLimits[(x)])
1924 #endif
1925
1926 #ifdef DEBUG
1927 ULONG CheckVectorWithIndex(int i, ULONG uColor);
1928 #define CHECK_VECTOR_WITH_INDEX(i, color) \
1929     CheckVectorWithIndex(i, color)
1930
1931 int DirectionBetweenSquaresWithIndex(int i);
1932 #define CHECK_DELTA_WITH_INDEX(i) \
1933     DirectionBetweenSquaresWithIndex(i)
1934
1935 int DirectionBetweenSquaresFromTo(COOR, COOR);
1936 #define DIRECTION_BETWEEN_SQUARES(from, to) \
1937     DirectionBetweenSquaresFromTo(from, to)
1938
1939 int NegativeDirectionBetweenSquaresWithIndex(int i);
1940 #define NEG_DELTA_WITH_INDEX(i) \
1941     NegativeDirectionBetweenSquaresWithIndex(i)
1942
1943 FLAG IsSquareWhite(COOR c);
1944 #define IS_SQUARE_WHITE(c) \
1945     IsSquareWhite(c)
1946
1947 #else
1948 #define CHECK_VECTOR_WITH_INDEX(i, color) \
1949     (g_pVectorDelta[(i)].iVector[(color)])
1950
1951 #define CHECK_DELTA_WITH_INDEX(i) \
1952     (g_pVectorDelta[(i)].iDelta)
1953
1954 #define DIRECTION_BETWEEN_SQUARES(cFrom, cTo) \
1955     CHECK_DELTA_WITH_INDEX((int)(cFrom) - (int)(cTo))
1956
1957 #define NEG_DELTA_WITH_INDEX(i) \
1958     (g_pVectorDelta[(i)].iNegDelta)
1959
1960 #define IS_SQUARE_WHITE(c) \
1961     (g_fIsWhiteSquare[(c)])
1962 #endif
1963
1964 //
1965 // san.c
1966 //
1967 MOVE
1968 ParseMoveSan(CHAR *szInput,
1969              POSITION *pos);
1970
1971 CHAR *
1972 MoveToSan(MOVE mv, POSITION *pos);
1973
1974 //
1975 // testsan.c
1976 //
1977 void
1978 TestSan(void);
1979
1980 //
1981 // list.c
1982 //
1983 void
1984 InitializeListHead(IN DLIST_ENTRY *pListHead);
1985
1986 FLAG
1987 IsListEmpty(IN DLIST_ENTRY *pListHead);
1988
1989 FLAG
1990 RemoveEntryList(IN DLIST_ENTRY *pEntry);
1991
1992 DLIST_ENTRY *
1993 RemoveHeadList(IN DLIST_ENTRY *pListHead);
1994
1995 DLIST_ENTRY *
1996 RemoveTailList(IN DLIST_ENTRY *pListHead);
1997
1998 void
1999 InsertTailList(IN DLIST_ENTRY *pListHead,
2000                IN DLIST_ENTRY *pEntry);
2001
2002 void
2003 InsertHeadList(IN DLIST_ENTRY *pListHead,
2004                IN DLIST_ENTRY *pEntry);
2005
2006 //
2007 // command.c
2008 //
2009 void
2010 ParseUserInput(FLAG fSearching);
2011
2012 FLAG
2013 InitializeCommandSystem(void);
2014
2015 void
2016 CleanupCommandSystem(void);
2017
2018 //
2019 // input.c
2020 //
2021 void
2022 InitInputSystemInBatchMode(void);
2023
2024 ULONG
2025 InitInputSystemWithDedicatedThread(void);
2026
2027 void
2028 PushNewInput(CHAR *buf);
2029
2030 CHAR *
2031 PeekNextInput(void);
2032
2033 CHAR *
2034 ReadNextInput(void);
2035
2036 CHAR *
2037 BlockingReadInput(void);
2038
2039 ULONG
2040 NumberOfPendingInputEvents(void);
2041
2042 volatile extern FLAG g_fExitProgram;
2043
2044 //
2045 // ics.c
2046 //
2047 MOVE
2048 ParseMoveIcs(CHAR *szInput, POSITION *pos);
2049
2050 CHAR *
2051 MoveToIcs(MOVE mv);
2052
2053 //
2054 // testics.c
2055 //
2056 void
2057 TestIcs(void);
2058
2059 //
2060 // gamelist.c
2061 //
2062 typedef enum _ERESULT
2063 {
2064     RESULT_BLACK_WON = -1,
2065     RESULT_DRAW = 0,
2066     RESULT_WHITE_WON = 1,
2067     RESULT_IN_PROGRESS,
2068     RESULT_ABANDONED,
2069     RESULT_UNKNOWN
2070 }
2071 ERESULT;
2072
2073 typedef struct _GAME_PLAYER
2074 {
2075     CHAR *szName;
2076     CHAR *szDescription;
2077     FLAG fIsComputer;
2078     ULONG uRating;
2079 }
2080 GAME_PLAYER;
2081
2082 typedef struct _GAME_HEADER
2083 {
2084     CHAR *szGameDescription;
2085     CHAR *szLocation;
2086     GAME_PLAYER sPlayer[2];
2087     FLAG fGameIsRated;
2088     UINT64 u64OpeningSig;
2089     ERESULT eResult;
2090     CHAR *szResultComment;
2091     CHAR *szInitialFen;
2092 }
2093 GAME_HEADER;
2094
2095 typedef struct _GAME_MOVE
2096 {
2097     DLIST_ENTRY links;
2098     ULONG uNumber;
2099     MOVE mv;
2100     CHAR *szComment;
2101     CHAR *szDecoration;
2102     CHAR *szMoveInSan;
2103     CHAR *szMoveInIcs;
2104     CHAR *szUndoPositionFen;
2105     SCORE iMoveScore;
2106     UINT64 u64PositionSigAfterMove;
2107     UINT64 u64PositionSigBeforeMove;
2108     volatile FLAG fInUse;
2109 }
2110 GAME_MOVE;
2111
2112 typedef struct _GAME_DATA
2113 {
2114     GAME_HEADER sHeader;
2115     DLIST_ENTRY sMoveList;
2116 }
2117 GAME_DATA;
2118
2119 extern GAME_DATA g_GameData;
2120
2121 POSITION *
2122 GetRootPosition(void);
2123
2124 FLAG
2125 SetRootPosition(CHAR *szFen);
2126
2127 void
2128 ResetGameList(void);
2129
2130 ULONG
2131 GetMoveNumber(ULONG uColor);
2132
2133 void
2134 SetGameResultAndDescription(ERESULT r, CHAR *sz);
2135
2136 INT
2137 GetGameResult(void);
2138
2139 void
2140 SetMyName(void);
2141
2142 void
2143 SetOpponentsName(CHAR *sz);
2144
2145 void
2146 SetMyRating(ULONG u);
2147
2148 void
2149 SetOpponentsRating(ULONG u);
2150
2151 void
2152 DumpGameList(void);
2153
2154 void
2155 TellGamelistThatIPlayColor(ULONG u);
2156
2157 void
2158 DumpPgn(void);
2159
2160 FLAG
2161 LoadPgn(CHAR *szPgn);
2162
2163 ULONG
2164 CountOccurrancesOfSigInOfficialGameList(UINT64 u64Sig);
2165
2166 FLAG
2167 DoesSigAppearInOfficialGameList(UINT64 u64Sig);
2168
2169 FLAG
2170 OfficiallyTakebackMove(void);
2171
2172 FLAG
2173 OfficiallyMakeMove(MOVE mv, SCORE iMoveScore, FLAG fFast);
2174
2175 GAME_MOVE *
2176 GetNthOfficialMoveRecord(ULONG n);
2177
2178 void
2179 MakeStatusLine(void);
2180
2181 FLAG
2182 IsLegalDrawByRepetition(void);
2183
2184 //
2185 // script.c
2186 //
2187 COMMAND(ScriptCommand);
2188
2189 COMMAND(SolutionCommand);
2190
2191 COMMAND(AvoidCommand);
2192
2193 COMMAND(IdCommand);
2194
2195 void
2196 PostMoveTestSuiteReport(SEARCHER_THREAD_CONTEXT *);
2197
2198 FLAG
2199 CheckTestSuiteMove(MOVE mv, SCORE iScore, ULONG uDepth);
2200
2201 FLAG
2202 WeAreRunningASuite(void);
2203
2204
2205 //
2206 // vars.c
2207 //
2208 COMMAND(SetCommand);
2209
2210 //
2211 // root.c
2212 //
2213 extern ULONG g_uSoftExtendLimit;
2214 extern ULONG g_uHardExtendLimit;
2215 extern volatile MOVE_TIMER g_MoveTimer;
2216 extern ULONG g_uExtensionReduction[MAX_PLY_PER_SEARCH];
2217
2218 #ifdef PERF_COUNTERS
2219 #define KEEP_TRACK_OF_FIRST_MOVE_FHs(x)                \
2220     ctx->sCounters.tree.u64BetaCutoffs++;              \
2221     if (x)                                             \
2222     {                                                  \
2223        ctx->sCounters.tree.u64BetaCutoffsOnFirstMove++;\
2224     }
2225 #else
2226 #define KEEP_TRACK_OF_FIRST_MOVE_FHs(x)
2227 #endif
2228
2229 #define GAME_NOT_OVER 0
2230 #define GAME_WHITE_WON 1
2231 #define GAME_BLACK_WON 2
2232 #define GAME_DRAW_STALEMATE 3
2233 #define GAME_DRAW_REPETITION 4
2234 #define GAME_ONE_LEGAL_MOVE 5
2235 #define GAME_DRAW_FIFTY_MOVES_WO_PROGRESS 6
2236
2237 FLAG
2238 Think(POSITION *pos);
2239
2240 FLAG
2241 Ponder(POSITION *pos);
2242
2243 FLAG
2244 Iterate(SEARCHER_THREAD_CONTEXT *ctx);
2245
2246 void
2247 SetMoveTimerForSearch(FLAG fSwitchOver, ULONG uColor);
2248
2249 void
2250 SetMoveTimerToThinkForever(void);
2251
2252 void
2253 ClearRootNodecountHash(void);
2254
2255 //
2256 // draw.c
2257 //
2258 FLAG
2259 IsDraw(SEARCHER_THREAD_CONTEXT *ctx);
2260
2261
2262 //
2263 // search.c
2264 //
2265 #define QPLIES_OF_NON_CAPTURE_CHECKS (1)
2266 #define FUTILITY_BASE_MARGIN         (50) // + ctx->uPositional (min 100)
2267 #define DO_IID
2268 #define IID_R_FACTOR                 (TWO_PLY + HALF_PLY)
2269
2270 #ifndef MP
2271 #define WE_SHOULD_STOP_SEARCHING (g_MoveTimer.bvFlags & TIMER_STOPPING)
2272 #else
2273 #define WE_SHOULD_STOP_SEARCHING ((g_MoveTimer.bvFlags & TIMER_STOPPING) || \
2274                                   (ThreadUnderTerminatingSplit(ctx)))
2275 #endif
2276
2277 SCORE FASTCALL
2278 QSearch(SEARCHER_THREAD_CONTEXT *ctx,
2279         SCORE iAlpha,
2280         SCORE iBeta);
2281
2282 SCORE FASTCALL
2283 Search(SEARCHER_THREAD_CONTEXT *ctx,
2284        SCORE iAlpha,
2285        SCORE iBeta,
2286        ULONG uDepth);
2287
2288
2289 //
2290 // searchsup.c
2291 //
2292 SCORE
2293 ComputeMoveScore(IN SEARCHER_THREAD_CONTEXT *ctx,
2294                  IN MOVE mv,
2295                  IN ULONG uMoveNum);
2296
2297 FLAG
2298 ThreadUnderTerminatingSplit(SEARCHER_THREAD_CONTEXT *);
2299
2300 FLAG
2301 WeShouldDoHistoryPruning(IN SCORE iRoughEval,
2302                          IN SCORE iAlpha,
2303                          IN SCORE iBeta,
2304                          IN SEARCHER_THREAD_CONTEXT *ctx,
2305                          IN ULONG uRemainingDepth,
2306                          IN ULONG uLegalMoves,
2307                          IN MOVE mv,
2308                          IN ULONG uMoveNum,
2309                          IN INT iExtend);
2310
2311 FLAG
2312 WeShouldTryNullmovePruning(IN SEARCHER_THREAD_CONTEXT *ctx,
2313                            IN SCORE iAlpha,
2314                            IN SCORE iBeta,
2315                            IN SCORE iRoughEval,
2316                            IN ULONG uNullDepth);
2317
2318 FLAG
2319 TryNullmovePruning(IN OUT SEARCHER_THREAD_CONTEXT *ctx,
2320                    IN OUT FLAG *pfThreat,
2321                    IN SCORE iAlpha,
2322                    IN SCORE iBeta,
2323                    IN ULONG uNullDepth,
2324                    IN OUT INT *piOrigExtend,
2325                    OUT SCORE *piNullScore);
2326
2327 void
2328 UpdatePV(SEARCHER_THREAD_CONTEXT *ctx, MOVE mv);
2329
2330 FLAG
2331 CheckInputAndTimers(IN SEARCHER_THREAD_CONTEXT *ctx);
2332
2333 void
2334 ComputeReactionToCheckExtension(IN OUT SEARCHER_THREAD_CONTEXT *ctx,
2335                                 IN ULONG uGenFlags,
2336                                 IN ULONG uMoveNum,
2337                                 IN SCORE iRoughEval,
2338                                 IN SCORE iAlpha,
2339                                 IN OUT INT *piExtend,
2340                                 IN OUT INT *piOrigExtend);
2341
2342 void
2343 ComputeMoveExtension(IN OUT SEARCHER_THREAD_CONTEXT *ctx,
2344                      IN SCORE iAlpha,
2345                      IN SCORE iBeta,
2346                      IN ULONG uMoveNum,
2347                      IN SCORE iRoughEval,
2348                      IN ULONG uDepth,
2349                      IN OUT INT *piExtend);
2350
2351 SCORE
2352 RescoreMovesViaSearch(IN SEARCHER_THREAD_CONTEXT *ctx,
2353                       IN ULONG uDepth,
2354                       IN SCORE iAlpha,
2355                       IN SCORE iBeta);
2356
2357 FLAG
2358 MateDistancePruningCutoff(IN ULONG uPly,
2359                           IN FLAG fInCheck,
2360                           IN OUT SCORE *piBestScore,
2361                           IN OUT SCORE *piAlpha,
2362                           IN OUT SCORE *piBeta);
2363
2364 FLAG
2365 CommonSearchInit(IN SEARCHER_THREAD_CONTEXT *ctx,
2366                  IN OUT SCORE *piAlpha,
2367                  IN OUT SCORE *piBeta,
2368                  IN OUT SCORE *piScore);
2369
2370 ULONG
2371 SelectNullmoveRFactor(IN SEARCHER_THREAD_CONTEXT *ctx,
2372                       IN INT uDepth);
2373
2374 #define VERIFY_BEFORE (1)
2375 #define VERIFY_AFTER  (2)
2376
2377 FLAG
2378 SanityCheckMoves(IN SEARCHER_THREAD_CONTEXT *ctx,
2379                  IN ULONG uCurrent,
2380                  IN ULONG uType);
2381
2382
2383 //
2384 // testsearch.c
2385 //
2386 FLAG
2387 TestSearch(void);
2388
2389 //
2390 // see.c
2391 //
2392 #define SEE_HEAPS
2393
2394 SCORE
2395 SEE(POSITION *pos,
2396     MOVE mv);
2397
2398 typedef struct _SEE_THREESOME
2399 {
2400     PIECE pPiece;
2401     COOR cLoc;
2402     ULONG uVal;
2403 } SEE_THREESOME;
2404
2405 typedef struct _SEE_LIST
2406 {
2407     ULONG uCount;
2408     SEE_THREESOME data[16];
2409 }
2410 SEE_LIST;
2411
2412 SCORE
2413 ControlsSquareMinusPiece(ULONG uSide,
2414                          POSITION *pos,
2415                          COOR c,
2416                          COOR cIgnore);
2417
2418 //
2419 // testsee.c
2420 //
2421 SCORE
2422 DebugSEE(POSITION *pos,
2423          MOVE mv);
2424
2425 void
2426 TestGetAttacks(void);
2427
2428 //
2429 // hash.c
2430 //
2431 #define NUM_HASH_ENTRIES_PER_LINE     4
2432 #define HASH_FLAG_EXACT               0x1
2433 #define HASH_FLAG_LOWER               0x2
2434 #define HASH_FLAG_UPPER               0x4
2435 #define HASH_FLAG_VALID_BOUNDS        0x7
2436 #define HASH_FLAG_THREAT              0x8
2437 #define HASH_FLAG_DIRTY               0xF0
2438
2439 typedef struct _HASH_ENTRY
2440 {
2441     MOVE mv;                         // 0 1 2 3
2442     UCHAR uDepth;                    // 4
2443     UCHAR bvFlags;                   // 5 ==> d  d  d  d | thr up low exact
2444     signed short iValue;             // 6 7
2445     UINT64 u64Sig;                   // 8 9 A B C D E F == 16 bytes
2446 } HASH_ENTRY;
2447
2448 FLAG
2449 InitializeHashSystem(void);
2450
2451 void
2452 CleanupHashSystem(void);
2453
2454 void
2455 ClearHashTable(void);
2456
2457 void
2458 DirtyHashTable(void);
2459
2460 void
2461 StoreLowerBound(MOVE mvBestMove,
2462            POSITION *pos,
2463            SCORE iValue,
2464            ULONG uDepth,
2465            FLAG fThreat);
2466 void
2467 StoreExactScore(MOVE mvBestMove,
2468             POSITION *pos,
2469           SCORE iValue,
2470           ULONG uDepth,
2471           FLAG fThreat,
2472           ULONG uPly);
2473
2474 void
2475 StoreUpperBound(//MOVE mvBestMove,
2476            POSITION *pos,
2477            SCORE iValue,
2478            ULONG uDepth,
2479            FLAG fThreat);
2480
2481 HASH_ENTRY *
2482 HashLookup(SEARCHER_THREAD_CONTEXT *ctx,
2483            ULONG uDepth,
2484            ULONG uNextDepth,
2485            SCORE iAlpha,
2486            SCORE iBeta,
2487            FLAG *pfThreat,
2488            FLAG *pfAvoidNull,
2489            MOVE *pHashMove,
2490            SCORE *piScore);
2491
2492 COOR
2493 CheckHashForDangerSquare(POSITION *pos);
2494
2495 MOVE
2496 GetPonderMove(POSITION *pos);
2497
2498 extern ULONG g_uHashTableSizeEntries;
2499 extern ULONG g_uHashTableSizeBytes;
2500 extern HASH_ENTRY *g_pHashTable;
2501
2502 //
2503 // testhash.c
2504 //
2505 void
2506 AnalyzeFullHashTable(void);
2507
2508 //
2509 // positionhash.c
2510 //
2511 // IDEA: store "mate threat" flag in here?
2512 // IDEA: store "king safety" numbers in here?
2513 //
2514 typedef struct _POSITION_HASH_ENTRY {
2515     UINT64 u64Sig;
2516     UCHAR cEnprise[2];
2517     UCHAR uEnpriseCount[2];
2518     UCHAR cTrapped[2];
2519 } POSITION_HASH_ENTRY;
2520
2521 void
2522 InitializePositionHashSystem(void);
2523
2524 void
2525 CleanupPositionHashSystem(void);
2526
2527 void
2528 StoreEnprisePiece(POSITION *pos, COOR cSquare);
2529
2530 void
2531 StoreTrappedPiece(POSITION *pos, COOR cSquare);
2532
2533 COOR
2534 GetEnprisePiece(POSITION *pos, ULONG uSide);
2535
2536 ULONG
2537 GetEnpriseCount(POSITION *pos, ULONG uSide);
2538
2539 COOR
2540 GetTrappedPiece(POSITION *pos, ULONG uSide);
2541
2542 FLAG
2543 SideCanStandPat(POSITION *pos, ULONG uSide);
2544
2545 ULONG
2546 ValueOfMaterialInTroubleDespiteMove(POSITION *pos, ULONG uSide);
2547
2548 ULONG
2549 ValueOfMaterialInTroubleAfterNull(POSITION *pos, ULONG uSide);
2550
2551 //
2552 // pawnhash.c
2553 //
2554 #define COOR_TO_BIT(x)       ((x) & 0x7) + ((0x7 - ((x) >> 4)) << 3)
2555
2556 void
2557 ClearPawnHashStats(void);
2558
2559 void
2560 ReportPawnHashStats(void);
2561
2562 PAWN_HASH_ENTRY *
2563 PawnHashLookup(SEARCHER_THREAD_CONTEXT *ctx);
2564
2565 //
2566 // eval.c
2567 //
2568 #define LAZY_EVAL
2569 #define LAZE_EVAL_BASE_SCORE 10
2570 extern const int g_iAhead[2];
2571 extern const int g_iBehind[2];
2572
2573 ULONG 
2574 DNABufferSizeBytes();
2575
2576 char *
2577 ExportEvalDNA();
2578
2579 FLAG
2580 WriteEvalDNA(char *szFilename);
2581
2582 FLAG
2583 ImportEvalDNA(char *p);
2584
2585 FLAG
2586 ReadEvalDNA(char *szFilename);
2587
2588
2589
2590 SCORE
2591 Eval(SEARCHER_THREAD_CONTEXT *, SCORE, SCORE);
2592
2593 FLAG
2594 EvalPasserRaces(POSITION *,
2595                 PAWN_HASH_ENTRY *);
2596
2597 ULONG
2598 CountKingSafetyDefects(POSITION *pos,
2599                        ULONG uSide);
2600
2601 //
2602 // testeval.c
2603 //
2604 #ifdef EVAL_DUMP
2605 void
2606 TestEval(void);
2607
2608 void
2609 EvalTraceReport(void);
2610
2611 void
2612 EvalTrace(ULONG uColor, PIECE p, COOR c, SCORE iVal, CHAR *szMessage);
2613
2614 SCORE
2615 EvalSigmaForPiece(POSITION *pos, COOR c);
2616
2617 void
2618 EvalTraceClear(void);
2619
2620 void
2621 TestEvalWithSymmetry(void);
2622
2623 #define EVAL_TERM(COL, PIE, COO, VAL, ADJ, MESS) \
2624     (VAL) += (ADJ); \
2625     EvalTrace((COL), (PIE), (COO), (ADJ), (MESS));
2626 #else
2627 #define EVAL_TERM(COL, PIE, COO, VAL, ADJ, MESS) \
2628     (VAL) += (ADJ);
2629 #endif
2630
2631 //
2632 // bitboard.c
2633 //
2634 void
2635 InitializeBitboards(void);
2636
2637 ULONG CDECL
2638 SlowCountBits(BITBOARD bb);
2639
2640 ULONG CDECL
2641 DeBruijnFirstBit(BITBOARD bb);
2642
2643 ULONG CDECL
2644 SlowFirstBit(BITBOARD bb);
2645
2646 ULONG CDECL
2647 SlowLastBit(BITBOARD bb);
2648
2649 COOR
2650 CoorFromBitBoardRank8ToRank1(BITBOARD *pbb);
2651
2652 COOR
2653 CoorFromBitBoardRank1ToRank8(BITBOARD *pbb);
2654
2655 //
2656 // x86.asm
2657 //
2658 ULONG CDECL
2659 CountBits(BITBOARD bb);
2660
2661 ULONG CDECL
2662 FirstBit(BITBOARD bb);
2663
2664 ULONG CDECL
2665 LastBit(BITBOARD bb);
2666
2667 ULONG CDECL
2668 LockCompareExchange(volatile void *pDest,
2669                     ULONG uExch,
2670                     ULONG uComp);
2671
2672 ULONG CDECL
2673 LockIncrement(volatile void *pDest);
2674
2675 ULONG CDECL
2676 LockDecrement(volatile void *pDest);
2677
2678 FLAG CDECL
2679 CanUseParallelOpcodes();
2680
2681 ULONG CDECL
2682 ParallelCompareUlong(ULONG uComparand, void *pComparators);
2683
2684 ULONG CDECL
2685 ParallelCompareVector(void *pComparand, void *pComparators);
2686
2687 void CDECL
2688 GetAttacks(SEE_LIST *pList,
2689            POSITION *pos,
2690            COOR cSquare,
2691            ULONG uSide);
2692
2693 void CDECL
2694 SlowGetAttacks(SEE_LIST *pList,
2695                POSITION *pos,
2696                COOR cSquare,
2697                ULONG uSide);
2698
2699 #ifdef _X86_
2700 //
2701 // Note: this is most of the stuff that x86.asm assumes about the
2702 // internal data structures.  If any of this fails then either the
2703 // assembly language code needs to be updated or you need to use the C
2704 // version of the routine in see.c instead.
2705 //
2706 #define ASSERT_ASM_ASSUMPTIONS \
2707     ASSERT(VALUE_PAWN == 100); \
2708     ASSERT(OFFSET_OF(uCount, SEE_LIST) == 0); \
2709     ASSERT(OFFSET_OF(data, SEE_LIST) == 4); \
2710     ASSERT(sizeof(SEE_THREESOME) == 12); \
2711     ASSERT(OFFSET_OF(pPiece, SEE_THREESOME) == 0); \
2712     ASSERT(OFFSET_OF(cLoc, SEE_THREESOME) == 4); \
2713     ASSERT(OFFSET_OF(uVal, SEE_THREESOME) == 8); \
2714     ASSERT(OFFSET_OF(cNonPawns, POSITION) == 0x478); \
2715     ASSERT(OFFSET_OF(uNonPawnCount, POSITION) == 0x500); \
2716     ASSERT(OFFSET_OF(rgSquare, POSITION) == 0); \
2717     ASSERT(sizeof(SQUARE) == 8); \
2718     ASSERT(sizeof(VECTOR_DELTA) == 4); \
2719     ASSERT(sizeof(g_VectorDelta) == 256 * 4); \
2720     ASSERT(OFFSET_OF(iVector, VECTOR_DELTA) == 0); \
2721     ASSERT(OFFSET_OF(iDelta, VECTOR_DELTA) == 2); \
2722     ASSERT(OFFSET_OF(iNegDelta, VECTOR_DELTA) == 3); \
2723     ASSERT(sizeof(g_PieceData) == 8 * 4 * 4); \
2724     ASSERT(OFFSET_OF(uValue, PIECE_DATA) == 0);
2725 #else
2726 #define ASSERT_ASM_ASSUMPTIONS
2727 #endif
2728
2729 //
2730 // testbitboard.c
2731 //
2732 void
2733 TestBitboards(void);
2734
2735 //
2736 // dynamic.c
2737 //
2738 extern ULONG g_HistoryCounters[14][128];
2739
2740 ULONG
2741 GetMoveFailHighPercentage(MOVE mv);
2742
2743 void
2744 UpdateDynamicMoveOrdering(SEARCHER_THREAD_CONTEXT *ctx,
2745                           ULONG uRemainingDepth,
2746                           MOVE mvBest,
2747                           SCORE iScore,
2748                           ULONG uCurrent);
2749
2750 void
2751 NewKillerMove(SEARCHER_THREAD_CONTEXT *ctx, MOVE mv, SCORE iScore);
2752
2753 FLAG
2754 InitializeDynamicMoveOrdering(void);
2755
2756 void
2757 CleanupDynamicMoveOrdering(void);
2758
2759 void
2760 ClearDynamicMoveOrdering(void);
2761
2762 void
2763 MaintainDynamicMoveOrdering(void);
2764
2765 void
2766 IncrementMoveHistoryCounter(MOVE mv, ULONG u);
2767
2768 void
2769 DecrementMoveHistoryCounter(MOVE mv, ULONG u);
2770
2771 //
2772 // split.c
2773 //
2774 extern volatile ULONG g_uNumHelpersAvailable;
2775 extern ULONG g_uNumHelperThreads;
2776
2777 FLAG
2778 InitializeParallelSearch(void);
2779
2780 FLAG
2781 CleanupParallelSearch(void);
2782
2783 void
2784 ClearHelperThreadIdleness(void);
2785
2786 void
2787 DumpHelperIdlenessReport(void);
2788
2789 SCORE
2790 StartParallelSearch(IN SEARCHER_THREAD_CONTEXT *ctx,
2791                     IN OUT SCORE *piAlpha,
2792                     IN SCORE iBeta,
2793                     IN OUT SCORE *piBestScore,
2794                     IN OUT MOVE *pmvBest,
2795                     IN ULONG uMoveNum,
2796                     IN INT iPositionExtend,
2797                     IN ULONG uDepth);
2798
2799 void
2800 InitializeSearcherContext(POSITION *pos, SEARCHER_THREAD_CONTEXT *ctx);
2801
2802 void
2803 ReInitializeSearcherContext(POSITION *pos, SEARCHER_THREAD_CONTEXT *ctx);
2804
2805 void
2806 InitializeLightweightSearcherContext(POSITION *pos,
2807                                      LIGHTWEIGHT_SEARCHER_CONTEXT *ctx);
2808
2809 //
2810 // book.c
2811 //
2812
2813 #define BOOK_PROBE_MISS_LIMIT  (7)
2814 #define FLAG_DISABLED          (1)
2815 #define FLAG_ALWAYSPLAY        (2)
2816 #define FLAG_DELETED           (4)
2817
2818 #define BOOKMOVE_SELECT_MOVE   (1)
2819 #define BOOKMOVE_DUMP          (2)
2820
2821 #pragma pack(4)
2822 typedef struct _BOOK_ENTRY
2823 {
2824     UINT64 u64Sig;                            // 8 bytes
2825     UINT64 u64NextSig;                        // 8 bytes
2826     MOVE mvNext;                              // 4 bytes
2827     ULONG uWins;                              // 4 bytes
2828     ULONG uDraws;                             // 4 bytes
2829     ULONG uLosses;                            // 4 bytes
2830     BITV bvFlags;                             // 4 bytes
2831 }
2832 BOOK_ENTRY;
2833 #pragma pack()
2834
2835 typedef struct _OPENING_NAME_MAPPING
2836 {
2837     UINT64 u64Sig;
2838     CHAR *szString;
2839 }
2840 OPENING_NAME_MAPPING;
2841
2842 #define BOOK_EDITING_RECORD       "bkedit.edt"
2843 #define OPENING_LEARNING_FILENAME "bklearn.bin"
2844
2845 typedef struct _OPENING_LEARNING_ENTRY
2846 {
2847     UINT64 u64Sig;
2848     ULONG uWhiteWins;
2849     ULONG uDraws;
2850     ULONG uBlackWins;
2851 }
2852 OPENING_LEARNING_ENTRY;
2853
2854 FLAG
2855 InitializeOpeningBook(void);
2856
2857 void
2858 ResetOpeningBook(void);
2859
2860 void
2861 CleanupOpeningBook(void);
2862
2863 MOVE
2864 BookMove(POSITION *pos,
2865          BITV bvFlags);
2866
2867 COMMAND(BookCommand);
2868
2869 extern ULONG g_uBookProbeFailures;
2870 extern FLAG g_fTournamentMode;
2871 extern CHAR *g_szBookName;
2872
2873 //
2874 // bench.c
2875 //
2876 COMMAND(BenchCommand);
2877
2878 //
2879 // testdraw.c
2880 //
2881 void
2882 TestDraw(void);
2883
2884 //
2885 // probe.c
2886 //
2887 FLAG
2888 ProbeEGTB(SEARCHER_THREAD_CONTEXT *ctx, SCORE *score);
2889
2890 void
2891 InitializeEGTB(void);
2892
2893 void
2894 CleanupEGTB(void);
2895
2896 //
2897 // dumptree.c
2898 //
2899 #ifdef DUMP_TREE
2900
2901 void
2902 InitializeTreeDump(void);
2903
2904 void
2905 CleanupTreeDump(void);
2906
2907 void
2908 DTEnterNode(SEARCHER_THREAD_CONTEXT *ctx,
2909             ULONG uDepth,
2910             FLAG fIsQNode,
2911             SCORE iAlpha,
2912             SCORE iBeta);
2913
2914 void
2915 DTLeaveNode(SEARCHER_THREAD_CONTEXT *ctx,
2916             FLAG fQNode,
2917             SCORE iBestScore,
2918             MOVE mvBestMove);
2919
2920 void CDECL
2921 DTTrace(ULONG uPly, CHAR *szMessage, ...);
2922
2923 #define DTTRACE(...) DTTrace(ctx->uPly, __VA_ARGS__)
2924
2925 #else
2926
2927 #define DTTRACE(...)
2928
2929 #define DTEnterNode(...)
2930
2931 #define DTLeaveNode(...)
2932
2933 #define InitializeTreeDump(...)
2934
2935 #define CleanupTreeDump(...)
2936
2937 #endif
2938
2939 //
2940 // testsup.c
2941 //
2942 FLAG
2943 IsBoardLegal(POSITION *pos);
2944
2945 void
2946 GenerateRandomLegalPosition(POSITION *pos);
2947
2948 void
2949 GenerateRandomLegalSymetricPosition(POSITION *pos);
2950
2951 //
2952 // recogn.c
2953 //
2954 #define UNRECOGNIZED (0)
2955 #define RECOGN_EXACT (1)
2956 #define RECOGN_UPPER (2)
2957 #define RECOGN_LOWER (3)
2958 #define RECOGN_EGTB  (4)
2959
2960 void
2961 InitializeInteriorNodeRecognizers(void);
2962
2963 ULONG
2964 RecognLookup(SEARCHER_THREAD_CONTEXT *ctx,
2965              SCORE *piScore,
2966              FLAG fProbeEGTB);
2967
2968 #ifdef EVAL_HASH
2969 void
2970 ClearEvalHashStats(void);
2971
2972 void
2973 ReportEvalHashStats(void);
2974
2975 SCORE
2976 ProbeEvalHash(SEARCHER_THREAD_CONTEXT *ctx);
2977
2978 SCORE
2979 GetRoughEvalScore(IN SEARCHER_THREAD_CONTEXT *ctx,
2980                   IN SCORE iAlpha,
2981                   IN SCORE iBeta,
2982                   IN FLAG fUseHash);
2983
2984 void
2985 StoreEvalHash(SEARCHER_THREAD_CONTEXT *ctx, SCORE iScore);
2986 #endif // EVAL_HASH
2987
2988 #endif // CHESS