Update codebase to remove clang warnings (and a couple of legit errors
[typhoon.git] / src / chess.h
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 354 2008-06-30 05:10:08Z 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 354 2008-06-30 05:10:08Z 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     UINT64 u64MaxNodeCount;
1039     FLAG fShouldPonder;
1040     FLAG fPondering;
1041     FLAG fThinking;
1042     FLAG fSuccessfulPonder;
1043     MOVE mvPonder;
1044     FLAG fShouldPost;
1045     FLAG fForceDrawWorthZero;
1046     ULONG uMyIncrement;
1047     ULONG uMovesPerTimePeriod;
1048     CHAR szAnalyzeProgressReport[SMALL_STRING_LEN_CHAR];
1049     FLAG fShouldAnnounceOpening;
1050     SCORE iLastEvalScore;
1051     UINT64 u64NodesSearched;
1052     CHAR szLogfile[SMALL_STRING_LEN_CHAR];
1053     CHAR szEGTBPath[SMALL_STRING_LEN_CHAR];
1054     CHAR szBookName[SMALL_STRING_LEN_CHAR];
1055     ULONG uNumProcessors;
1056     ULONG uNumHashTableEntries;
1057     FLAG fNoInputThread;
1058     FLAG fVerbosePosting;
1059     FLAG fRunningUnderXboard;
1060     FLAG fStatusLine;
1061     FLAG fFastScript;
1062     INT iResignThreshold;
1063
1064     enum
1065     {
1066         CLOCK_NORMAL               = 0,
1067         CLOCK_FIXED,
1068         CLOCK_INCREMENT,
1069         CLOCK_NONE
1070     }
1071     eClock;
1072
1073     enum
1074     {
1075         GAME_UNKNOWN               = 0,
1076         GAME_BULLET,
1077         GAME_BLITZ,
1078         GAME_STANDARD
1079     }
1080     eGameType;
1081
1082     enum
1083     {
1084         I_PLAY_WHITE               = 0,
1085         I_PLAY_BLACK,
1086         FORCE_MODE,
1087         EDIT_MODE,
1088         ANALYZE_MODE
1089     }
1090     ePlayMode;
1091 }
1092 GAME_OPTIONS;
1093 extern GAME_OPTIONS g_Options;
1094
1095 // ----------------------------------------------------------------------
1096 //
1097 // Move timer
1098 //
1099
1100 #define TIMER_SEARCHING_FIRST_MOVE       (0x1)
1101 #define TIMER_SEARCHING_IMPORTANT_MOVE   (0x2)
1102 #define TIMER_RESOLVING_ROOT_FL          (0x4)
1103 #define TIMER_RESOLVING_ROOT_FH          (0x8)
1104 #define TIMER_JUST_OUT_OF_BOOK           (0x10)
1105 #define TIMER_CURRENT_OBVIOUS            (0x20)
1106 #define TIMER_CURRENT_WONT_UNBLOCK       (0x40)
1107 #define TIMER_ROOT_POSITION_CRITICAL     (0x80)
1108 #define TIMER_MOVE_IMMEDIATELY           (0x100)
1109 #define TIMER_MANY_ROOT_FLS              (0x200)
1110 #define TIMER_STOPPING                   (0x400)
1111 #define TIMER_SPLIT_FAILED               (0x800)
1112
1113 typedef struct _MOVE_TIMER
1114 {
1115     double dStartTime;
1116     double dEndTime;
1117     double dSoftTimeLimit;
1118     double dHardTimeLimit;
1119     ULONG uNodeCheckMask;
1120     volatile BITV bvFlags;
1121 }
1122 MOVE_TIMER;
1123
1124 // ----------------------------------------------------------------------
1125 //
1126 // Special move tag literals
1127 //
1128 #define ILLEGALMOVE                ((ULONG)0x1DDD8888)
1129
1130 //
1131 // useful macros
1132 //
1133 #ifdef DEBUG
1134 void
1135 _assert(CHAR *szFile, ULONG uLine);
1136
1137 #define ASSERT(x)                  if (x)    \
1138                                    { ; }     \
1139                                    else      \
1140                                    { _assert(__FILE__, __LINE__); }
1141 #define VERIFY(x)                  ASSERT(x)
1142 #else
1143 #define ASSERT(x)                   ;
1144 #define VERIFY(x)                  x;
1145 #endif // DEBUG
1146
1147 #ifdef PERF_COUNTERS
1148 #define INC(x)                     ((x) += 1)
1149 #else
1150 #define INC(x)
1151 #endif
1152
1153 #define BREAKPOINT                 SystemDebugBreakpoint()
1154
1155 #define MIN(x, y)                  (((x) < (y)) ? (x) : (y))
1156 #define MAX(x, y)                  (((x) > (y)) ? (x) : (y))
1157
1158 #ifdef _X86_
1159 //
1160 // Note: MAXU, MINU and ABS_DIFF require arguments with the high order
1161 // bit CLEAR to work right.
1162 //
1163 // These are branchless constructs.  MAXU and MINU are equivalent to
1164 // MIN and MAX (with the above restriction on inputs)
1165 //
1166 // MIN0 and MAX0 are equivalent to MAX(0, x) and MIN(0, x).  These
1167 // macros have no restiction on argument type.
1168 //
1169 // ABS_DIFF is equivalent to abs(x - y).  Again, x and y must have
1170 // their high-order bits CLEAR for this to work.
1171 //
1172 // Note: gcc generates code with cmovs so no need for MAXU/MINU on
1173 // that compiler.
1174 //
1175 #define MINU(x, y)                 \
1176     (((((int)((x)-(y)))>>31) & ((x)-(y)))+(y))
1177 #define MAXU(x, y)                 \
1178     (((((int)((x)-(y)))>>31) & ((y)-(x)))+(x))
1179 #define MIN0(x)                    \
1180     ((x) & (((int)(x)) >> 31))
1181 #define MAX0(x)                    \
1182     ((x) & ~(((int)(x)) >> 31))
1183
1184
1185 #define ABS_DIFF(a, b)             \
1186     (((b)-(a)) - ((((b) - (a)) & (((int)((b) - (a))) >> 31) ) << 1))
1187
1188 #endif // _X86_
1189
1190 #ifndef MINU
1191 #define MINU(x, y)                 (MIN((x), (y)))
1192 #endif
1193
1194 #ifndef MAXU
1195 #define MAXU(x, y)                 (MAX((x), (y)))
1196 #endif
1197
1198 #ifndef MIN0
1199 #define MIN0(x)                    (MIN((x), 0))
1200 #endif
1201
1202 #ifndef MAX0
1203 #define MAX0(x)                    (MAX((x), 0))
1204 #endif
1205
1206 #ifndef ABS_DIFF
1207 #define ABS_DIFF(a, b)             (abs((a) - (b)))
1208 #endif
1209
1210 #define FILE_DISTANCE(a, b)        (ABS_DIFF(FILE((a)), FILE((b))))
1211 #define RANK_DISTANCE(a, b)        (ABS_DIFF(((a) & 0xF0), ((b) & 0xF0)) >> 4)
1212 #define REAL_DISTANCE(a, b)        (MAXU(FILE_DISTANCE((a), (b)), \
1213                                          RANK_DISTANCE((a), (b))))
1214 #ifdef DEBUG
1215 #define DISTANCE(a, b)             DistanceBetweenSquares((a), (b))
1216 #else
1217 #define DISTANCE(a, b)             g_pDistance[(a) - (b)]
1218 #endif // DEBUG
1219
1220 #define    IS_EMPTY( square )      (!(square))
1221 #define IS_OCCUPIED( square )      ((square))
1222
1223 #define IS_DEAD( listindex )       ((listindex) > 119)
1224 #define IS_ALIVE( listindex )      ((listindex) <= 119)
1225 #define ILLEGAL_COOR               (0x88)
1226 #define EDGE_DISTANCE(c)           (MIN(MIN(abs(RANK(c) - 7), RANK(c)), \
1227                                         MIN(abs(FILE(c) - 7), FILE(c))))
1228 #define NOT_ON_EDGE(c)             ((((c) & 0xF0) != 0x00) && \
1229                                        (((c) & 0xF0) != 0x70) && \
1230                                        (((c) & 0x0F) != 0x00) && \
1231                                        (((c) & 0x0F) != 0x07))
1232 #define ON_EDGE(c)                 (RANK8(c) || \
1233                                     RANK1(c) || \
1234                                     FILEA(c) || \
1235                                     FILEH(c))
1236 #define CORNER_DISTANCE(c)         (MAX(MIN((ULONG)(RANK(c) - 7), RANK(c)),\
1237                                         MIN((ULONG)(FILE(c) - 7), FILE(c))))
1238 #define IN_CORNER(c)               (((c) == A8) || \
1239                                        ((c) == A1) || \
1240                                        ((c) == H8) || \
1241                                        ((c) == H1))
1242 #define WHITE_CORNER_DISTANCE(c)   (MIN(DISTANCE((c), A8), \
1243                                         DISTANCE((c), H1)))
1244 #define BLACK_CORNER_DISTANCE(c)   (MIN(DISTANCE((c), H8), \
1245                                         DISTANCE((c), A1)))
1246 #define SYM_SQ(c)                  ((7 - (((c) & 0xF0) >> 4)) << 4) \
1247                                        | (7 - ((c) & 0x0F))
1248 #define ARRAY_SIZE(a)              (sizeof((a)) / sizeof((a[0])))
1249 #define MAKE_PSQT(a, b, c, d)      (((a) << 24) | ((b) << 16) | \
1250                                        ((c) << 8) | (d))
1251 #define TO64(x)                    ((x) & 0x7) + ((0x7 - ((x)>>4)) << 3)
1252 #define COOR_TO_BIT_NUMBER(c)      (((((c) & 0x70) >> 1) | ((c) & 0x7)))
1253 #define SLOWCOOR_TO_BB(c)          (1ULL << COOR_TO_BIT_NUMBER(c))
1254 #define COOR_TO_BB(c)              (BBSQUARE[COOR_TO_BIT_NUMBER(c)])
1255 #define SLOW_BIT_NUMBER_TO_COOR(b) ((((b) / 8) << 4) + ((b) & 7))
1256 #define BIT_NUMBER_TO_COOR(b)      ((((b) & 0xF8) << 1) | ((b) & 7))
1257
1258 #define BBRANK88 \
1259     SLOWCOOR_TO_BB(A8) | SLOWCOOR_TO_BB(B8) | SLOWCOOR_TO_BB(C8) | \
1260     SLOWCOOR_TO_BB(D8) | SLOWCOOR_TO_BB(E8) | SLOWCOOR_TO_BB(F8) | \
1261     SLOWCOOR_TO_BB(G8) | SLOWCOOR_TO_BB(H8)
1262
1263 #define BBRANK77 \
1264     SLOWCOOR_TO_BB(A7) | SLOWCOOR_TO_BB(B7) | SLOWCOOR_TO_BB(C7) | \
1265     SLOWCOOR_TO_BB(D7) | SLOWCOOR_TO_BB(E7) | SLOWCOOR_TO_BB(F7) | \
1266     SLOWCOOR_TO_BB(G7) | SLOWCOOR_TO_BB(H7)
1267
1268 #define BBRANK66 \
1269     SLOWCOOR_TO_BB(A6) | SLOWCOOR_TO_BB(B6) | SLOWCOOR_TO_BB(C6) | \
1270     SLOWCOOR_TO_BB(D6) | SLOWCOOR_TO_BB(E6) | SLOWCOOR_TO_BB(F6) | \
1271     SLOWCOOR_TO_BB(G6) | SLOWCOOR_TO_BB(H6)
1272
1273 #define BBRANK55 \
1274     SLOWCOOR_TO_BB(A5) | SLOWCOOR_TO_BB(B5) | SLOWCOOR_TO_BB(C5) | \
1275     SLOWCOOR_TO_BB(D5) | SLOWCOOR_TO_BB(E5) | SLOWCOOR_TO_BB(F5) | \
1276     SLOWCOOR_TO_BB(G5) | SLOWCOOR_TO_BB(H5)
1277
1278 #define BBRANK44 \
1279     SLOWCOOR_TO_BB(A4) | SLOWCOOR_TO_BB(B4) | SLOWCOOR_TO_BB(C4) | \
1280     SLOWCOOR_TO_BB(D4) | SLOWCOOR_TO_BB(E4) | SLOWCOOR_TO_BB(F4) | \
1281     SLOWCOOR_TO_BB(G4) | SLOWCOOR_TO_BB(H4)
1282
1283 #define BBRANK33 \
1284     SLOWCOOR_TO_BB(A3) | SLOWCOOR_TO_BB(B3) | SLOWCOOR_TO_BB(C3) | \
1285     SLOWCOOR_TO_BB(D3) | SLOWCOOR_TO_BB(E3) | SLOWCOOR_TO_BB(F3) | \
1286     SLOWCOOR_TO_BB(G3) | SLOWCOOR_TO_BB(H3)
1287
1288 #define BBRANK22 \
1289     SLOWCOOR_TO_BB(A2) | SLOWCOOR_TO_BB(B2) | SLOWCOOR_TO_BB(C2) | \
1290     SLOWCOOR_TO_BB(D2) | SLOWCOOR_TO_BB(E2) | SLOWCOOR_TO_BB(F2) | \
1291     SLOWCOOR_TO_BB(G2) | SLOWCOOR_TO_BB(H2)
1292
1293 #define BBRANK11 \
1294     SLOWCOOR_TO_BB(A1) | SLOWCOOR_TO_BB(B1) | SLOWCOOR_TO_BB(C1) | \
1295     SLOWCOOR_TO_BB(D1) | SLOWCOOR_TO_BB(E1) | SLOWCOOR_TO_BB(F1) | \
1296     SLOWCOOR_TO_BB(G1) | SLOWCOOR_TO_BB(H1)
1297
1298 #define BBFILEA \
1299     SLOWCOOR_TO_BB(A1) | SLOWCOOR_TO_BB(A2) | SLOWCOOR_TO_BB(A3) | \
1300     SLOWCOOR_TO_BB(A4) | SLOWCOOR_TO_BB(A5) | SLOWCOOR_TO_BB(A6) | \
1301     SLOWCOOR_TO_BB(A7) | SLOWCOOR_TO_BB(A8)
1302
1303 #define BBFILEB \
1304     SLOWCOOR_TO_BB(B1) | SLOWCOOR_TO_BB(B2) | SLOWCOOR_TO_BB(B3) | \
1305     SLOWCOOR_TO_BB(B4) | SLOWCOOR_TO_BB(B5) | SLOWCOOR_TO_BB(B6) | \
1306     SLOWCOOR_TO_BB(B7) | SLOWCOOR_TO_BB(B8)
1307
1308 #define BBFILEC \
1309     SLOWCOOR_TO_BB(C1) | SLOWCOOR_TO_BB(C2) | SLOWCOOR_TO_BB(C3) | \
1310     SLOWCOOR_TO_BB(C4) | SLOWCOOR_TO_BB(C5) | SLOWCOOR_TO_BB(C6) | \
1311     SLOWCOOR_TO_BB(C7) | SLOWCOOR_TO_BB(C8)
1312
1313 #define BBFILED \
1314     SLOWCOOR_TO_BB(D1) | SLOWCOOR_TO_BB(D2) | SLOWCOOR_TO_BB(D3) | \
1315     SLOWCOOR_TO_BB(D4) | SLOWCOOR_TO_BB(D5) | SLOWCOOR_TO_BB(D6) | \
1316     SLOWCOOR_TO_BB(D7) | SLOWCOOR_TO_BB(D8)
1317
1318 #define BBFILEE \
1319     SLOWCOOR_TO_BB(E1) | SLOWCOOR_TO_BB(E2) | SLOWCOOR_TO_BB(E3) | \
1320     SLOWCOOR_TO_BB(E4) | SLOWCOOR_TO_BB(E5) | SLOWCOOR_TO_BB(E6) | \
1321     SLOWCOOR_TO_BB(E7) | SLOWCOOR_TO_BB(E8)
1322
1323 #define BBFILEF \
1324     SLOWCOOR_TO_BB(F1) | SLOWCOOR_TO_BB(F2) | SLOWCOOR_TO_BB(F3) | \
1325     SLOWCOOR_TO_BB(F4) | SLOWCOOR_TO_BB(F5) | SLOWCOOR_TO_BB(F6) | \
1326     SLOWCOOR_TO_BB(F7) | SLOWCOOR_TO_BB(F8)
1327
1328 #define BBFILEG \
1329     SLOWCOOR_TO_BB(G1) | SLOWCOOR_TO_BB(G2) | SLOWCOOR_TO_BB(G3) | \
1330     SLOWCOOR_TO_BB(G4) | SLOWCOOR_TO_BB(G5) | SLOWCOOR_TO_BB(G6) | \
1331     SLOWCOOR_TO_BB(G7) | SLOWCOOR_TO_BB(G8)
1332
1333 #define BBFILEH \
1334     SLOWCOOR_TO_BB(H1) | SLOWCOOR_TO_BB(H2) | SLOWCOOR_TO_BB(H3) | \
1335     SLOWCOOR_TO_BB(H4) | SLOWCOOR_TO_BB(H5) | SLOWCOOR_TO_BB(H6) | \
1336     SLOWCOOR_TO_BB(H7) | SLOWCOOR_TO_BB(H8)
1337
1338 #define BBRANK72 \
1339     BBRANK77 | BBRANK66 | BBRANK55 | BBRANK44 | BBRANK33 | BBRANK22
1340
1341 #define BBRANK62 \
1342     BBRANK66 | BBRANK55 | BBRANK44 | BBRANK33 | BBRANK22
1343
1344 #define BBRANK52 \
1345     BBRANK55 | BBRANK44 | BBRANK33 | BBRANK22
1346
1347 #define BBRANK42 \
1348     BBRANK44 | BBRANK33 | BBRANK22
1349
1350 #define BBRANK32 \
1351     BBRANK33 | BBRANK22
1352
1353 #define BBRANK27 \
1354     BBRANK22 | BBRANK33 | BBRANK44 | BBRANK55 | BBRANK66 | BBRANK77
1355
1356 #define BBRANK37 \
1357     BBRANK33 | BBRANK44 | BBRANK55 | BBRANK66 | BBRANK77
1358
1359 #define BBRANK47 \
1360     BBRANK44 | BBRANK55 | BBRANK66 | BBRANK77
1361
1362 #define BBRANK57 \
1363     BBRANK55 | BBRANK66 | BBRANK77
1364
1365 #define BBRANK67 \
1366     BBRANK66 | BBRANK77
1367
1368 #include <stdlib.h>
1369 #include <stdio.h>
1370 #include <stdarg.h>
1371 #include <string.h>
1372 #include <ctype.h>
1373 #include <time.h>
1374 #include <sys/types.h>
1375 #include <sys/stat.h>
1376 #include <fcntl.h>
1377
1378 //
1379 // util.c
1380 //
1381 COMMAND(LearnPsqtFromPgn);
1382
1383 COMMAND(GeneratePositionAndBestMoveSuite);
1384
1385 CHAR *
1386 WalkPV(SEARCHER_THREAD_CONTEXT *ctx);
1387
1388 CHAR *
1389 ReadNextGameFromPgnFile(FILE *pf);
1390
1391 COOR
1392 DistanceBetweenSquares(COOR a, COOR b);
1393
1394 void CDECL
1395 Trace(CHAR *szMessage, ...);
1396
1397 void CDECL
1398 Log(CHAR *szMessage, ...);
1399
1400 void CDECL
1401 Bug(CHAR *szMessage, ...);
1402
1403 char *
1404 FindChunk(char *sz, ULONG uTargetChunk);
1405
1406 FLAG
1407 BufferIsZeroed(BYTE *p, ULONG u);
1408
1409 char *
1410 ColorToString(ULONG u);
1411
1412 char *
1413 CoorToString(COOR c);
1414
1415 char *
1416 ScoreToString(SCORE iScore);
1417
1418 char *
1419 TimeToString(double d);
1420
1421 ULONG
1422 AcquireSpinLock(volatile ULONG *pSpinlock);
1423
1424 FLAG
1425 TryAcquireSpinLock(volatile ULONG *pSpinlock);
1426
1427 void
1428 ReleaseSpinLock(volatile ULONG *pSpinLock);
1429
1430 BYTE
1431 Checksum(BYTE *p, ULONG uSize);
1432
1433 FLAG
1434 BackupFile(CHAR *szFile);
1435
1436 void
1437 UtilPrintPV(SEARCHER_THREAD_CONTEXT *ctx,
1438             SCORE iAlpha,
1439             SCORE iBeta,
1440             SCORE iScore,
1441             MOVE mv);
1442
1443 #define CANNOT_INITIALIZE_SPLIT           (1)
1444 #define INCONSISTENT_POSITION             (2)
1445 #define UNEXPECTED_SYSTEM_CALL_FAILURE    (3)
1446 #define SHOULD_NOT_GET_HERE               (4)
1447 #define GOT_ILLEGAL_MOVE_WHILE_PONDERING  (5)
1448 #define CANNOT_OFFICIALLY_MAKE_MOVE       (6)
1449 #define DETECTED_INCORRECT_INITIALIZATION (7)
1450 #define INCONSISTENT_STATE                (8)
1451 #define FATAL_ACCESS_DENIED               (9)
1452 #define TESTCASE_FAILURE                  (10)
1453 #define INITIALIZATION_FAILURE            (11)
1454
1455 void
1456 UtilPanic(ULONG uPanicCode,
1457           POSITION *pos,
1458           void *a1,
1459           void *a2,
1460           void *a3,
1461           char *file, ULONG line);
1462
1463
1464 //
1465 // main.c
1466 //
1467 #define LOGFILE_NAME                "typhoon.log"
1468 extern FILE *g_pfLogfile;
1469
1470 void
1471 Banner(void);
1472
1473 FLAG
1474 PreGameReset(FLAG fResetBoard);
1475
1476 //
1477 // system dependent exports (see win32.c or fbsd.c)
1478 //
1479 typedef ULONG (THREAD_ENTRYPOINT)(ULONG);
1480
1481 #ifdef DEBUG
1482 ULONG
1483 GetHeapMemoryUsage(void);
1484 #endif
1485
1486 void
1487 SystemDebugBreakpoint(void);
1488
1489 CHAR *
1490 SystemStrDup(CHAR *p);
1491
1492 double
1493 SystemTimeStamp(void);
1494
1495 FLAG
1496 SystemDoesFileExist(CHAR *szFilename);
1497
1498 void
1499 SystemDeferExecution(ULONG uMs);
1500
1501 void
1502 SystemFreeMemory(void *pMem);
1503
1504 void *
1505 SystemAllocateMemory(ULONG dwSizeBytes);
1506
1507 FLAG
1508 SystemMakeMemoryReadOnly(void *pMemory, ULONG dwSizeBytes);
1509
1510 FLAG
1511 SystemMakeMemoryNoAccess(void *pMemory, ULONG dwSizeBytes);
1512
1513 FLAG
1514 SystemMakeMemoryReadWrite(void *pMemory, ULONG dwSizeBytes);
1515
1516 FLAG
1517 SystemDependentInitialization(void);
1518
1519 UINT64 FASTCALL
1520 SystemReadTimeStampCounter(void);
1521
1522 //
1523 // This routine _must_ implement a full memory fence -- it is used in
1524 // util.c to implement spinlocks.
1525 //
1526 FLAG
1527 SystemCreateThread(THREAD_ENTRYPOINT *pEntry, ULONG uParam, ULONG *puHandle);
1528
1529 FLAG
1530 SystemWaitForThreadToExit(ULONG uThreadHandle);
1531
1532 FLAG
1533 SystemGetThreadExitCode(ULONG uThreadHandle, ULONG *puCode);
1534
1535 FLAG
1536 SystemDeleteThread(ULONG uThreadHandle);
1537
1538 CHAR *
1539 SystemGetDateString(void);
1540
1541 CHAR *
1542 SystemGetTimeString(void);
1543
1544 FLAG
1545 SystemCopyFile(CHAR *szSource, CHAR *szDest);
1546
1547 FLAG
1548 SystemDeleteFile(CHAR *szFile);
1549
1550 ULONG
1551 SystemCreateLock(void);
1552
1553 FLAG
1554 SystemDeleteLock(ULONG u);
1555
1556 FLAG
1557 SystemBlockingWaitForLock(ULONG u);
1558
1559 FLAG
1560 SystemReleaseLock(ULONG u);
1561
1562 ULONG
1563 SystemCreateSemaphore(ULONG u);
1564
1565 FLAG
1566 SystemDeleteSemaphore(ULONG u);
1567
1568 void
1569 SystemReleaseSemaphoreResource(ULONG u);
1570
1571 void
1572 SystemObtainSemaphoreResource(ULONG u);
1573
1574
1575 //
1576 // fen.c
1577 //
1578 #define STARTING_POSITION_IN_FEN \
1579     "rnbqkbnr/pppppppp/--------/8/8/--------/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
1580
1581 FLAG
1582 LooksLikeFen(char *szFen);
1583
1584 char *
1585 PositionToFen(POSITION *p);
1586
1587 FLAG
1588 FenToPosition(POSITION *p, char *szFen);
1589
1590 //
1591 // testfen.c
1592 //
1593 #ifdef TEST
1594 void
1595 TestFenCode(void);
1596 #endif
1597
1598 //
1599 // piece.c
1600 //
1601 // INVERTED VALUE == (VALUE_QUEEN / VALUE_PIECE) * VALUE_PAWN;
1602 #define VALUE_PAWN            100
1603 #define INVERT_PAWN           900
1604 #define VALUE_KNIGHT          300
1605 #define INVERT_KNIGHT         300
1606 #define VALUE_BISHOP          300
1607 #define INVERT_BISHOP         300
1608 #define VALUE_ROOK            500
1609 #define INVERT_ROOK           180
1610 #define VALUE_QUEEN           975
1611 #define INVERT_QUEEN          100
1612 #define VALUE_KING            (INFINITY)
1613 #define INVERT_KING           1
1614
1615 #define VALUE_FULL_ARMY       (8 * VALUE_PAWN) + (2 * VALUE_KNIGHT) + \
1616                               (2 * VALUE_BISHOP) + (2 * VALUE_ROOK) + \
1617                               VALUE_QUEEN + VALUE_KING
1618 #define VALUE_MAX_ARMY        (9 * VALUE_QUEEN) + (2 * VALUE_KNIGHT) + \
1619                               (2 * VALUE_BISHOP) + (2 * VALUE_ROOK) + \
1620                               VALUE_KING
1621
1622 typedef struct _PIECE_DATA
1623 {
1624     ULONG uValue;
1625     ULONG uValueOver100;
1626     ULONG uInvertedValue;
1627     CHAR *szName;
1628 } PIECE_DATA;
1629
1630 extern PIECE_DATA g_PieceData[8];
1631
1632 #define PIECE_VALUE_OVER_100(p) (g_PieceData[PIECE_TYPE(p)].uValueOver100)
1633 extern ULONG
1634 PieceValueOver100(PIECE p);
1635
1636 #define PIECE_VALUE(p)          (g_PieceData[PIECE_TYPE(p)].uValue)
1637 extern ULONG
1638 PieceValue(PIECE p);
1639
1640 #define INVERTED_PIECE_VALUE(p) (g_PieceData[PIECE_TYPE(p)].uInvertedValue)
1641 extern ULONG
1642 PieceInvertedValue(PIECE p);
1643
1644 CHAR *
1645 PieceAbbrev(PIECE p);
1646
1647 //
1648 // board.c
1649 //
1650 FLAG
1651 VerifyPositionConsistency(POSITION *pos, FLAG fContinueOnError);
1652
1653 FLAG
1654 PositionsAreEquivalent(POSITION *p1, POSITION *p2);
1655
1656 CHAR *
1657 DrawTextBoardFromPosition(POSITION *pos);
1658
1659 void
1660 DumpPosition(POSITION *pos);
1661
1662 CHAR *
1663 CastleInfoString(BITV bv);
1664
1665 void
1666 SetRootToInitialPosition(void);
1667
1668 //
1669 // move.c
1670 //
1671 void
1672 SlidePiece(POSITION *pos, COOR cFrom, COOR cTo);
1673
1674 PIECE
1675 LiftPiece(POSITION *pos, COOR cSquare);
1676
1677 void
1678 PlacePiece(POSITION *pos, COOR cSquare, PIECE pPiece);
1679
1680 FLAG
1681 MakeMove(SEARCHER_THREAD_CONTEXT *ctx,
1682          MOVE mv);
1683
1684 void
1685 UnmakeMove(SEARCHER_THREAD_CONTEXT *ctx,
1686            MOVE mv);
1687
1688 FLAG
1689 MakeUserMove(SEARCHER_THREAD_CONTEXT *ctx, MOVE mvUser);
1690
1691 void
1692 DumpMove(ULONG u);
1693
1694 //
1695 // movesup.c
1696 //
1697 #define MOVE_TO_INDEX(mv)  (((mv).uMove & 0xFFFF) + \
1698                             (0x10000 * GET_COLOR(mv.pMoved)))
1699
1700 COOR
1701 FasterExposesCheck(POSITION *pos,
1702                    COOR cRemove,
1703                    COOR cLocation);
1704
1705 COOR
1706 ExposesCheck(POSITION *pos,
1707              COOR cRemove,
1708              COOR cLocation);
1709
1710 COOR
1711 ExposesCheckEp(POSITION *pos,
1712                COOR cTest,
1713                COOR cIgnore,
1714                COOR cBlock,
1715                COOR cKing);
1716
1717 FLAG
1718 IsAttacked(COOR cTest, POSITION *pos, ULONG uSide);
1719
1720 FLAG
1721 InCheck(POSITION *pos, ULONG uSide);
1722
1723 FLAG
1724 SanityCheckMove(POSITION *pos, MOVE mv);
1725
1726 FLAG
1727 LooksLikeFile(CHAR c);
1728
1729 FLAG
1730 LooksLikeRank(CHAR c);
1731
1732 FLAG
1733 LooksLikeCoor(CHAR *szData);
1734
1735 CHAR *
1736 StripMove(CHAR *szMove);
1737
1738 ULONG
1739 LooksLikeMove(CHAR *szData);
1740
1741 void FASTCALL
1742 SelectBestWithHistory(SEARCHER_THREAD_CONTEXT *ctx, ULONG u);
1743
1744 void FASTCALL
1745 SelectBestNoHistory(SEARCHER_THREAD_CONTEXT *ctx, ULONG u);
1746
1747 void FASTCALL
1748 SelectMoveAtRoot(SEARCHER_THREAD_CONTEXT *ctx, ULONG u);
1749
1750 #define NOT_MOVE 0
1751 #define MOVE_ICS 1
1752 #define MOVE_SAN 2
1753
1754 COMMAND(PerftCommand);
1755
1756
1757 //
1758 // testmove.c
1759 //
1760 #ifdef TEST
1761 void
1762 TestLiftPlaceSlidePiece(void);
1763
1764 void
1765 TestExposesCheck(void);
1766
1767 void
1768 TestIsAttacked(void);
1769
1770 void
1771 TestMakeUnmakeMove(void);
1772 #endif
1773
1774 //
1775 // generate.c
1776 //
1777 #define SORT_THESE_FIRST (0x40000000)
1778 #define FIRST_KILLER     (0x20000000)
1779 #define SECOND_KILLER    (0x10000000)
1780 #define THIRD_KILLER     (0x08000000)
1781 #define FOURTH_KILLER    (0x04000000)
1782 #define GOOD_MOVE        (0x02000000)
1783 #define STRIP_OFF_FLAGS  (0x00FFFFFF)
1784
1785 extern const int g_iQKDeltas[9];
1786 extern const int g_iNDeltas[9];
1787 extern const int g_iBDeltas[5];
1788 extern const int g_iRDeltas[5];
1789
1790 void
1791 GenerateMoves(SEARCHER_THREAD_CONTEXT *ctx,
1792               MOVE mvOrderFirst,
1793               ULONG uType);
1794
1795 FLAG
1796 WouldGiveCheck(IN SEARCHER_THREAD_CONTEXT *ctx,
1797                IN MOVE mv);
1798
1799 //
1800 // testgenerate.c
1801 //
1802 #ifdef TEST
1803
1804 void
1805 PlyTest(SEARCHER_THREAD_CONTEXT *ctx,
1806         ULONG uDepth,
1807         FLAG fRootPositionInCheck);
1808
1809 void
1810 TestMoveGenerator(void);
1811
1812 void
1813 TestLegalMoveGenerator(void);
1814
1815 #endif
1816
1817 //
1818 // sig.c
1819 //
1820 extern UINT64 g_u64SigSeeds[128][7][2];
1821 extern UINT64 g_u64PawnSigSeeds[128][2];
1822 extern UINT64 g_u64CastleSigSeeds[16];
1823 extern UINT64 g_u64EpSigSeeds[9];
1824
1825 void
1826 InitializeSigSystem(void);
1827
1828 UINT64
1829 ComputePawnSig(POSITION *pos);
1830
1831 UINT64
1832 ComputeSig(POSITION *pos);
1833
1834 //
1835 // mersenne.c
1836 //
1837 void
1838 seedMT(unsigned int seed);
1839
1840 unsigned int
1841 reloadMT(void);
1842
1843 unsigned int
1844 randomMT(void);
1845
1846 //
1847 // data.c
1848 //
1849 typedef struct _VECTOR_DELTA
1850 {
1851     UCHAR iVector[2];
1852     signed char iDelta;
1853     signed char iNegDelta;
1854 }
1855 VECTOR_DELTA;
1856
1857 extern ULONG g_uDistance[256];
1858 extern ULONG *g_pDistance;
1859 extern VECTOR_DELTA g_VectorDelta[256];
1860 extern VECTOR_DELTA *g_pVectorDelta;
1861 extern CHAR g_SwapTable[14][32][32];
1862 extern SCORE _PSQT[14][128];
1863 extern ULONG g_uSearchSortLimits[];
1864 extern MOVE NULLMOVE;
1865 extern MOVE HASHMOVE;
1866 extern MOVE RECOGNMOVE;
1867 extern MOVE DRAWMOVE;
1868 extern MOVE MATEMOVE;
1869 extern FLAG g_fIsWhiteSquare[128];
1870 extern BITBOARD BBFILE[8];
1871 extern BITBOARD BBRANK[9];
1872 extern BITBOARD BBWHITESQ;
1873 extern BITBOARD BBBLACKSQ;
1874 extern BITBOARD BBLEFTSIDE;
1875 extern BITBOARD BBRIGHTSIDE;
1876 extern BITBOARD BBSQUARE[64];
1877 extern BITBOARD BBROOK_PAWNS;
1878 extern BITBOARD BBPRECEEDING_RANKS[8][2];
1879 extern BITBOARD BBADJACENT_FILES[8];
1880 extern BITBOARD BBADJACENT_RANKS[9];
1881
1882 void
1883 InitializeWhiteSquaresTable(void);
1884
1885 void
1886 InitializeVectorDeltaTable(void);
1887
1888 void
1889 InitializeSwapTable(void);
1890
1891 void
1892 InitializeDistanceTable(void);
1893
1894 void
1895 InitializeSearchDepthArray(void);
1896
1897 ULONG
1898 GetSearchSortLimit(ULONG);
1899
1900 #ifdef DEBUG
1901 #define SEARCH_SORT_LIMIT(x)    (GetSearchSortLimit((x)))
1902 #else
1903 #define SEARCH_SORT_LIMIT(x)    (g_uSearchSortLimits[(x)])
1904 #endif
1905
1906 #ifdef DEBUG
1907 ULONG CheckVectorWithIndex(int i, ULONG uColor);
1908 #define CHECK_VECTOR_WITH_INDEX(i, color) \
1909     CheckVectorWithIndex(i, color)
1910
1911 int DirectionBetweenSquaresWithIndex(int i);
1912 #define CHECK_DELTA_WITH_INDEX(i) \
1913     DirectionBetweenSquaresWithIndex(i)
1914
1915 int DirectionBetweenSquaresFromTo(COOR, COOR);
1916 #define DIRECTION_BETWEEN_SQUARES(from, to) \
1917     DirectionBetweenSquaresFromTo(from, to)
1918
1919 int NegativeDirectionBetweenSquaresWithIndex(int i);
1920 #define NEG_DELTA_WITH_INDEX(i) \
1921     NegativeDirectionBetweenSquaresWithIndex(i)
1922
1923 FLAG IsSquareWhite(COOR c);
1924 #define IS_SQUARE_WHITE(c) \
1925     IsSquareWhite(c)
1926
1927 #else
1928 #define CHECK_VECTOR_WITH_INDEX(i, color) \
1929     (g_pVectorDelta[(i)].iVector[(color)])
1930
1931 #define CHECK_DELTA_WITH_INDEX(i) \
1932     (g_pVectorDelta[(i)].iDelta)
1933
1934 #define DIRECTION_BETWEEN_SQUARES(cFrom, cTo) \
1935     CHECK_DELTA_WITH_INDEX((int)(cFrom) - (int)(cTo))
1936
1937 #define NEG_DELTA_WITH_INDEX(i) \
1938     (g_pVectorDelta[(i)].iNegDelta)
1939
1940 #define IS_SQUARE_WHITE(c) \
1941     (g_fIsWhiteSquare[(c)])
1942 #endif
1943
1944 //
1945 // san.c
1946 //
1947 MOVE
1948 ParseMoveSan(CHAR *szInput,
1949              POSITION *pos);
1950
1951 CHAR *
1952 MoveToSan(MOVE mv, POSITION *pos);
1953
1954 //
1955 // testsan.c
1956 //
1957 void
1958 TestSan(void);
1959
1960 //
1961 // list.c
1962 //
1963 void
1964 InitializeListHead(IN DLIST_ENTRY *pListHead);
1965
1966 FLAG
1967 IsListEmpty(IN DLIST_ENTRY *pListHead);
1968
1969 FLAG
1970 RemoveEntryList(IN DLIST_ENTRY *pEntry);
1971
1972 DLIST_ENTRY *
1973 RemoveHeadList(IN DLIST_ENTRY *pListHead);
1974
1975 DLIST_ENTRY *
1976 RemoveTailList(IN DLIST_ENTRY *pListHead);
1977
1978 void
1979 InsertTailList(IN DLIST_ENTRY *pListHead,
1980                IN DLIST_ENTRY *pEntry);
1981
1982 void
1983 InsertHeadList(IN DLIST_ENTRY *pListHead,
1984                IN DLIST_ENTRY *pEntry);
1985
1986 //
1987 // command.c
1988 //
1989 void
1990 ParseUserInput(FLAG fSearching);
1991
1992 FLAG
1993 InitializeCommandSystem(void);
1994
1995 void
1996 CleanupCommandSystem(void);
1997
1998 //
1999 // input.c
2000 //
2001 void
2002 InitInputSystemInBatchMode(void);
2003
2004 ULONG
2005 InitInputSystemWithDedicatedThread(void);
2006
2007 void
2008 PushNewInput(CHAR *buf);
2009
2010 CHAR *
2011 PeekNextInput(void);
2012
2013 CHAR *
2014 ReadNextInput(void);
2015
2016 CHAR *
2017 BlockingReadInput(void);
2018
2019 ULONG
2020 NumberOfPendingInputEvents(void);
2021
2022 volatile extern FLAG g_fExitProgram;
2023
2024 //
2025 // ics.c
2026 //
2027 MOVE
2028 ParseMoveIcs(CHAR *szInput, POSITION *pos);
2029
2030 CHAR *
2031 MoveToIcs(MOVE mv);
2032
2033 //
2034 // testics.c
2035 //
2036 void
2037 TestIcs(void);
2038
2039 //
2040 // gamelist.c
2041 //
2042 typedef enum _ERESULT
2043 {
2044     RESULT_BLACK_WON = -1,
2045     RESULT_DRAW = 0,
2046     RESULT_WHITE_WON = 1,
2047     RESULT_IN_PROGRESS,
2048     RESULT_ABANDONED,
2049     RESULT_UNKNOWN
2050 } ERESULT;
2051
2052 typedef struct _GAME_RESULT
2053 {
2054     ERESULT eResult;
2055     CHAR szDescription[256];
2056 } GAME_RESULT;
2057
2058 typedef struct _GAME_PLAYER
2059 {
2060     CHAR *szName;
2061     CHAR *szDescription;
2062     FLAG fIsComputer;
2063     ULONG uRating;
2064 }
2065 GAME_PLAYER;
2066
2067 typedef struct _GAME_HEADER
2068 {
2069     CHAR *szGameDescription;
2070     CHAR *szLocation;
2071     GAME_PLAYER sPlayer[2];
2072     FLAG fGameIsRated;
2073     UINT64 u64OpeningSig;
2074     GAME_RESULT result;
2075     CHAR *szInitialFen;
2076 }
2077 GAME_HEADER;
2078
2079 typedef struct _GAME_MOVE
2080 {
2081     DLIST_ENTRY links;
2082     ULONG uNumber;
2083     MOVE mv;
2084     CHAR *szComment;
2085     CHAR *szDecoration;
2086     CHAR *szMoveInSan;
2087     CHAR *szMoveInIcs;
2088     CHAR *szUndoPositionFen;
2089     SCORE iMoveScore;
2090     UINT64 u64PositionSigAfterMove;
2091     UINT64 u64PositionSigBeforeMove;
2092     volatile FLAG fInUse;
2093 }
2094 GAME_MOVE;
2095
2096 typedef struct _GAME_DATA
2097 {
2098     GAME_HEADER sHeader;
2099     DLIST_ENTRY sMoveList;
2100 }
2101 GAME_DATA;
2102
2103 extern GAME_DATA g_GameData;
2104
2105 POSITION *
2106 GetRootPosition(void);
2107
2108 FLAG
2109 SetRootPosition(CHAR *szFen);
2110
2111 void
2112 ResetGameList(void);
2113
2114 ULONG
2115 GetMoveNumber(ULONG uColor);
2116
2117 void
2118 SetGameResultAndDescription(GAME_RESULT result);
2119
2120 GAME_RESULT
2121 GetGameResult(void);
2122
2123 void
2124 SetMyName(void);
2125
2126 void
2127 SetOpponentsName(CHAR *sz);
2128
2129 void
2130 SetMyRating(ULONG u);
2131
2132 void
2133 SetOpponentsRating(ULONG u);
2134
2135 void
2136 DumpGameList(void);
2137
2138 void
2139 TellGamelistThatIPlayColor(ULONG u);
2140
2141 void
2142 DumpPgn(void);
2143
2144 FLAG
2145 LoadPgn(CHAR *szPgn);
2146
2147 ULONG
2148 CountOccurrancesOfSigInOfficialGameList(UINT64 u64Sig);
2149
2150 FLAG
2151 DoesSigAppearInOfficialGameList(UINT64 u64Sig);
2152
2153 FLAG
2154 OfficiallyTakebackMove(void);
2155
2156 FLAG
2157 OfficiallyMakeMove(MOVE mv, SCORE iMoveScore, FLAG fFast);
2158
2159 GAME_MOVE *
2160 GetNthOfficialMoveRecord(ULONG n);
2161
2162 void
2163 MakeStatusLine(void);
2164
2165 FLAG
2166 IsLegalDrawByRepetition(void);
2167
2168 //
2169 // script.c
2170 //
2171 COMMAND(ScriptCommand);
2172
2173 COMMAND(SolutionCommand);
2174
2175 COMMAND(AvoidCommand);
2176
2177 COMMAND(IdCommand);
2178
2179 void
2180 PostMoveTestSuiteReport(SEARCHER_THREAD_CONTEXT *);
2181
2182 FLAG
2183 CheckTestSuiteMove(MOVE mv, SCORE iScore, ULONG uDepth);
2184
2185 FLAG
2186 WeAreRunningASuite(void);
2187
2188
2189 //
2190 // vars.c
2191 //
2192 COMMAND(SetCommand);
2193
2194 //
2195 // root.c
2196 //
2197 extern ULONG g_uSoftExtendLimit;
2198 extern ULONG g_uHardExtendLimit;
2199 extern volatile MOVE_TIMER g_MoveTimer;
2200 extern ULONG g_uExtensionReduction[MAX_PLY_PER_SEARCH];
2201
2202 #ifdef PERF_COUNTERS
2203 #define KEEP_TRACK_OF_FIRST_MOVE_FHs(x)                \
2204     ctx->sCounters.tree.u64BetaCutoffs++;              \
2205     if (x)                                             \
2206     {                                                  \
2207        ctx->sCounters.tree.u64BetaCutoffsOnFirstMove++;\
2208     }
2209 #else
2210 #define KEEP_TRACK_OF_FIRST_MOVE_FHs(x)
2211 #endif
2212
2213 #define GAME_NOT_OVER 0
2214 #define GAME_WHITE_WON 1
2215 #define GAME_BLACK_WON 2
2216 #define GAME_DRAW_STALEMATE 3
2217 #define GAME_DRAW_REPETITION 4
2218 #define GAME_ONE_LEGAL_MOVE 5
2219 #define GAME_DRAW_FIFTY_MOVES_WO_PROGRESS 6
2220
2221 GAME_RESULT
2222 Think(POSITION *pos);
2223
2224 GAME_RESULT
2225 Ponder(POSITION *pos);
2226
2227 GAME_RESULT
2228 Iterate(SEARCHER_THREAD_CONTEXT *ctx);
2229
2230 void
2231 SetMoveTimerForSearch(FLAG fSwitchOver, ULONG uColor);
2232
2233 void
2234 SetMoveTimerToThinkForever(void);
2235
2236 void
2237 ClearRootNodecountHash(void);
2238
2239 //
2240 // draw.c
2241 //
2242 FLAG
2243 IsDraw(SEARCHER_THREAD_CONTEXT *ctx);
2244
2245
2246 //
2247 // search.c
2248 //
2249 #define QPLIES_OF_NON_CAPTURE_CHECKS (1)
2250 #define FUTILITY_BASE_MARGIN         (50) // + ctx->uPositional (min 100)
2251 #define DO_IID
2252 #define IID_R_FACTOR                 (TWO_PLY + HALF_PLY)
2253
2254 #ifndef MP
2255 #define WE_SHOULD_STOP_SEARCHING (g_MoveTimer.bvFlags & TIMER_STOPPING)
2256 #else
2257 #define WE_SHOULD_STOP_SEARCHING ((g_MoveTimer.bvFlags & TIMER_STOPPING) || \
2258                                   (ThreadUnderTerminatingSplit(ctx)))
2259 #endif
2260
2261 SCORE FASTCALL
2262 QSearch(SEARCHER_THREAD_CONTEXT *ctx,
2263         SCORE iAlpha,
2264         SCORE iBeta);
2265
2266 SCORE FASTCALL
2267 Search(SEARCHER_THREAD_CONTEXT *ctx,
2268        SCORE iAlpha,
2269        SCORE iBeta,
2270        ULONG uDepth);
2271
2272
2273 //
2274 // searchsup.c
2275 //
2276 SCORE
2277 ComputeMoveScore(IN SEARCHER_THREAD_CONTEXT *ctx,
2278                  IN MOVE mv,
2279                  IN ULONG uMoveNum);
2280
2281 FLAG
2282 ThreadUnderTerminatingSplit(SEARCHER_THREAD_CONTEXT *);
2283
2284 FLAG
2285 WeShouldDoHistoryPruning(IN SCORE iRoughEval,
2286                          IN SCORE iAlpha,
2287                          IN SCORE iBeta,
2288                          IN SEARCHER_THREAD_CONTEXT *ctx,
2289                          IN ULONG uRemainingDepth,
2290                          IN ULONG uLegalMoves,
2291                          IN MOVE mv,
2292                          IN ULONG uMoveNum,
2293                          IN INT iExtend);
2294
2295 FLAG
2296 WeShouldTryNullmovePruning(IN SEARCHER_THREAD_CONTEXT *ctx,
2297                            IN SCORE iAlpha,
2298                            IN SCORE iBeta,
2299                            IN SCORE iRoughEval,
2300                            IN ULONG uNullDepth);
2301
2302 FLAG
2303 TryNullmovePruning(IN OUT SEARCHER_THREAD_CONTEXT *ctx,
2304                    IN OUT FLAG *pfThreat,
2305                    IN SCORE iAlpha,
2306                    IN SCORE iBeta,
2307                    IN ULONG uNullDepth,
2308                    IN OUT INT *piOrigExtend,
2309                    OUT SCORE *piNullScore);
2310
2311 void
2312 UpdatePV(SEARCHER_THREAD_CONTEXT *ctx, MOVE mv);
2313
2314 FLAG
2315 CheckInputAndTimers(IN SEARCHER_THREAD_CONTEXT *ctx);
2316
2317 void
2318 ComputeReactionToCheckExtension(IN OUT SEARCHER_THREAD_CONTEXT *ctx,
2319                                 IN ULONG uGenFlags,
2320                                 IN ULONG uMoveNum,
2321                                 IN SCORE iRoughEval,
2322                                 IN SCORE iAlpha,
2323                                 IN OUT INT *piExtend,
2324                                 IN OUT INT *piOrigExtend);
2325
2326 void
2327 ComputeMoveExtension(IN OUT SEARCHER_THREAD_CONTEXT *ctx,
2328                      IN SCORE iAlpha,
2329                      IN SCORE iBeta,
2330                      IN ULONG uMoveNum,
2331                      IN SCORE iRoughEval,
2332                      IN ULONG uDepth,
2333                      IN OUT INT *piExtend);
2334
2335 SCORE
2336 RescoreMovesViaSearch(IN SEARCHER_THREAD_CONTEXT *ctx,
2337                       IN ULONG uDepth,
2338                       IN SCORE iAlpha,
2339                       IN SCORE iBeta);
2340
2341 FLAG
2342 MateDistancePruningCutoff(IN ULONG uPly,
2343                           IN FLAG fInCheck,
2344                           IN OUT SCORE *piBestScore,
2345                           IN OUT SCORE *piAlpha,
2346                           IN OUT SCORE *piBeta);
2347
2348 FLAG
2349 CommonSearchInit(IN SEARCHER_THREAD_CONTEXT *ctx,
2350                  IN OUT SCORE *piAlpha,
2351                  IN OUT SCORE *piBeta,
2352                  IN OUT SCORE *piScore);
2353
2354 ULONG
2355 SelectNullmoveRFactor(IN SEARCHER_THREAD_CONTEXT *ctx,
2356                       IN INT uDepth);
2357
2358 #define VERIFY_BEFORE (1)
2359 #define VERIFY_AFTER  (2)
2360
2361 FLAG
2362 SanityCheckMoves(IN SEARCHER_THREAD_CONTEXT *ctx,
2363                  IN ULONG uCurrent,
2364                  IN ULONG uType);
2365
2366
2367 //
2368 // testsearch.c
2369 //
2370 FLAG
2371 TestSearch(void);
2372
2373 //
2374 // see.c
2375 //
2376 #define SEE_HEAPS
2377
2378 SCORE
2379 SEE(POSITION *pos,
2380     MOVE mv);
2381
2382 typedef struct _SEE_THREESOME
2383 {
2384     PIECE pPiece;
2385     COOR cLoc;
2386     ULONG uVal;
2387 } SEE_THREESOME;
2388
2389 typedef struct _SEE_LIST
2390 {
2391     ULONG uCount;
2392     SEE_THREESOME data[16];
2393 }
2394 SEE_LIST;
2395
2396 SCORE
2397 ControlsSquareMinusPiece(ULONG uSide,
2398                          POSITION *pos,
2399                          COOR c,
2400                          COOR cIgnore);
2401
2402 //
2403 // testsee.c
2404 //
2405 SCORE
2406 DebugSEE(POSITION *pos,
2407          MOVE mv);
2408
2409 void
2410 TestGetAttacks(void);
2411
2412 //
2413 // hash.c
2414 //
2415 #define NUM_HASH_ENTRIES_PER_LINE     4
2416 #define HASH_FLAG_EXACT               0x1
2417 #define HASH_FLAG_LOWER               0x2
2418 #define HASH_FLAG_UPPER               0x4
2419 #define HASH_FLAG_VALID_BOUNDS        0x7
2420 #define HASH_FLAG_THREAT              0x8
2421 #define HASH_FLAG_DIRTY               0xF0
2422
2423 typedef struct _HASH_ENTRY
2424 {
2425     MOVE mv;                         // 0 1 2 3
2426     UCHAR uDepth;                    // 4
2427     UCHAR bvFlags;                   // 5 ==> d  d  d  d | thr up low exact
2428     signed short iValue;             // 6 7
2429     UINT64 u64Sig;                   // 8 9 A B C D E F == 16 bytes
2430 } HASH_ENTRY;
2431
2432 FLAG
2433 InitializeHashSystem(void);
2434
2435 void
2436 CleanupHashSystem(void);
2437
2438 void
2439 ClearHashTable(void);
2440
2441 void
2442 DirtyHashTable(void);
2443
2444 void
2445 StoreLowerBound(MOVE mvBestMove,
2446            POSITION *pos,
2447            SCORE iValue,
2448            ULONG uDepth,
2449            FLAG fThreat);
2450 void
2451 StoreExactScore(MOVE mvBestMove,
2452             POSITION *pos,
2453           SCORE iValue,
2454           ULONG uDepth,
2455           FLAG fThreat,
2456           ULONG uPly);
2457
2458 void
2459 StoreUpperBound(//MOVE mvBestMove,
2460            POSITION *pos,
2461            SCORE iValue,
2462            ULONG uDepth,
2463            FLAG fThreat);
2464
2465 HASH_ENTRY *
2466 HashLookup(SEARCHER_THREAD_CONTEXT *ctx,
2467            ULONG uDepth,
2468            ULONG uNextDepth,
2469            SCORE iAlpha,
2470            SCORE iBeta,
2471            FLAG *pfThreat,
2472            FLAG *pfAvoidNull,
2473            MOVE *pHashMove,
2474            SCORE *piScore);
2475
2476 COOR
2477 CheckHashForDangerSquare(POSITION *pos);
2478
2479 MOVE
2480 GetPonderMove(POSITION *pos);
2481
2482 extern ULONG g_uHashTableSizeEntries;
2483 extern ULONG g_uHashTableSizeBytes;
2484 extern HASH_ENTRY *g_pHashTable;
2485
2486 //
2487 // testhash.c
2488 //
2489 void
2490 AnalyzeFullHashTable(void);
2491
2492 //
2493 // positionhash.c
2494 //
2495 // IDEA: store "mate threat" flag in here?
2496 // IDEA: store "king safety" numbers in here?
2497 //
2498 typedef struct _POSITION_HASH_ENTRY {
2499     UINT64 u64Sig;
2500     UCHAR cEnprise[2];
2501     UCHAR uEnpriseCount[2];
2502     UCHAR cTrapped[2];
2503 } POSITION_HASH_ENTRY;
2504
2505 void
2506 InitializePositionHashSystem(void);
2507
2508 void
2509 CleanupPositionHashSystem(void);
2510
2511 void
2512 StoreEnprisePiece(POSITION *pos, COOR cSquare);
2513
2514 void
2515 StoreTrappedPiece(POSITION *pos, COOR cSquare);
2516
2517 COOR
2518 GetEnprisePiece(POSITION *pos, ULONG uSide);
2519
2520 ULONG
2521 GetEnpriseCount(POSITION *pos, ULONG uSide);
2522
2523 COOR
2524 GetTrappedPiece(POSITION *pos, ULONG uSide);
2525
2526 FLAG
2527 SideCanStandPat(POSITION *pos, ULONG uSide);
2528
2529 ULONG
2530 ValueOfMaterialInTroubleDespiteMove(POSITION *pos, ULONG uSide);
2531
2532 ULONG
2533 ValueOfMaterialInTroubleAfterNull(POSITION *pos, ULONG uSide);
2534
2535 //
2536 // pawnhash.c
2537 //
2538 #define COOR_TO_BIT(x)       ((x) & 0x7) + ((0x7 - ((x) >> 4)) << 3)
2539
2540 void
2541 ClearPawnHashStats(void);
2542
2543 void
2544 ReportPawnHashStats(void);
2545
2546 PAWN_HASH_ENTRY *
2547 PawnHashLookup(SEARCHER_THREAD_CONTEXT *ctx);
2548
2549 //
2550 // eval.c
2551 //
2552 #define LAZY_EVAL
2553 #define LAZE_EVAL_BASE_SCORE 10
2554 extern const int g_iAhead[2];
2555 extern const int g_iBehind[2];
2556
2557 ULONG 
2558 DNABufferSizeBytes();
2559
2560 char *
2561 ExportEvalDNA();
2562
2563 FLAG
2564 WriteEvalDNA(char *szFilename);
2565
2566 FLAG
2567 ImportEvalDNA(char *p);
2568
2569 FLAG
2570 ReadEvalDNA(char *szFilename);
2571
2572
2573
2574 SCORE
2575 Eval(SEARCHER_THREAD_CONTEXT *, SCORE, SCORE);
2576
2577 FLAG
2578 EvalPasserRaces(POSITION *,
2579                 PAWN_HASH_ENTRY *);
2580
2581 ULONG
2582 CountKingSafetyDefects(POSITION *pos,
2583                        ULONG uSide);
2584
2585 //
2586 // testeval.c
2587 //
2588 #ifdef EVAL_DUMP
2589 void
2590 TestEval(void);
2591
2592 void
2593 EvalTraceReport(void);
2594
2595 void
2596 EvalTrace(ULONG uColor, PIECE p, COOR c, SCORE iVal, CHAR *szMessage);
2597
2598 SCORE
2599 EvalSigmaForPiece(POSITION *pos, COOR c);
2600
2601 void
2602 EvalTraceClear(void);
2603
2604 void
2605 TestEvalWithSymmetry(void);
2606
2607 #define EVAL_TERM(COL, PIE, COO, VAL, ADJ, MESS) \
2608     (VAL) += (ADJ); \
2609     EvalTrace((COL), (PIE), (COO), (ADJ), (MESS));
2610 #else
2611 #define EVAL_TERM(COL, PIE, COO, VAL, ADJ, MESS) \
2612     (VAL) += (ADJ);
2613 #endif
2614
2615 //
2616 // bitboard.c
2617 //
2618 void
2619 InitializeBitboards(void);
2620
2621 ULONG CDECL
2622 SlowCountBits(BITBOARD bb);
2623
2624 ULONG CDECL
2625 DeBruijnFirstBit(BITBOARD bb);
2626
2627 ULONG CDECL
2628 SlowFirstBit(BITBOARD bb);
2629
2630 ULONG CDECL
2631 SlowLastBit(BITBOARD bb);
2632
2633 #ifdef CROUTINES
2634 #define CountBits SlowCountBits
2635 #define FirstBit SlowFirstBit
2636 #define LastBit SlowLastBit
2637 #endif
2638
2639 COOR
2640 CoorFromBitBoardRank8ToRank1(BITBOARD *pbb);
2641
2642 COOR
2643 CoorFromBitBoardRank1ToRank8(BITBOARD *pbb);
2644
2645 //
2646 // x86.asm
2647 //
2648 ULONG CDECL
2649 CountBits(BITBOARD bb);
2650
2651 ULONG CDECL
2652 FirstBit(BITBOARD bb);
2653
2654 ULONG CDECL
2655 LastBit(BITBOARD bb);
2656
2657 ULONG CDECL
2658 LockCompareExchange(volatile void *pDest,
2659                     ULONG uExch,
2660                     ULONG uComp);
2661
2662 ULONG CDECL
2663 LockIncrement(volatile void *pDest);
2664
2665 ULONG CDECL
2666 LockDecrement(volatile void *pDest);
2667
2668 FLAG CDECL
2669 CanUseParallelOpcodes();
2670
2671 ULONG CDECL
2672 ParallelCompareUlong(ULONG uComparand, void *pComparators);
2673
2674 ULONG CDECL
2675 ParallelCompareVector(void *pComparand, void *pComparators);
2676
2677 void CDECL
2678 GetAttacks(SEE_LIST *pList,
2679            POSITION *pos,
2680            COOR cSquare,
2681            ULONG uSide);
2682
2683 void CDECL
2684 SlowGetAttacks(SEE_LIST *pList,
2685                POSITION *pos,
2686                COOR cSquare,
2687                ULONG uSide);
2688 #ifdef CROUTINES
2689 #define GetAttacks SlowGetAttacks
2690 #endif
2691
2692 #ifdef _X86_
2693 //
2694 // Note: this is most of the stuff that x86.asm assumes about the
2695 // internal data structures.  If any of this fails then either the
2696 // assembly language code needs to be updated or you need to use the C
2697 // version of the routine in see.c instead.
2698 //
2699 #define ASSERT_ASM_ASSUMPTIONS \
2700     ASSERT(VALUE_PAWN == 100); \
2701     ASSERT(OFFSET_OF(uCount, SEE_LIST) == 0); \
2702     ASSERT(OFFSET_OF(data, SEE_LIST) == 4); \
2703     ASSERT(sizeof(SEE_THREESOME) == 12); \
2704     ASSERT(OFFSET_OF(pPiece, SEE_THREESOME) == 0); \
2705     ASSERT(OFFSET_OF(cLoc, SEE_THREESOME) == 4); \
2706     ASSERT(OFFSET_OF(uVal, SEE_THREESOME) == 8); \
2707     ASSERT(OFFSET_OF(cNonPawns, POSITION) == 0x478); \
2708     ASSERT(OFFSET_OF(uNonPawnCount, POSITION) == 0x500); \
2709     ASSERT(OFFSET_OF(rgSquare, POSITION) == 0); \
2710     ASSERT(sizeof(SQUARE) == 8); \
2711     ASSERT(sizeof(VECTOR_DELTA) == 4); \
2712     ASSERT(sizeof(g_VectorDelta) == 256 * 4); \
2713     ASSERT(OFFSET_OF(iVector, VECTOR_DELTA) == 0); \
2714     ASSERT(OFFSET_OF(iDelta, VECTOR_DELTA) == 2); \
2715     ASSERT(OFFSET_OF(iNegDelta, VECTOR_DELTA) == 3); \
2716     ASSERT(sizeof(g_PieceData) == 8 * 4 * 4); \
2717     ASSERT(OFFSET_OF(uValue, PIECE_DATA) == 0);
2718 #else
2719 #define ASSERT_ASM_ASSUMPTIONS
2720 #endif
2721
2722 //
2723 // testbitboard.c
2724 //
2725 void
2726 TestBitboards(void);
2727
2728 //
2729 // dynamic.c
2730 //
2731 extern ULONG g_HistoryCounters[14][128];
2732
2733 ULONG
2734 GetMoveFailHighPercentage(MOVE mv);
2735
2736 void
2737 UpdateDynamicMoveOrdering(SEARCHER_THREAD_CONTEXT *ctx,
2738                           ULONG uRemainingDepth,
2739                           MOVE mvBest,
2740                           SCORE iScore,
2741                           ULONG uCurrent);
2742
2743 void
2744 NewKillerMove(SEARCHER_THREAD_CONTEXT *ctx, MOVE mv, SCORE iScore);
2745
2746 FLAG
2747 InitializeDynamicMoveOrdering(void);
2748
2749 void
2750 CleanupDynamicMoveOrdering(void);
2751
2752 void
2753 ClearDynamicMoveOrdering(void);
2754
2755 void
2756 MaintainDynamicMoveOrdering(void);
2757
2758 void
2759 IncrementMoveHistoryCounter(MOVE mv, ULONG u);
2760
2761 void
2762 DecrementMoveHistoryCounter(MOVE mv, ULONG u);
2763
2764 //
2765 // split.c
2766 //
2767 extern volatile ULONG g_uNumHelpersAvailable;
2768 extern ULONG g_uNumHelperThreads;
2769
2770 FLAG
2771 InitializeParallelSearch(void);
2772
2773 FLAG
2774 CleanupParallelSearch(void);
2775
2776 void
2777 ClearHelperThreadIdleness(void);
2778
2779 void
2780 DumpHelperIdlenessReport(void);
2781
2782 SCORE
2783 StartParallelSearch(IN SEARCHER_THREAD_CONTEXT *ctx,
2784                     IN OUT SCORE *piAlpha,
2785                     IN SCORE iBeta,
2786                     IN OUT SCORE *piBestScore,
2787                     IN OUT MOVE *pmvBest,
2788                     IN ULONG uMoveNum,
2789                     IN INT iPositionExtend,
2790                     IN ULONG uDepth);
2791
2792 void
2793 InitializeSearcherContext(POSITION *pos, SEARCHER_THREAD_CONTEXT *ctx);
2794
2795 void
2796 ReInitializeSearcherContext(POSITION *pos, SEARCHER_THREAD_CONTEXT *ctx);
2797
2798 void
2799 InitializeLightweightSearcherContext(POSITION *pos,
2800                                      LIGHTWEIGHT_SEARCHER_CONTEXT *ctx);
2801
2802 //
2803 // book.c
2804 //
2805
2806 #define BOOK_PROBE_MISS_LIMIT  (7)
2807 #define FLAG_DISABLED          (1)
2808 #define FLAG_ALWAYSPLAY        (2)
2809 #define FLAG_DELETED           (4)
2810
2811 #define BOOKMOVE_SELECT_MOVE   (1)
2812 #define BOOKMOVE_DUMP          (2)
2813
2814 #pragma pack(4)
2815 typedef struct _BOOK_ENTRY
2816 {
2817     UINT64 u64Sig;                            // 8 bytes
2818     UINT64 u64NextSig;                        // 8 bytes
2819     MOVE mvNext;                              // 4 bytes
2820     ULONG uWins;                              // 4 bytes
2821     ULONG uDraws;                             // 4 bytes
2822     ULONG uLosses;                            // 4 bytes
2823     BITV bvFlags;                             // 4 bytes
2824 }
2825 BOOK_ENTRY;
2826 #pragma pack()
2827
2828 typedef struct _OPENING_NAME_MAPPING
2829 {
2830     UINT64 u64Sig;
2831     CHAR *szString;
2832 }
2833 OPENING_NAME_MAPPING;
2834
2835 #define BOOK_EDITING_RECORD       "bkedit.edt"
2836 #define OPENING_LEARNING_FILENAME "bklearn.bin"
2837
2838 typedef struct _OPENING_LEARNING_ENTRY
2839 {
2840     UINT64 u64Sig;
2841     ULONG uWhiteWins;
2842     ULONG uDraws;
2843     ULONG uBlackWins;
2844 }
2845 OPENING_LEARNING_ENTRY;
2846
2847 FLAG
2848 InitializeOpeningBook(void);
2849
2850 void
2851 ResetOpeningBook(void);
2852
2853 void
2854 CleanupOpeningBook(void);
2855
2856 MOVE
2857 BookMove(POSITION *pos,
2858          BITV bvFlags);
2859
2860 COMMAND(BookCommand);
2861
2862 extern ULONG g_uBookProbeFailures;
2863 extern FLAG g_fTournamentMode;
2864 extern CHAR *g_szBookName;
2865
2866 //
2867 // bench.c
2868 //
2869 COMMAND(BenchCommand);
2870
2871 //
2872 // testdraw.c
2873 //
2874 void
2875 TestDraw(void);
2876
2877 //
2878 // probe.c
2879 //
2880 FLAG
2881 ProbeEGTB(SEARCHER_THREAD_CONTEXT *ctx, SCORE *score);
2882
2883 void
2884 InitializeEGTB(void);
2885
2886 void
2887 CleanupEGTB(void);
2888
2889 //
2890 // dumptree.c
2891 //
2892 #ifdef DUMP_TREE
2893
2894 void
2895 InitializeTreeDump(void);
2896
2897 void
2898 CleanupTreeDump(void);
2899
2900 void
2901 DTEnterNode(SEARCHER_THREAD_CONTEXT *ctx,
2902             ULONG uDepth,
2903             FLAG fIsQNode,
2904             SCORE iAlpha,
2905             SCORE iBeta);
2906
2907 void
2908 DTLeaveNode(SEARCHER_THREAD_CONTEXT *ctx,
2909             FLAG fQNode,
2910             SCORE iBestScore,
2911             MOVE mvBestMove);
2912
2913 void CDECL
2914 DTTrace(ULONG uPly, CHAR *szMessage, ...);
2915
2916 #define DTTRACE(...) DTTrace(ctx->uPly, __VA_ARGS__)
2917
2918 #else
2919
2920 #define DTTRACE(...)
2921
2922 #define DTEnterNode(...)
2923
2924 #define DTLeaveNode(...)
2925
2926 #define InitializeTreeDump(...)
2927
2928 #define CleanupTreeDump(...)
2929
2930 #endif
2931
2932 //
2933 // testsup.c
2934 //
2935 FLAG
2936 IsBoardLegal(POSITION *pos);
2937
2938 void
2939 GenerateRandomLegalPosition(POSITION *pos);
2940
2941 void
2942 GenerateRandomLegalSymetricPosition(POSITION *pos);
2943
2944 //
2945 // recogn.c
2946 //
2947 #define UNRECOGNIZED (0)
2948 #define RECOGN_EXACT (1)
2949 #define RECOGN_UPPER (2)
2950 #define RECOGN_LOWER (3)
2951 #define RECOGN_EGTB  (4)
2952
2953 void
2954 InitializeInteriorNodeRecognizers(void);
2955
2956 ULONG
2957 RecognLookup(SEARCHER_THREAD_CONTEXT *ctx,
2958              SCORE *piScore,
2959              FLAG fProbeEGTB);
2960
2961 #ifdef EVAL_HASH
2962 void
2963 ClearEvalHashStats(void);
2964
2965 void
2966 ReportEvalHashStats(void);
2967
2968 SCORE
2969 ProbeEvalHash(SEARCHER_THREAD_CONTEXT *ctx);
2970
2971 SCORE
2972 GetRoughEvalScore(IN SEARCHER_THREAD_CONTEXT *ctx,
2973                   IN SCORE iAlpha,
2974                   IN SCORE iBeta,
2975                   IN FLAG fUseHash);
2976
2977 void
2978 StoreEvalHash(SEARCHER_THREAD_CONTEXT *ctx, SCORE iScore);
2979 #endif // EVAL_HASH
2980
2981 #endif // CHESS