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