1 /*
2  *******************************************************************************
3  *                                                                             *
4  *   configuration information:  the following variables need to be set to     *
5  *   indicate the machine configuration/capabilities.                          *
6  *                                                                             *
7  *   UNIX:  define this if the program is being run on a unix-based system,    *
8  *   which causes the executable to use unix-specific runtime utilities.       *
9  *                                                                             *
10  *   CPUS=N:  this sets up data structures to the appropriate size to support  *
11  *   up to N simultaneous search engines.  note that you can set this to a     *
12  *   value larger than the max processors you currently have, because the mt=n *
13  *   command (added to the command line or your crafty.rc/.craftyrc file) will *
14  *   control how many threads are actually spawned.                            *
15  *                                                                             *
16  *******************************************************************************
17  */
18 /* *INDENT-OFF* */
19 
20 #if defined(AFFINITY)
21 #  define _GNU_SOURCE
22 #  include <sched.h>
23 #endif
24 #if defined(UNIX)
25 #  define _GNU_SOURCE
26 #  if (CPUS > 1)
27 #    include <pthread.h>
28 #  endif
29 #  include <unistd.h>
30 #  include <sys/types.h>
31 #  include <sys/stat.h>
32 #endif
33 #include <stdint.h>
34 #include <inttypes.h>
35 #include <time.h>
36 #include <stdio.h>
37 #include <assert.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #pragma once
41 #  if !defined (UNIX)
42 #    define RESTRICT __restrict
43 #  else
44 #    define RESTRICT
45 #  endif
46 #  if !defined(CPUS)
47 #    define CPUS 1
48 #  endif
49 #  if !defined(UNIX)
50 #    include <windows.h>
51 #    include <process.h>
52 #  endif
53 #  define CDECL
54 #  define STDCALL
55 /* Provide reasonable defaults for UNIX systems. */
56 #  if !defined(UNIX)
57 #    undef  STDCALL
58 #    define STDCALL __stdcall
59 #    ifdef  VC_INLINE32
60 #      undef  CDECL
61 #      define CDECL __cdecl
62 #    endif
63 #  endif
64 #  if !defined(BOOKDIR)
65 #    define   BOOKDIR      "."
66 #  endif
67 #  if !defined(LOGDIR)
68 #    define   LOGDIR       "."
69 #  endif
70 #  if !defined(TBDIR)
71 #    define   TBDIR        "./syzygy"
72 #  endif
73 #  if !defined(RCDIR)
74 #    define   RCDIR        "."
75 #  endif
76 #  include "lock.h"
77 #  define MAXPLY                                 129
78 #  define MAX_TC_NODES                       3000000
79 #  define MAX_BLOCKS                       64 * CPUS
80 #  define BOOK_CLUSTER_SIZE                     8000
81 #  define MERGE_BLOCK                           1000
82 #  define SORT_BLOCK                         4000000
83 #  define LEARN_INTERVAL                          10
84 #  define LEARN_COUNTER_BAD                      -80
85 #  define LEARN_COUNTER_GOOD                    +100
86 #  define MATE                                 32768
87 #  define TBWIN                                31000
88 #  define PAWN_VALUE                             100
89 #  define KNIGHT_VALUE                           305
90 #  define BISHOP_VALUE                           305
91 #  define ROOK_VALUE                             490
92 #  define QUEEN_VALUE                           1000
93 #  define KING_VALUE                           40000
94 #  define FOREVER                                  1
95 #  if !defined(CLOCKS_PER_SEC)
96 #    define CLOCKS_PER_SEC 1000000
97 #  endif
98 typedef enum {
99   A1, B1, C1, D1, E1, F1, G1, H1,
100   A2, B2, C2, D2, E2, F2, G2, H2,
101   A3, B3, C3, D3, E3, F3, G3, H3,
102   A4, B4, C4, D4, E4, F4, G4, H4,
103   A5, B5, C5, D5, E5, F5, G5, H5,
104   A6, B6, C6, D6, E6, F6, G6, H6,
105   A7, B7, C7, D7, E7, F7, G7, H7,
106   A8, B8, C8, D8, E8, F8, G8, H8,
107   BAD_SQUARE
108 } squares;
109 typedef enum { FILEA, FILEB, FILEC, FILED, FILEE, FILEF, FILEG, FILEH } files;
110 typedef enum { RANK1, RANK2, RANK3, RANK4, RANK5, RANK6, RANK7, RANK8 } ranks;
111 typedef enum { empty = 0, occupied = 0, pawn = 1, knight = 2, bishop = 3,
112   rook = 4, queen = 5, king = 6
113 } PIECE;
114 typedef enum { black = 0, white = 1 } COLOR;
115 typedef enum { mg = 0, eg = 1 } PHASE;
116 typedef enum { empty_v = 0, pawn_v = 1, knight_v = 3,
117                bishop_v = 3, rook_v = 5, queen_v = 9, king_v = 99
118 } PIECE_V;
119 typedef enum { serial = 0, parallel = 1} SEARCH_MODE;
120 typedef enum { think = 1, puzzle = 2, book = 3, annotate = 4 } SEARCH_TYPE;
121 typedef enum { normal_mode, tournament_mode } PLAYING_MODE;
122 typedef struct {
123   int8_t castle[2];
124   uint8_t enpassant_target;
125   uint8_t reversible;
126 } SEARCH_POSITION;
127 typedef struct {
128   uint32_t move1;
129   uint32_t move2;
130 } KILLER;
131 typedef struct {
132   uint64_t pieces[7];
133 } BB_PIECES;
134 typedef struct {
135   BB_PIECES color[2];
136   uint64_t hash_key;
137   uint64_t pawn_hash_key;
138   int material_evaluation;
139   int kingsq[2];
140   int8_t board[64];
141   char pieces[2][7];
142   char total_all_pieces;
143 } POSITION;
144 typedef struct {
145   uint64_t word1;
146   uint64_t word2;
147 } HASH_ENTRY;
148 typedef struct {
149   uint64_t key;
150   int32_t score_mg, score_eg;
151   unsigned char defects_k[2];
152   unsigned char defects_m[2];
153   unsigned char defects_q[2];
154   unsigned char passed[2];
155 } PAWN_HASH_ENTRY;
156 typedef struct {
157   uint64_t entry[3];
158 } PXOR;
159 typedef struct {
160   int path[MAXPLY];
161   int pathh;
162   int pathl;
163   int pathd;
164   int pathv;
165 } PATH;
166 typedef struct {
167   uint64_t path_sig;
168   int hash_pathl;
169   int hash_path_age;
170   int hash_path_moves[MAXPLY];
171 } HPATH_ENTRY;
172 typedef struct {
173   int phase;
174   int order;
175   int remaining;
176   unsigned *last;
177   unsigned done[10];
178   unsigned *exclude;
179 } NEXT_MOVE;
180 /*
181    root_move.status:
182 
183    xxx1 = failed low this iteration
184    xx1x = failed high this iteration
185    x1xx = don't search in parallel or reduce
186    1xxx = move has been searched
187  */
188 typedef struct {
189   int move;
190   unsigned status;
191   int bm_age;
192   PATH path;
193 } ROOT_MOVE;
194 #  if !defined(UNIX)
195 #    pragma pack(4)
196 #  endif
197 typedef struct {
198   uint64_t position;
199   unsigned status_played;
200   float learn;
201 } BOOK_POSITION;
202 #  if !defined(UNIX)
203 #    pragma pack()
204 #  endif
205 typedef struct {
206   unsigned char position[8];
207   unsigned char status;
208   unsigned char percent_play;
209 } BB_POSITION;
210 struct personality_term {
211   char *description;
212   int type;
213   int size;
214   void *value;
215 };
216 struct autotune {
217   unsigned int min;
218   unsigned int max;
219   unsigned int increment;
220   char description[64];
221   char command[16];
222   unsigned int *parameter;
223 };
224 typedef struct tree {
225 /* commonly used variables */
226   SEARCH_POSITION status[MAXPLY + 3];
227   NEXT_MOVE next_status[MAXPLY];
228   KILLER killers[MAXPLY];
229   KILLER counter_move[4096];
230   KILLER move_pair[4096];
231   POSITION position;
232   uint64_t save_hash_key[MAXPLY + 3];
233   uint64_t save_pawn_hash_key[MAXPLY + 3];
234   uint64_t rep_list[256];
235   int curmv[MAXPLY];
236   int phase[MAXPLY];
237   int hash_move[MAXPLY];
238   unsigned *last[MAXPLY];
239   unsigned move_list[5120];
240   PATH pv[MAXPLY];
241 /* variables used by Evaluate() */
242   PAWN_HASH_ENTRY pawn_score;
243   int tropism[2];
244   int dangerous[2];
245   uint64_t all_pawns;
246   int score_mg, score_eg;
247 /* statistical counters */
248   uint64_t nodes_searched;
249   uint64_t fail_highs;
250   uint64_t fail_high_first_move;
251   uint64_t evaluations;
252   uint64_t egtb_probes;
253   uint64_t egtb_hits;
254   uint64_t extensions_done;
255   uint64_t qchecks_done;
256   uint64_t moves_fpruned;
257   uint64_t moves_mpruned;
258   uint64_t LMR_done[16];
259   uint64_t null_done[16];
260 /* thread stuff */
261   lock_t lock;
262   int thread_id;
263   volatile int joinable;
264   volatile int joined;
265   volatile int stop;
266   volatile int nprocs;
267   int alpha;
268   int beta;
269   volatile int value;
270   int wtm;
271   int depth;
272   int ply;
273   int in_check;
274   int *searched;
275   int cutmove;
276   struct tree *volatile siblings[CPUS], *parent;
277 /* rarely accessed */
278   char root_move_text[16];
279   char remaining_moves_text[16];
280 } TREE;
281 typedef struct thread {
282   TREE *tree;
283   uint64_t blocks;
284   uint64_t max_blocks;
285   unsigned int idle;
286   volatile unsigned int terminate;
287   char filler[40];
288 } THREAD;
289 /*
290    DO NOT modify these.  these are constants, used in multiple modules.
291    modification may corrupt the search in any number of ways, all bad.
292  */
293 #  define WORTHLESS                    0
294 #  define UPPER                        1
295 #  define LOWER                        2
296 #  define EXACT                        3
297 #  define HASH_MISS                    0
298 #  define HASH_HIT                     1
299 #  define AVOID_NULL_MOVE              2
300 #  define NO_NULL                      0
301 #  define DO_NULL                      1
302 #  define NONE                         0
303 #  define NULL_MOVE                    1
304 #  define DO_NOT_REDUCE                1
305 #  define HASH                         2
306 #  define GENERATE_CAPTURES            3
307 #  define CAPTURES                     4
308 #  define KILLER1                      5
309 #  define KILLER2                      6
310 #  define KILLER3                      7
311 #  define KILLER4                      8
312 #  define COUNTER_MOVE1                9
313 #  define COUNTER_MOVE2               10
314 #  define MOVE_PAIR1                  11
315 #  define MOVE_PAIR2                  12
316 #  define GENERATE_QUIET              13
317 #  define HISTORY                     14
318 #  define REMAINING                   15
319 #  define EVALUATION                  16
320 #  define ILLEGAL                      0
321 #  define LEGAL                        1
322 #  define IN_WINDOW                    2
323 #  define FAIL_HIGH                    3
324 #define PopCnt(v) __builtin_popcountll(v)
325 #define LSB(v)    __builtin_ctzll(v)
326 #define MSB(v)    (63 - __builtin_clzll(v))
327 void AlignedMalloc(void **, uint64_t, size_t);
328 void AlignedRemalloc(void **, uint64_t, size_t);
329 void Analyze(void);
330 void Annotate(void);
331 void AnnotateHeaderHTML(char *, FILE *);
332 void AnnotateFooterHTML(FILE *);
333 void AnnotatePositionHTML(TREE *RESTRICT, int, FILE *);
334 char *AnnotateVtoNAG(int, int, int, int);
335 void AnnotateHeaderTeX(FILE *);
336 void AnnotateFooterTeX(FILE *);
337 void AnnotatePositionTeX(TREE *, int, FILE *);
338 uint64_t atoiKMB(char *);
339 int Attacks(TREE *RESTRICT, int, int);
340 uint64_t Attacked(TREE *RESTRICT, int, uint64_t);
341 uint64_t AttacksFrom(TREE *RESTRICT, int, int);
342 uint64_t AttacksTo(TREE *RESTRICT, int);
343 void AutoTune(int, char **);
344 int Bench(int, int);
345 int Book(TREE *RESTRICT, int);
346 void BookClusterIn(FILE *, int, BOOK_POSITION *);
347 void BookClusterOut(FILE *, int, BOOK_POSITION *);
348 int BookIn32(unsigned char *);
349 float BookIn32f(unsigned char *);
350 uint64_t BookIn64(unsigned char *);
351 int BookMask(char *);
352 unsigned char *BookOut32(int);
353 unsigned char *BookOut32f(float);
354 unsigned char *BookOut64(uint64_t);
355 int BookPonderMove(TREE *RESTRICT, int);
356 void Bookup(TREE *RESTRICT, int, char **);
357 void BookSort(BB_POSITION *, int, int);
358 int BookupCompare(const void *, const void *);
359 BB_POSITION BookupNextPosition(int, int);
360 int CheckInput(void);
361 void ClearHashTableScores(void);
362 int ComputeDifficulty(int, int);
363 void CopyFromParent(TREE *RESTRICT);
364 void CopyToParent(TREE *RESTRICT, TREE *RESTRICT, int);
365 void CraftyExit(int);
366 void DisplayArray(int *, int);
367 void DisplayArrayX2(int *, int *, int);
368 void DisplayBitBoard(uint64_t);
369 void Display2BitBoards(uint64_t, uint64_t);
370 void DisplayChessBoard(FILE *, POSITION);
371 char *DisplayEvaluation(int, int);
372 char *DisplayEvaluationKibitz(int, int);
373 void DisplayFT(int, int, int);
374 char *DisplayHHMM(unsigned);
375 char *DisplayHHMMSS(unsigned);
376 char *DisplayKMB(uint64_t, int);
377 void DisplayFail(TREE *RESTRICT, int, int, int, int, int, int, int);
378 char *DisplayPath(TREE *RESTRICT, int, PATH *);
379 void DisplayPV(TREE *RESTRICT, int, int, int, PATH *, int);
380 char *DisplayTime(unsigned);
381 char *Display2Times(unsigned);
382 char *DisplayTimeKibitz(unsigned);
383 void DisplayChessMove(char *, int);
384 int Drawn(TREE *RESTRICT, int);
385 int  DTZtoWDL(int, int);
386 void Edit(void);
387 int Evaluate(TREE *RESTRICT, int, int, int, int);
388 void EvaluateBishops(TREE *RESTRICT, int);
389 void EvaluateCastling(TREE *RESTRICT, int, int);
390 int EvaluateDraws(TREE *RESTRICT, int, int, int);
391 int EvaluateHasOpposition(int, int, int);
392 void EvaluateKing(TREE *RESTRICT, int, int);
393 int EvaluateKingsFile(TREE * RESTRICT, int, int, int);
394 void EvaluateKnights(TREE *RESTRICT, int);
395 void EvaluateMate(TREE *RESTRICT, int);
396 void EvaluateMaterial(TREE *RESTRICT, int);
397 void EvaluatePassedPawns(TREE *RESTRICT, int, int);
398 void EvaluatePassedPawnRaces(TREE *RESTRICT, int);
399 void EvaluatePawns(TREE *RESTRICT, int);
400 void EvaluateQueens(TREE *RESTRICT, int);
401 void EvaluateRooks(TREE *RESTRICT, int);
402 int EvaluateWinningChances(TREE *RESTRICT, int, int);
403 void EVTest(char *);
404 int Exclude(TREE *RESTRICT, int, int);
405 int FindBlockID(TREE *RESTRICT);
406 char *FormatPV(TREE *RESTRICT, int, PATH);
407 int FTbSetCacheSize(void *, unsigned long);
408 int GameOver(int);
409 unsigned *GenerateCaptures(TREE *RESTRICT, int, int, unsigned *);
410 unsigned *GenerateCheckEvasions(TREE *RESTRICT, int, int, unsigned *);
411 unsigned *GenerateChecks(TREE *RESTRICT, int, unsigned *);
412 unsigned *GenerateNoncaptures(TREE *RESTRICT, int, int, unsigned *);
413 TREE *GetBlock(TREE *, int);
414 void Initialize(void);
415 void InitializeAttackBoards(void);
416 void InitializeChessBoard(TREE *);
417 int InitializeGetLogID();
418 void InitializeHashTables(int);
419 void InitializeKillers(void);
420 void InitializeKingSafety(void);
421 void InitializeMagic(void);
422 uint64_t InitializeMagicBishop(int, uint64_t);
423 uint64_t InitializeMagicRook(int, uint64_t);
424 uint64_t InitializeMagicOccupied(int *, int, uint64_t);
425 void InitializeMasks(void);
426 void InitializePawnMasks(void);
427 void InitializeLMP(void);
428 void InitializeLMR(void);
429 void InitializeSMP(void);
430 int IInitializeTb(char *);
431 int InputMove(TREE *RESTRICT, int, int, int, int, char *);
432 int InputMoveICS(TREE *RESTRICT, int, int, int, int, char *);
433 uint64_t InterposeSquares(int, int, int);
434 void Interrupt(int);
435 int InvalidPosition(TREE *RESTRICT);
436 int Iterate(int, int, int);
437 int Join(int64_t);
438 void Kibitz(int, int, int, int, int, uint64_t, int, int, char *);
439 void History(TREE *RESTRICT, int, int, int, int, int*);
440 int KingPawnSquare(int, int, int, int);
441 int LearnAdjust(int);
442 void LearnBook(void);
443 int LearnFunction(int, int, int, int);
444 void LearnValue(int, int);
445 void MakeMove(TREE *RESTRICT, int, int, int);
446 void MakeMoveRoot(TREE *RESTRICT, int, int);
447 int Mated(TREE *RESTRICT, int, int);
448 int RootMoveEGTB(int);
449 int NextMove(TREE *RESTRICT, int, int, int, int);
450 int NextRootMove(TREE *RESTRICT, TREE *RESTRICT, int);
451 int NextRootMoveParallel(void);
452 void NextSort(TREE *RESTRICT, int);
453 int Option(TREE *RESTRICT);
454 int OptionMatch(char *, char *);
455 void OptionPerft(TREE *RESTRICT, int, int, int);
456 void Output(TREE *RESTRICT);
457 char *OutputMove(TREE *RESTRICT, int, int, int);
458 int ParseTime(char *);
459 void Pass(void);
460 int PinnedOnKing(TREE *RESTRICT, int, int);
461 int Ponder(int);
462 void Print(int, char *, ...);
463 int ProbeDTZ(TREE * RESTRICT tree, int ply, int wtm);
464 int HashProbe(TREE *RESTRICT, int, int, int, int, int, int*);
465 void HashStore(TREE *RESTRICT, int, int, int, int, int, int);
466 void HashStorePV(TREE *RESTRICT, int, int);
467 int Quiesce(TREE *RESTRICT, int, int, int, int, int);
468 int QuiesceEvasions(TREE *RESTRICT, int, int, int, int);
469 unsigned Random32(void);
470 uint64_t Random64(void);
471 int Read(int, char *);
472 int ReadChessMove(TREE *RESTRICT, FILE *, int, int);
473 void ReadClear(void);
474 unsigned ReadClock(void);
475 int ReadPGN(FILE *, int);
476 int ReadNextMove(TREE *RESTRICT, char *, int, int);
477 int ReadParse(char *, char *args[], char *);
478 int ReadInput(void);
479 int Repeat(TREE *RESTRICT, int);
480 int Repeat3x(TREE *RESTRICT);
481 void ResignOrDraw(TREE *RESTRICT, int);
482 void RestoreGame(void);
483 void RootMoveList(int);
484 int Search(TREE *RESTRICT, int, int, int, int, int, int, int);
485 int SearchMove(TREE *RESTRICT, int, int, int, int, int, int, int, int, int);
486 int SearchMoveList(TREE *RESTRICT, int, int, int, int, int, int *, int, int, int);
487 int SearchNull(TREE * RESTRICT, int, int, int, int);
488 void Trace(TREE *RESTRICT, int, int, int, int, int, const char *, int, int, int);
489 void SetBoard(TREE *, int, char **, int);
490 void SetChessBitBoards(TREE *);
491 void SharedFree(void *address);
492 void SortRootMoves(TREE *RESTRICT, int);
493 int Split(TREE *RESTRICT);
494 int StrCnt(char *, char);
495 int SEE(TREE *RESTRICT, int, int);
496 int SEEO(TREE *RESTRICT, int, int);
497 void Test(char *, FILE *, int, int);
498 void TestEPD(char *, FILE *, int, int);
499 void ThreadAffinity(int);
500 void *STDCALL ThreadInit(void *);
501 #  if !defined(UNIX)
502 void ThreadMalloc(int64_t);
503 #  endif
504 int ThreadSplit(TREE *RESTRICT, int, int, int, int, int);
505 void ThreadStop(TREE *RESTRICT);
506 void ThreadTrace(TREE * RESTRICT, int, int);
507 int ThreadWait(int, TREE *RESTRICT);
508 int Threat(TREE *, int, int, int, int);
509 void TimeAdjust(int, int);
510 int TimeCheck(TREE *RESTRICT, int);
511 void TimeSet(int);
512 void UnmakeMove(TREE *RESTRICT, int, int, int);
513 int ValidMove(TREE *RESTRICT, int, int, int);
514 int VerifyMove(TREE *RESTRICT, int, int, int);
515 void ValidatePosition(TREE *RESTRICT, int, int, char *);
516 void WaitForAllThreadsInitialized(void);
517 #  if !defined(UNIX)
518 extern void *WinMallocInterleaved(size_t, int);
519 extern void WinFreeInterleaved(void *, size_t);
520 #    define MallocInterleaved(cBytes, cThreads)     \
521        WinMallocInterleaved(cBytes, cThreads)
522 #    define FreeInterleaved(pMemory, cBytes)        \
523        WinFreeInterleaved(pMemory, cBytes)
524 #  else
525 #    if defined(NUMA)
526 #      define MallocInterleaved(cBytes, cThreads) numa_alloc_interleaved(cBytes)
527 #      define FreeInterleaved(pMemory, cBytes)          numa_free(pMemory, 1)
528 #    else
529 #      define MallocInterleaved(cBytes, cThreads) malloc(cBytes)
530 #      define FreeInterleaved(pMemory, cBytes)          free(pMemory)
531 #    endif
532 #  endif
533 #  define Abs(a)    (((a) > 0) ? (a) : -(a))
534 #  define Max(a,b)  (((a) > (b)) ? (a) : (b))
535 #  define Min(a,b)  (((a) < (b)) ? (a) : (b))
536 #  define Sign(a)   ((a) < 0 ? -1 : +1)
537 #  define FileDistance(a,b) abs(File(a) - File(b))
538 #  define RankDistance(a,b) abs(Rank(a) - Rank(b))
539 #  define Distance(a,b) Max(FileDistance(a,b), RankDistance(a,b))
540 #  define DrawScore(side)                  (draw_score[side])
541 #  define PopCnt8Bit(a) (pop_cnt_8bit[a])
542 #  define MSB8Bit(a) (msb_8bit[a])
543 #  define LSB8Bit(a) (lsb_8bit[a])
544 #  define HistoryIndex(side, m) ((side << 9) + (Piece(m) << 6) + To(m))
545 /*
546    side = side to move
547    mptr = pointer into move list
548    m = bit vector of to squares to unpack
549    t = pre-computed from + moving piece
550  */
551 #  define Extract(side, mptr, m, t)                                         \
552   for ( ; m ; Clear(to, m)) {                                               \
553     to = MostAdvanced(side, m);                                             \
554     *mptr++ = t | (to << 6) | (Abs(PcOnSq(to)) << 15);                      \
555   }
556 #  define Check(side) Attacks(tree, Flip(side), KingSQ(side))
557 #  define Attack(from,to) (!(intervening[from][to] & OccupiedSquares))
558 #  define BishopAttacks(square, occ) *(magic_bishop_indices[square]+((((occ)&magic_bishop_mask[square])*magic_bishop[square])>>magic_bishop_shift[square]))
559 #  define BishopMobility(square, occ) *(magic_bishop_mobility_indices[square]+((((occ)&magic_bishop_mask[square])*magic_bishop[square])>>magic_bishop_shift[square]))
560 #  define KingAttacks(square) king_attacks[square]
561 #  define KnightAttacks(square) knight_attacks[square]
562 #  define PawnAttacks(side, square)   pawn_attacks[side][square]
563 #  define Reversible(p)               (tree->status[p].reversible)
564 #  define ReversibleMove(m)           (!CaptureOrPromote(m) && Piece(m) != pawn)
565 #  define RookAttacks(square, occ) *(magic_rook_indices[square]+((((occ)&magic_rook_mask[square])*magic_rook[square])>>magic_rook_shift[square]))
566 #  define RookMobility(square, occ) *(magic_rook_mobility_indices[square]+((((occ)&magic_rook_mask[square])*magic_rook[square])>>magic_rook_shift[square]))
567 #  define QueenAttacks(square, occ)   (BishopAttacks(square, occ)|RookAttacks(square, occ))
568 #  define Rank(x)        ((x)>>3)
569 #  define File(x)        ((x)&7)
570 #  define Flip(x)        ((x)^1)
571 #  define MostAdvanced(side, squares) ((side) ? MSB(squares) : LSB(squares))
572 #  define LeastAdvanced(side, squares) ((side) ? LSB(squares) : MSB(squares))
573 #  define MinMax(side, v1, v2) ((side) ? Min((v1), (v2)) : Max((v1), (v2)))
574 #  define InFront(side, k, p) ((side) ? k > p : k < p)
575 #  define Behind(side, k, p) ((side) ? k < p : k > p)
576 #  define Passed(sq, wtm)        (!(mask_passed[wtm][sq] & Pawns(Flip(wtm))))
577 #  define RankAttacks(a) (RookAttacks(a, OccupiedSquares) & rank_mask[Rank(a)])
578 #  define FileAttacks(a) (RookAttacks(a, OccupiedSquares) & file_mask[File(a)])
579 #  define Diaga1Attacks(a) (BishopAttacks(a, OccupiedSquares) & (plus9dir[a] | minus9dir[a]))
580 #  define Diagh1Attacks(a) (BishopAttacks(a, OccupiedSquares) & (plus7dir[a] | minus7dir[a]))
581 #  define InterposeSquares(kingsq, checksq) intervening[kingsq][checksq]
582 /*
583    the following macros are used to extract the pieces of a move that are
584    kept compressed into the rightmost 21 bits of a simple integer.
585  */
586 #  define From(a)               ((a) & 63)
587 #  define To(a)                 (((a)>>6) & 63)
588 #  define Piece(a)              (((a)>>12) & 7)
589 #  define Captured(a)           (((a)>>15) & 7)
590 #  define Promote(a)            (((a)>>18) & 7)
591 #  define Move(a)               (a & 0x1fffff)
592 #  define SortV(a)              (a >> 21)
593 #  define CaptureOrPromote(a)   (((a)>>15) & 63)
594 #  define PawnPush(c, a)        (Piece(a) == pawn &&                          \
595                                      rankflip[c][Rank(To(a))] >= RANK6        \
596                                      && !(mask_passed[c][To(a)] &             \
597                                           Pawns(Flip(c))))
598 #  define CastleMove(c, a)       (Piece(a) == king && Abs(File(To(a)) -       \
599                                      File(From(a))) > 1)
600 #  define SetMask(a)             (set_mask[a])
601 #  define ClearMask(a)           (clear_mask[a])
602 #  define Pawns(c)               (tree->position.color[c].pieces[pawn])
603 #  define Knights(c)             (tree->position.color[c].pieces[knight])
604 #  define Bishops(c)             (tree->position.color[c].pieces[bishop])
605 #  define Rooks(c)               (tree->position.color[c].pieces[rook])
606 #  define Queens(c)              (tree->position.color[c].pieces[queen])
607 #  define Kings(c)               (tree->position.color[c].pieces[king])
608 #  define KingSQ(c)              (tree->position.kingsq[c])
609 #  define Occupied(c)            (tree->position.color[c].pieces[occupied])
610 #  define Pieces(c, p)           (tree->position.color[c].pieces[p])
611 #  define TotalPieces(c, p)      (tree->position.pieces[c][p])
612 #  define PieceValues(c, p)      (piece_values[c][p])
613 #  define TotalAllPieces         (tree->position.total_all_pieces)
614 #  define Material               (tree->position.material_evaluation)
615 #  define MaterialSTM(side)      ((side) ? Material : -Material)
616 #  define MateScore(s)           (Abs(s) > 32000)
617 #  define EGTBScore(s)           (Abs(s) > 30000 && Abs(s) < 32000)
618 #  define Castle(ply, c)         (tree->status[ply].castle[c])
619 #  define HashKey                (tree->position.hash_key)
620 #  define PawnHashKey            (tree->position.pawn_hash_key)
621 #  define EnPassant(ply)         (tree->status[ply].enpassant_target)
622 #  define EnPassantTarget(ply)   (EnPassant(ply) ? SetMask(EnPassant(ply)) : 0)
623 #  define PcOnSq(sq)             (tree->position.board[sq])
624 #  define OccupiedSquares        (Occupied(white) | Occupied(black))
625 #  define Color(square)       (square_color[square] ? dark_squares : ~dark_squares)
626 #  define SideToMove(c)          ((c) ? "White" : "Black")
627 /*
628    the following macros are used to Set and Clear a specific bit in the
629    second argument.  this is done to make the code more readable, rather
630    than to make it faster.
631  */
632 #  define ClearSet(a,b)         b=((a) ^ (b))
633 #  define Clear(a,b)            b=ClearMask(a) & (b)
634 #  define Set(a,b)              b=SetMask(a) | (b)
635 /*
636    the following macros are used to update the hash signatures.
637  */
638 #  define Hash(stm,piece,square)     (HashKey^=randoms[stm][piece][square])
639 #  define HashP(stm,square)          (PawnHashKey^=randoms[stm][pawn][square])
640 #  define HashCastle(stm,direction)  (HashKey^=castle_random[stm][direction])
641 #  define HashEP(sq)                 (HashKey^=enpassant_random[sq])
642 #  define SavePV(tree,ply,ph)        do {                                     \
643         tree->pv[ply-1].path[ply-1]=tree->curmv[ply-1];                       \
644         tree->pv[ply-1].pathl=ply;                                            \
645         tree->pv[ply-1].pathh=ph;                                             \
646         tree->pv[ply-1].pathd=iteration;} while(0)
647 #  if defined(INLINEASM)
648 #    include "inline.h"
649 #  endif
650 /* *INDENT-ON* */
651