Subversion Repositories Games.Chess Giants

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
154 pmbaty 1
/*
2
 * tbprobe.c
3
 * Copyright (c) 2013-2015 Ronald de Man
4
 * This file may be redistributed and/or modified without restrictions.
5
 *
6
 * (C) 2015 basil, all rights reserved,
7
 * Permission is hereby granted, free of charge, to any person obtaining a
8
 * copy of this software and associated documentation files (the "Software"),
9
 * to deal in the Software without restriction, including without limitation
10
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
 * and/or sell copies of the Software, and to permit persons to whom the
12
 * Software is furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
 * DEALINGS IN THE SOFTWARE.
24
 */
25
 
26
#include <assert.h>
27
#include <stdio.h>
28
#include <stdlib.h>
29
 
30
#include "tbprobe.h"
31
 
32
//#include <x86intrin.h>
33
 
34
#define WHITE_KING              (TB_WPAWN + 5)
35
#define WHITE_QUEEN             (TB_WPAWN + 4)
36
#define WHITE_ROOK              (TB_WPAWN + 3)
37
#define WHITE_BISHOP            (TB_WPAWN + 2)
38
#define WHITE_KNIGHT            (TB_WPAWN + 1)
39
#define WHITE_PAWN              TB_WPAWN
40
#define BLACK_KING              (TB_BPAWN + 5)
41
#define BLACK_QUEEN             (TB_BPAWN + 4)
42
#define BLACK_ROOK              (TB_BPAWN + 3)
43
#define BLACK_BISHOP            (TB_BPAWN + 2)
44
#define BLACK_KNIGHT            (TB_BPAWN + 1)
45
#define BLACK_PAWN              TB_BPAWN
46
 
47
#define PRIME_WHITE_QUEEN       11811845319353239651ull
48
#define PRIME_WHITE_ROOK        10979190538029446137ull
49
#define PRIME_WHITE_BISHOP      12311744257139811149ull
50
#define PRIME_WHITE_KNIGHT      15202887380319082783ull
51
#define PRIME_WHITE_PAWN        17008651141875982339ull
52
#define PRIME_BLACK_QUEEN       15484752644942473553ull
53
#define PRIME_BLACK_ROOK        18264461213049635989ull
54
#define PRIME_BLACK_BISHOP      15394650811035483107ull
55
#define PRIME_BLACK_KNIGHT      13469005675588064321ull
56
#define PRIME_BLACK_PAWN        11695583624105689831ull
57
 
58
#define BOARD_RANK_EDGE         0x8181818181818181ull
59
#define BOARD_FILE_EDGE         0xFF000000000000FFull
60
#define BOARD_EDGE              (BOARD_RANK_EDGE | BOARD_FILE_EDGE)
61
#define BOARD_RANK_1            0x00000000000000FFull
62
#define BOARD_FILE_A            0x8080808080808080ull
63
 
64
#define KEY_KvK                 0
65
 
66
#define BEST_NONE               0xFFFF
67
#define SCORE_ILLEGAL           0x7FFF
68
 
69
#define popcount(v) PopCnt(v)
70
 
71
#define poplsb(x)               ((x) & ((x) - 1))
72
 
73
#define make_move(promote, from, to)                                    \
74
    ((((promote) & 0x7) << 12) | (((from) & 0x3F) << 6) | ((to) & 0x3F))
75
#define move_from(move)                                                 \
76
    (((move) >> 6) & 0x3F)
77
#define move_to(move)                                                   \
78
    ((move) & 0x3F)
79
#define move_promotes(move)                                             \
80
    (((move) >> 12) & 0x7)
81
 
82
#define MAX_MOVES               TB_MAX_MOVES
83
#define MOVE_STALEMATE          0xFFFF
84
#define MOVE_CHECKMATE          0xFFFE
85
 
86
struct pos {
87
  uint64_t white;
88
  uint64_t black;
89
  uint64_t kings;
90
  uint64_t queens;
91
  uint64_t rooks;
92
  uint64_t bishops;
93
  uint64_t knights;
94
  uint64_t pawns;
95
  uint8_t rule50;
96
  uint8_t ep;
97
  bool turn;
98
};
99
 
100
static bool do_move(struct pos *pos, const struct pos *pos0, uint16_t move);
101
static int probe_dtz(const struct pos *pos, int *success);
102
 
103
unsigned TB_LARGEST = 0;
104
#include "tbcore.c"
105
 
106
#define rank(s)                 ((s) >> 3)
107
#define file(s)                 ((s) & 0x07)
108
#define board(s)                ((uint64_t)1 << (s))
109
static inline unsigned _lsb(uint64_t b) {
110
#ifdef _WIN32 // Pierre-Marie Baty -- Win32 addition
111
  static const int index64[64] = {
112
     0, 47,  1, 56, 48, 27,  2, 60,
113
     57, 49, 41, 37, 28, 16,  3, 61,
114
     54, 58, 35, 52, 50, 42, 21, 44,
115
     38, 32, 29, 23, 17, 11,  4, 62,
116
     46, 55, 26, 59, 40, 36, 15, 53,
117
     34, 51, 20, 43, 31, 22, 10, 45,
118
     25, 39, 14, 33, 19, 30,  9, 24,
119
     13, 18,  8, 12,  7,  6,  5, 63
120
  };
121
  /**
122
  * bitScanForward
123
  * @author Kim Walisch (2012)
124
  * @param bb bitboard to scan
125
  * @precondition bb != 0
126
  * @return index (0..63) of least significant one bit
127
  */
128
   const uint64_t debruijn64 = 0x03f79d71b4cb0a89ULL;
129
   assert (b != 0);
130
   return index64[((b ^ (b - 1)) * debruijn64) >> 58];
131
#else
132
  size_t idx;
133
__asm__("bsfq %1, %0": "=r"(idx):"rm"(b));
134
  return idx;
135
#endif
136
}
137
 
138
#define square(r, f)            (8 * (r) + (f))
139
 
140
#ifdef TB_KING_ATTACKS
141
#  define king_attacks(s)         TB_KING_ATTACKS(s)
142
#  define king_attacks_init()
143
                            /* NOP */
144
#else                           /* TB_KING_ATTACKS */
145
 
146
static uint64_t king_attacks_table[64];
147
 
148
#  define king_attacks(s)         king_attacks_table[(s)]
149
 
150
static void king_attacks_init(void) {
151
  for (unsigned s = 0; s < 64; s++) {
152
    unsigned r = rank(s);
153
    unsigned f = file(s);
154
    uint64_t b = 0;
155
    if (r != 0 && f != 0)
156
      b |= board(square(r - 1, f - 1));
157
    if (r != 0)
158
      b |= board(square(r - 1, f));
159
    if (r != 0 && f != 7)
160
      b |= board(square(r - 1, f + 1));
161
    if (f != 7)
162
      b |= board(square(r, f + 1));
163
    if (r != 7 && f != 7)
164
      b |= board(square(r + 1, f + 1));
165
    if (r != 7)
166
      b |= board(square(r + 1, f));
167
    if (r != 7 && f != 0)
168
      b |= board(square(r + 1, f - 1));
169
    if (f != 0)
170
      b |= board(square(r, f - 1));
171
    king_attacks_table[s] = b;
172
  }
173
}
174
 
175
#endif                          /* TB_KING_ATTACKS */
176
 
177
#ifdef TB_KNIGHT_ATTACKS
178
#  define knight_attacks(s)       TB_KNIGHT_ATTACKS(s)
179
#  define knight_attacks_init()
180
                              /* NOP */
181
#else                           /* TB_KNIGHT_ATTACKS */
182
 
183
static uint64_t knight_attacks_table[64];
184
 
185
#  define knight_attacks(s)       knight_attacks_table[(s)]
186
 
187
static void knight_attacks_init(void) {
188
  for (unsigned s = 0; s < 64; s++) {
189
    int r1, r = rank(s);
190
    int f1, f = file(s);
191
    uint64_t b = 0;
192
    r1 = r - 1;
193
    f1 = f - 2;
194
    if (r1 >= 0 && f1 >= 0)
195
      b |= board(square(r1, f1));
196
    r1 = r - 1;
197
    f1 = f + 2;
198
    if (r1 >= 0 && f1 <= 7)
199
      b |= board(square(r1, f1));
200
    r1 = r - 2;
201
    f1 = f - 1;
202
    if (r1 >= 0 && f1 >= 0)
203
      b |= board(square(r1, f1));
204
    r1 = r - 2;
205
    f1 = f + 1;
206
    if (r1 >= 0 && f1 <= 7)
207
      b |= board(square(r1, f1));
208
    r1 = r + 1;
209
    f1 = f - 2;
210
    if (r1 <= 7 && f1 >= 0)
211
      b |= board(square(r1, f1));
212
    r1 = r + 1;
213
    f1 = f + 2;
214
    if (r1 <= 7 && f1 <= 7)
215
      b |= board(square(r1, f1));
216
    r1 = r + 2;
217
    f1 = f - 1;
218
    if (r1 <= 7 && f1 >= 0)
219
      b |= board(square(r1, f1));
220
    r1 = r + 2;
221
    f1 = f + 1;
222
    if (r1 <= 7 && f1 <= 7)
223
      b |= board(square(r1, f1));
224
    knight_attacks_table[s] = b;
225
  }
226
}
227
 
228
#endif                          /* TB_KNIGHT_ATTACKS */
229
 
230
#ifdef TB_BISHOP_ATTACKS
231
#  define bishop_attacks(s, occ)  TB_BISHOP_ATTACKS(s, occ)
232
#  define bishop_attacks_init()
233
                              /* NOP */
234
#else                           /* TB_BISHOP_ATTACKS */
235
 
236
static uint64_t diag_attacks_table[64][64];
237
static uint64_t anti_attacks_table[64][64];
238
 
239
static const unsigned square2diag_table[64] = {
240
  0, 1, 2, 3, 4, 5, 6, 7,
241
  14, 0, 1, 2, 3, 4, 5, 6,
242
  13, 14, 0, 1, 2, 3, 4, 5,
243
  12, 13, 14, 0, 1, 2, 3, 4,
244
  11, 12, 13, 14, 0, 1, 2, 3,
245
  10, 11, 12, 13, 14, 0, 1, 2,
246
  9, 10, 11, 12, 13, 14, 0, 1,
247
  8, 9, 10, 11, 12, 13, 14, 0
248
};
249
 
250
static const unsigned square2anti_table[64] = {
251
  8, 9, 10, 11, 12, 13, 14, 0,
252
  9, 10, 11, 12, 13, 14, 0, 1,
253
  10, 11, 12, 13, 14, 0, 1, 2,
254
  11, 12, 13, 14, 0, 1, 2, 3,
255
  12, 13, 14, 0, 1, 2, 3, 4,
256
  13, 14, 0, 1, 2, 3, 4, 5,
257
  14, 0, 1, 2, 3, 4, 5, 6,
258
  0, 1, 2, 3, 4, 5, 6, 7
259
};
260
 
261
static const uint64_t diag2board_table[15] = {
262
  0x8040201008040201ull,
263
  0x0080402010080402ull,
264
  0x0000804020100804ull,
265
  0x0000008040201008ull,
266
  0x0000000080402010ull,
267
  0x0000000000804020ull,
268
  0x0000000000008040ull,
269
  0x0000000000000080ull,
270
  0x0100000000000000ull,
271
  0x0201000000000000ull,
272
  0x0402010000000000ull,
273
  0x0804020100000000ull,
274
  0x1008040201000000ull,
275
  0x2010080402010000ull,
276
  0x4020100804020100ull,
277
};
278
 
279
static const uint64_t anti2board_table[15] = {
280
  0x0102040810204080ull,
281
  0x0204081020408000ull,
282
  0x0408102040800000ull,
283
  0x0810204080000000ull,
284
  0x1020408000000000ull,
285
  0x2040800000000000ull,
286
  0x4080000000000000ull,
287
  0x8000000000000000ull,
288
  0x0000000000000001ull,
289
  0x0000000000000102ull,
290
  0x0000000000010204ull,
291
  0x0000000001020408ull,
292
  0x0000000102040810ull,
293
  0x0000010204081020ull,
294
  0x0001020408102040ull,
295
};
296
 
297
static inline size_t diag2index(uint64_t b, unsigned d) {
298
  b *= 0x0101010101010101ull;
299
  b >>= 56;
300
  b >>= 1;
301
  return (size_t) b;
302
}
303
 
304
static inline size_t anti2index(uint64_t b, unsigned a) {
305
  return diag2index(b, a);
306
}
307
 
308
#  define diag(s)                 square2diag_table[(s)]
309
#  define anti(s)                 square2anti_table[(s)]
310
#  define diag2board(d)           diag2board_table[(d)]
311
#  define anti2board(a)           anti2board_table[(a)]
312
 
313
static uint64_t bishop_attacks(unsigned sq, uint64_t occ) {
314
  occ &= ~board(sq);
315
  unsigned d = diag(sq), a = anti(sq);
316
  uint64_t d_occ = occ & (diag2board(d) & ~BOARD_EDGE);
317
  uint64_t a_occ = occ & (anti2board(a) & ~BOARD_EDGE);
318
  size_t d_idx = diag2index(d_occ, d);
319
  size_t a_idx = anti2index(a_occ, a);
320
  uint64_t d_attacks = diag_attacks_table[sq][d_idx];
321
  uint64_t a_attacks = anti_attacks_table[sq][a_idx];
322
  return d_attacks | a_attacks;
323
}
324
 
325
static void bishop_attacks_init(void) {
326
  for (unsigned idx = 0; idx < 64; idx++) {
327
    unsigned idx1 = idx << 1;
328
    for (unsigned s = 0; s < 64; s++) {
329
      int r = rank(s);
330
      int f = file(s);
331
      uint64_t b = 0;
332
      for (int i = -1; f + i >= 0 && r + i >= 0; i--) {
333
        unsigned occ = (1 << (f + i));
334
        b |= board(square(r + i, f + i));
335
        if (idx1 & occ)
336
          break;
337
      }
338
      for (int i = 1; f + i <= 7 && r + i <= 7; i++) {
339
        unsigned occ = (1 << (f + i));
340
        b |= board(square(r + i, f + i));
341
        if (idx1 & occ)
342
          break;
343
      }
344
      diag_attacks_table[s][idx] = b;
345
    }
346
  }
347
 
348
  for (unsigned idx = 0; idx < 64; idx++) {
349
    unsigned idx1 = idx << 1;
350
    for (unsigned s = 0; s < 64; s++) {
351
      int r = rank(s);
352
      int f = file(s);
353
      uint64_t b = 0;
354
      for (int i = -1; f + i >= 0 && r - i <= 7; i--) {
355
        unsigned occ = (1 << (f + i));
356
        b |= board(square(r - i, f + i));
357
        if (idx1 & occ)
358
          break;
359
      }
360
      for (int i = 1; f + i <= 7 && r - i >= 0; i++) {
361
        unsigned occ = (1 << (f + i));
362
        b |= board(square(r - i, f + i));
363
        if (idx1 & occ)
364
          break;
365
      }
366
      anti_attacks_table[s][idx] = b;
367
    }
368
  }
369
}
370
 
371
#endif                          /* TB_BISHOP_ATTACKS */
372
 
373
#ifdef TB_ROOK_ATTACKS
374
#  define rook_attacks(s, occ)    TB_ROOK_ATTACKS(s, occ)
375
#  define rook_attacks_init()
376
                            /* NOP */
377
#else                           /* TB_ROOK_ATTACKS */
378
 
379
static uint64_t rank_attacks_table[64][64];
380
static uint64_t file_attacks_table[64][64];
381
 
382
static inline size_t rank2index(uint64_t b, unsigned r) {
383
  b >>= (8 * r);
384
  b >>= 1;
385
  return (size_t) b;
386
}
387
 
388
static inline size_t file2index(uint64_t b, unsigned f) {
389
  b >>= f;
390
  b *= 0x0102040810204080ull;
391
  b >>= 56;
392
  b >>= 1;
393
  return (size_t) b;
394
}
395
 
396
#  define rank2board(r)           (0xFFull << (8 * (r)))
397
#  define file2board(f)           (0x0101010101010101ull << (f))
398
 
399
static uint64_t rook_attacks(unsigned sq, uint64_t occ) {
400
  occ &= ~board(sq);
401
  unsigned r = rank(sq), f = file(sq);
402
  uint64_t r_occ = occ & (rank2board(r) & ~BOARD_RANK_EDGE);
403
  uint64_t f_occ = occ & (file2board(f) & ~BOARD_FILE_EDGE);
404
  size_t r_idx = rank2index(r_occ, r);
405
  size_t f_idx = file2index(f_occ, f);
406
  uint64_t r_attacks = rank_attacks_table[sq][r_idx];
407
  uint64_t f_attacks = file_attacks_table[sq][f_idx];
408
  return r_attacks | f_attacks;
409
}
410
 
411
static void rook_attacks_init(void) {
412
  for (unsigned idx = 0; idx < 64; idx++) {
413
    unsigned idx1 = idx << 1, occ;
414
    for (int f = 0; f <= 7; f++) {
415
      uint64_t b = 0;
416
      if (f > 0) {
417
        int i = f - 1;
418
        do {
419
          occ = (1 << i);
420
          b |= board(square(0, i));
421
          i--;
422
        }
423
        while (!(idx1 & occ) && i >= 0);
424
      }
425
      if (f < 7) {
426
        int i = f + 1;
427
        do {
428
          occ = (1 << i);
429
          b |= board(square(0, i));
430
          i++;
431
        }
432
        while (!(idx1 & occ) && i <= 7);
433
      }
434
      for (int r = 0; r <= 7; r++) {
435
        rank_attacks_table[square(r, f)][idx] = b;
436
        b <<= 8;
437
      }
438
    }
439
  }
440
  for (unsigned idx = 0; idx < 64; idx++) {
441
    unsigned idx1 = idx << 1, occ;
442
    for (int r = 0; r <= 7; r++) {
443
      uint64_t b = 0;
444
      if (r > 0) {
445
        int i = r - 1;
446
        do {
447
          occ = (1 << i);
448
          b |= board(square(i, 0));
449
          i--;
450
        }
451
        while (!(idx1 & occ) && i >= 0);
452
      }
453
      if (r < 7) {
454
        int i = r + 1;
455
        do {
456
          occ = (1 << i);
457
          b |= board(square(i, 0));
458
          i++;
459
        }
460
        while (!(idx1 & occ) && i <= 7);
461
      }
462
      for (int f = 0; f <= 7; f++) {
463
        file_attacks_table[square(r, f)][idx] = b;
464
        b <<= 1;
465
      }
466
    }
467
  }
468
}
469
 
470
#endif                          /* TB_ROOK_ATTACKS */
471
 
472
#ifdef TB_QUEEN_ATTACKS
473
#  define queen_attacks(s, occ)   TB_QUEEN_ATTACKS(s, occ)
474
#else                           /* TB_QUEEN_ATTACKS */
475
#  define queen_attacks(s, occ)   \
476
    (rook_attacks((s), (occ)) | bishop_attacks((s), (occ)))
477
#endif                          /* TB_QUEEN_ATTACKS */
478
 
479
#ifdef TB_PAWN_ATTACKS
480
#  define pawn_attacks(s, c)      TB_PAWN_ATTACKS(s, c)
481
#  define pawn_attacks_init()
482
                            /* NOP */
483
#else                           /* TB_PAWN_ATTACKS */
484
 
485
static uint64_t pawn_attacks_table[2][64];
486
 
487
#  define pawn_attacks(s, c)      pawn_attacks_table[(c)][(s)]
488
 
489
static void pawn_attacks_init(void) {
490
  for (unsigned s = 0; s < 64; s++) {
491
    int r = rank(s);
492
    int f = file(s);
493
 
494
    uint64_t b = 0;
495
    if (r != 7) {
496
      if (f != 0)
497
        b |= board(square(r + 1, f - 1));
498
      if (f != 7)
499
        b |= board(square(r + 1, f + 1));
500
    }
501
    pawn_attacks_table[1][s] = b;
502
 
503
    b = 0;
504
    if (r != 0) {
505
      if (f != 0)
506
        b |= board(square(r - 1, f - 1));
507
      if (f != 7)
508
        b |= board(square(r - 1, f + 1));
509
    }
510
    pawn_attacks_table[0][s] = b;
511
  }
512
}
513
 
514
#endif                          /* TB_PAWN_ATTACKS */
515
 
516
static void prt_str(const struct pos *pos, char *str, bool mirror) {
517
  uint64_t white = pos->white, black = pos->black;
518
  int i;
519
  if (mirror) {
520
    uint64_t tmp = white;
521
    white = black;
522
    black = tmp;
523
  }
524
  *str++ = 'K';
525
  for (i = popcount(white & pos->queens); i > 0; i--)
526
    *str++ = 'Q';
527
  for (i = popcount(white & pos->rooks); i > 0; i--)
528
    *str++ = 'R';
529
  for (i = popcount(white & pos->bishops); i > 0; i--)
530
    *str++ = 'B';
531
  for (i = popcount(white & pos->knights); i > 0; i--)
532
    *str++ = 'N';
533
  for (i = popcount(white & pos->pawns); i > 0; i--)
534
    *str++ = 'P';
535
  *str++ = 'v';
536
  *str++ = 'K';
537
  for (i = popcount(black & pos->queens); i > 0; i--)
538
    *str++ = 'Q';
539
  for (i = popcount(black & pos->rooks); i > 0; i--)
540
    *str++ = 'R';
541
  for (i = popcount(black & pos->bishops); i > 0; i--)
542
    *str++ = 'B';
543
  for (i = popcount(black & pos->knights); i > 0; i--)
544
    *str++ = 'N';
545
  for (i = popcount(black & pos->pawns); i > 0; i--)
546
    *str++ = 'P';
547
  *str++ = '\0';
548
}
549
 
550
/*
551
 * Given a position, produce a 64-bit material signature key.
552
 */
553
static uint64_t calc_key(const struct pos *pos, bool mirror) {
554
  uint64_t white = pos->white, black = pos->black;
555
  if (mirror) {
556
    uint64_t tmp = white;
557
    white = black;
558
    black = tmp;
559
  }
560
  return popcount(white & pos->queens) * PRIME_WHITE_QUEEN +
561
      popcount(white & pos->rooks) * PRIME_WHITE_ROOK +
562
      popcount(white & pos->bishops) * PRIME_WHITE_BISHOP +
563
      popcount(white & pos->knights) * PRIME_WHITE_KNIGHT +
564
      popcount(white & pos->pawns) * PRIME_WHITE_PAWN +
565
      popcount(black & pos->queens) * PRIME_BLACK_QUEEN +
566
      popcount(black & pos->rooks) * PRIME_BLACK_ROOK +
567
      popcount(black & pos->bishops) * PRIME_BLACK_BISHOP +
568
      popcount(black & pos->knights) * PRIME_BLACK_KNIGHT +
569
      popcount(black & pos->pawns) * PRIME_BLACK_PAWN;
570
}
571
 
572
static uint64_t calc_key_from_pcs(int *pcs, int mirror) {
573
  mirror = (mirror ? 8 : 0);
574
  return pcs[WHITE_QUEEN ^ mirror] * PRIME_WHITE_QUEEN +
575
      pcs[WHITE_ROOK ^ mirror] * PRIME_WHITE_ROOK +
576
      pcs[WHITE_BISHOP ^ mirror] * PRIME_WHITE_BISHOP +
577
      pcs[WHITE_KNIGHT ^ mirror] * PRIME_WHITE_KNIGHT +
578
      pcs[WHITE_PAWN ^ mirror] * PRIME_WHITE_PAWN +
579
      pcs[BLACK_QUEEN ^ mirror] * PRIME_BLACK_QUEEN +
580
      pcs[BLACK_ROOK ^ mirror] * PRIME_BLACK_ROOK +
581
      pcs[BLACK_BISHOP ^ mirror] * PRIME_BLACK_BISHOP +
582
      pcs[BLACK_KNIGHT ^ mirror] * PRIME_BLACK_KNIGHT +
583
      pcs[BLACK_PAWN ^ mirror] * PRIME_BLACK_PAWN;
584
}
585
 
586
static uint64_t get_pieces(const struct pos *pos, uint8_t code) {
587
  switch (code) {
588
    case WHITE_KING:
589
      return pos->kings & pos->white;
590
    case WHITE_QUEEN:
591
      return pos->queens & pos->white;
592
    case WHITE_ROOK:
593
      return pos->rooks & pos->white;
594
    case WHITE_BISHOP:
595
      return pos->bishops & pos->white;
596
    case WHITE_KNIGHT:
597
      return pos->knights & pos->white;
598
    case WHITE_PAWN:
599
      return pos->pawns & pos->white;
600
    case BLACK_KING:
601
      return pos->kings & pos->black;
602
    case BLACK_QUEEN:
603
      return pos->queens & pos->black;
604
    case BLACK_ROOK:
605
      return pos->rooks & pos->black;
606
    case BLACK_BISHOP:
607
      return pos->bishops & pos->black;
608
    case BLACK_KNIGHT:
609
      return pos->knights & pos->black;
610
    case BLACK_PAWN:
611
      return pos->pawns & pos->black;
612
    default:
613
      return 0; // Dummy.
614
  }
615
}
616
 
617
static int probe_wdl_table(const struct pos *pos, int *success) {
618
  struct TBEntry *ptr;
619
  struct TBHashEntry *ptr2;
620
  uint64_t idx;
621
  uint64_t key;
622
  int i;
623
  uint8_t res;
624
  int p[TBPIECES];
625
 
626
 // Obtain the position's material signature key.
627
  key = calc_key(pos, false);
628
 
629
 // Test for KvK.
630
  if (key == KEY_KvK)
631
    return 0;
632
 
633
  ptr2 = TB_hash[key >> (64 - TBHASHBITS)];
634
  for (i = 0; i < HSHMAX; i++) {
635
    if (ptr2[i].key == key)
636
      break;
637
  }
638
  if (i == HSHMAX) {
639
    *success = 0;
640
    return 0;
641
  }
642
 
643
  ptr = ptr2[i].ptr;
644
  if (!ptr->ready) {
645
    LOCK(TB_MUTEX);
646
    if (!ptr->ready) {
647
      char str[16];
648
      prt_str(pos, str, ptr->key != key);
649
      if (!init_table_wdl(ptr, str)) {
650
        ptr2[i].key = 0ULL;
651
        *success = 0;
652
        UNLOCK(TB_MUTEX);
653
        return 0;
654
      }
655
     // Memory barrier to ensure ptr->ready = 1 is not reordered.
656
#ifdef _MSC_VER
657
      MemoryBarrier (); // Pierre-Marie Baty -- Win32 equivalent
658
#else
659
      __asm__ __volatile__("":::"memory");
660
#endif // _MSC_VER
661
      ptr->ready = 1;
662
    }
663
    UNLOCK(TB_MUTEX);
664
  }
665
 
666
  int bside, mirror, cmirror;
667
  if (!ptr->symmetric) {
668
    if (key != ptr->key) {
669
      cmirror = 8;
670
      mirror = 0x38;
671
      bside = pos->turn;
672
    } else {
673
      cmirror = mirror = 0;
674
      bside = !pos->turn;
675
    }
676
  } else {
677
    cmirror = (pos->turn ? 0 : 8);
678
    mirror = (pos->turn ? 0 : 0x38);
679
    bside = 0;
680
  }
681
 
682
 // p[i] is to contain the square 0-63 (A1-H8) for a piece of type
683
 // pc[i] ^ cmirror, where 1 = white pawn, ..., 14 = black king.
684
 // Pieces of the same type are guaranteed to be consecutive.
685
  if (!ptr->has_pawns) {
686
    struct TBEntry_piece *entry = (struct TBEntry_piece *) ptr;
687
    uint8_t *pc = entry->pieces[bside];
688
    for (i = 0; i < entry->num;) {
689
      uint64_t bb = get_pieces(pos, pc[i] ^ cmirror);
690
      do {
691
        p[i++] = _lsb(bb);
692
        bb = poplsb(bb);
693
      } while (bb);
694
    }
695
    idx = encode_piece(entry, entry->norm[bside], p, entry->factor[bside]);
696
    res = decompress_pairs(entry->precomp[bside], idx);
697
  } else {
698
    struct TBEntry_pawn *entry = (struct TBEntry_pawn *) ptr;
699
    int k = entry->file[0].pieces[0][0] ^ cmirror;
700
    uint64_t bb = get_pieces(pos, k);
701
    i = 0;
702
    do {
703
      p[i++] = _lsb(bb) ^ mirror;
704
      bb = poplsb(bb);
705
    } while (bb);
706
    int f = pawn_file(entry, p);
707
    uint8_t *pc = entry->file[f].pieces[bside];
708
    for (; i < entry->num;) {
709
      bb = get_pieces(pos, pc[i] ^ cmirror);
710
      do {
711
        p[i++] = _lsb(bb) ^ mirror;
712
        bb = poplsb(bb);
713
      } while (bb);
714
    }
715
    idx =
716
        encode_pawn(entry, entry->file[f].norm[bside], p,
717
        entry->file[f].factor[bside]);
718
    res = decompress_pairs(entry->file[f].precomp[bside], idx);
719
  }
720
 
721
  return ((int) res) - 2;
722
}
723
 
724
static int probe_dtz_table(const struct pos *pos, int wdl, int *success) {
725
  struct TBEntry *ptr;
726
  uint64_t idx;
727
  int i, res;
728
  int p[TBPIECES];
729
 
730
 // Obtain the position's material signature key.
731
  uint64_t key = calc_key(pos, false);
732
 
733
  if (DTZ_table[0].key1 != key && DTZ_table[0].key2 != key) {
734
    for (i = 1; i < DTZ_ENTRIES; i++) {
735
      if (DTZ_table[i].key1 == key || DTZ_table[i].key2 == key)
736
        break; //new
737
     /*if (DTZ_table[i].key1 == key)
738
        break; *///mfb old
739
    }
740
    if (i < DTZ_ENTRIES) {
741
      struct DTZTableEntry table_entry = DTZ_table[i];
742
      for (; i > 0; i--)
743
        DTZ_table[i] = DTZ_table[i - 1];
744
      DTZ_table[0] = table_entry;
745
    } else {
746
      struct TBHashEntry *ptr2 = TB_hash[key >> (64 - TBHASHBITS)];
747
      for (i = 0; i < HSHMAX; i++) {
748
        if (ptr2[i].key == key)
749
          break;
750
      }
751
      if (i == HSHMAX) {
752
        *success = 0;
753
        return 0;
754
      }
755
      ptr = ptr2[i].ptr;
756
      char str[16];
757
      int mirror = (ptr->key != key);
758
      prt_str(pos, str, mirror);
759
      if (DTZ_table[DTZ_ENTRIES - 1].entry)
760
        free_dtz_entry(DTZ_table[DTZ_ENTRIES - 1].entry);
761
      for (i = DTZ_ENTRIES - 1; i > 0; i--)
762
        DTZ_table[i] = DTZ_table[i - 1];
763
      uint64_t key1 = calc_key(pos, mirror);
764
      uint64_t key2 = calc_key(pos, !mirror);
765
      load_dtz_table(str, key1, key2);
766
    }
767
  }
768
 
769
  ptr = DTZ_table[0].entry;
770
  if (!ptr) {
771
    *success = 0;
772
    return 0;
773
  }
774
 
775
  int bside, mirror, cmirror;
776
  if (!ptr->symmetric) {
777
    if (key != ptr->key) {
778
      cmirror = 8;
779
      mirror = 0x38;
780
      bside = pos->turn;
781
    } else {
782
      cmirror = mirror = 0;
783
      bside = !pos->turn;
784
    }
785
  } else {
786
    cmirror = (pos->turn ? 0 : 8);
787
    mirror = (pos->turn ? 0 : 0x38);
788
    bside = 0;
789
  }
790
 
791
  if (!ptr->has_pawns) {
792
    struct DTZEntry_piece *entry = (struct DTZEntry_piece *) ptr;
793
    if ((entry->flags & 1) != bside && !entry->symmetric) {
794
      *success = -1;
795
      return 0;
796
    }
797
    uint8_t *pc = entry->pieces;
798
    for (i = 0; i < entry->num;) {
799
      uint64_t bb = get_pieces(pos, pc[i] ^ cmirror);
800
      do {
801
        p[i++] = _lsb(bb);
802
        bb = poplsb(bb);
803
      }
804
      while (bb);
805
    }
806
    idx =
807
        encode_piece((struct TBEntry_piece *) entry, entry->norm, p,
808
        entry->factor);
809
    res = decompress_pairs(entry->precomp, idx);
810
 
811
    if (entry->flags & 2)
812
      res = entry->map[entry->map_idx[wdl_to_map[wdl + 2]] + res];
813
    if (!(entry->flags & pa_flags[wdl + 2]) || (wdl & 1))
814
      res *= 2;
815
  } else {
816
    struct DTZEntry_pawn *entry = (struct DTZEntry_pawn *) ptr;
817
    int k = entry->file[0].pieces[0] ^ cmirror;
818
    uint64_t bb = get_pieces(pos, k);
819
    i = 0;
820
    do {
821
      p[i++] = _lsb(bb) ^ mirror;
822
      bb = poplsb(bb);
823
    }
824
    while (bb);
825
    int f = pawn_file((struct TBEntry_pawn *) entry, p);
826
    if ((entry->flags[f] & 1) != bside) {
827
      *success = -1;
828
      return 0;
829
    }
830
    uint8_t *pc = entry->file[f].pieces;
831
    for (; i < entry->num;) {
832
      bb = get_pieces(pos, pc[i] ^ cmirror);
833
      do {
834
        p[i++] = _lsb(bb) ^ mirror;
835
        bb = poplsb(bb);
836
      }
837
      while (bb);
838
    }
839
    idx =
840
        encode_pawn((struct TBEntry_pawn *) entry, entry->file[f].norm, p,
841
        entry->file[f].factor);
842
    res = decompress_pairs(entry->file[f].precomp, idx);
843
 
844
    if (entry->flags[f] & 2)
845
      res = entry->map[entry->map_idx[f][wdl_to_map[wdl + 2]] + res];
846
    if (!(entry->flags[f] & pa_flags[wdl + 2]) || (wdl & 1))
847
      res *= 2;
848
  }
849
 
850
  return res;
851
}
852
 
853
static uint16_t *add_move(uint16_t * moves, bool promotes, unsigned from,
854
    unsigned to) {
855
  if (!promotes)
856
    *moves++ = make_move(TB_PROMOTES_NONE, from, to);
857
  else {
858
    *moves++ = make_move(TB_PROMOTES_QUEEN, from, to);
859
    *moves++ = make_move(TB_PROMOTES_KNIGHT, from, to);
860
    *moves++ = make_move(TB_PROMOTES_ROOK, from, to);
861
    *moves++ = make_move(TB_PROMOTES_BISHOP, from, to);
862
  }
863
  return moves;
864
}
865
 
866
/*
867
 * Generate all captures or promotions.
868
 */
869
static uint16_t *gen_captures_or_promotions(const struct pos *pos,
870
    uint16_t * moves) {
871
  uint64_t occ = pos->white | pos->black;
872
  uint64_t us = (pos->turn ? pos->white : pos->black), them =
873
      (pos->turn ? pos->black : pos->white);
874
  uint64_t b, att;
875
  {
876
    unsigned from = _lsb(pos->kings & us);
877
    for (att = king_attacks(from) & them; att; att = poplsb(att)) {
878
      unsigned to = _lsb(att);
879
      moves = add_move(moves, false, from, to);
880
    }
881
  }
882
  for (b = us & pos->queens; b; b = poplsb(b)) {
883
    unsigned from = _lsb(b);
884
    for (att = queen_attacks(from, occ) & them; att; att = poplsb(att)) {
885
      unsigned to = _lsb(att);
886
      moves = add_move(moves, false, from, to);
887
    }
888
  }
889
  for (b = us & pos->rooks; b; b = poplsb(b)) {
890
    unsigned from = _lsb(b);
891
    for (att = rook_attacks(from, occ) & them; att; att = poplsb(att)) {
892
      unsigned to = _lsb(att);
893
      moves = add_move(moves, false, from, to);
894
    }
895
  }
896
  for (b = us & pos->bishops; b; b = poplsb(b)) {
897
    unsigned from = _lsb(b);
898
    for (att = bishop_attacks(from, occ) & them; att; att = poplsb(att)) {
899
      unsigned to = _lsb(att);
900
      moves = add_move(moves, false, from, to);
901
    }
902
  }
903
  for (b = us & pos->knights; b; b = poplsb(b)) {
904
    unsigned from = _lsb(b);
905
    for (att = knight_attacks(from) & them; att; att = poplsb(att)) {
906
      unsigned to = _lsb(att);
907
      moves = add_move(moves, false, from, to);
908
    }
909
  }
910
  for (b = us & pos->pawns; b; b = poplsb(b)) {
911
    unsigned from = _lsb(b);
912
    att = pawn_attacks(from, pos->turn);
913
    if (pos->ep != 0 && ((att & board(pos->ep)) != 0)) {
914
      unsigned to = pos->ep;
915
      moves = add_move(moves, false, from, to);
916
    }
917
    for (att = att & them; att; att = poplsb(att)) {
918
      unsigned to = _lsb(att);
919
      moves = add_move(moves, (rank(to) == 7 || rank(to) == 0), from, to);
920
    }
921
    if (pos->turn && rank(from) == 6) {
922
      unsigned to = from + 8;
923
      if ((board(to) & occ) == 0)
924
        moves = add_move(moves, true, from, to);
925
    } else if (!pos->turn && rank(from) == 1) {
926
      unsigned to = from - 8;
927
      if ((board(to) & occ) == 0)
928
        moves = add_move(moves, true, from, to);
929
    }
930
  }
931
  return moves;
932
}
933
 
934
/*
935
 * Generate all non-capture pawn moves and promotions.
936
 */
937
static uint16_t *gen_pawn_quiets_or_promotions(const struct pos *pos,
938
    uint16_t * moves) {
939
  uint64_t occ = pos->white | pos->black;
940
  uint64_t us = (pos->turn ? pos->white : pos->black);
941
  uint64_t b, att;
942
 
943
  for (b = us & pos->pawns; b; b = poplsb(b)) {
944
    unsigned from = _lsb(b);
945
    unsigned next = from + (pos->turn ? 8 : -8);
946
    att = 0;
947
    if ((board(next) & occ) == 0) {
948
      att |= board(next);
949
      unsigned next2 = from + (pos->turn ? 16 : -16);
950
      if ((pos->turn ? rank(from) == 1 : rank(from) == 6) &&
951
          ((board(next2) & occ) == 0))
952
        att |= board(next2);
953
    }
954
    for (; att; att = poplsb(att)) {
955
      unsigned to = _lsb(att);
956
      moves = add_move(moves, (rank(to) == 7 || rank(to) == 0), from, to);
957
    }
958
  }
959
  return moves;
960
}
961
 
962
/*
963
 * Generate all en passant captures.
964
 */
965
static uint16_t *gen_pawn_ep_captures(const struct pos *pos, uint16_t * moves) {
966
  if (pos->ep == 0)
967
    return moves;
968
  uint64_t ep = board(pos->ep);
969
  unsigned to = pos->ep;
970
  uint64_t us = (pos->turn ? pos->white : pos->black);
971
  uint64_t b;
972
  for (b = us & pos->pawns; b; b = poplsb(b)) {
973
    unsigned from = _lsb(b);
974
    if ((pawn_attacks(from, pos->turn) & ep) != 0)
975
      moves = add_move(moves, false, from, to);
976
  }
977
  return moves;
978
}
979
 
980
/*
981
 * Generate all moves.
982
 */
983
static uint16_t *gen_moves(const struct pos *pos, uint16_t * moves) {
984
  uint64_t occ = pos->white | pos->black;
985
  uint64_t us = (pos->turn ? pos->white : pos->black), them =
986
      (pos->turn ? pos->black : pos->white);
987
  uint64_t b, att;
988
 
989
  {
990
    unsigned from = _lsb(pos->kings & us);
991
    for (att = king_attacks(from) & ~us; att; att = poplsb(att)) {
992
      unsigned to = _lsb(att);
993
      moves = add_move(moves, false, from, to);
994
    }
995
  }
996
  for (b = us & pos->queens; b; b = poplsb(b)) {
997
    unsigned from = _lsb(b);
998
    for (att = queen_attacks(from, occ) & ~us; att; att = poplsb(att)) {
999
      unsigned to = _lsb(att);
1000
      moves = add_move(moves, false, from, to);
1001
    }
1002
  }
1003
  for (b = us & pos->rooks; b; b = poplsb(b)) {
1004
    unsigned from = _lsb(b);
1005
    for (att = rook_attacks(from, occ) & ~us; att; att = poplsb(att)) {
1006
      unsigned to = _lsb(att);
1007
      moves = add_move(moves, false, from, to);
1008
    }
1009
  }
1010
  for (b = us & pos->bishops; b; b = poplsb(b)) {
1011
    unsigned from = _lsb(b);
1012
    for (att = bishop_attacks(from, occ) & ~us; att; att = poplsb(att)) {
1013
      unsigned to = _lsb(att);
1014
      moves = add_move(moves, false, from, to);
1015
    }
1016
  }
1017
  for (b = us & pos->knights; b; b = poplsb(b)) {
1018
    unsigned from = _lsb(b);
1019
    for (att = knight_attacks(from) & ~us; att; att = poplsb(att)) {
1020
      unsigned to = _lsb(att);
1021
      moves = add_move(moves, false, from, to);
1022
    }
1023
  }
1024
  for (b = us & pos->pawns; b; b = poplsb(b)) {
1025
    unsigned from = _lsb(b);
1026
    unsigned next = from + (pos->turn ? 8 : -8);
1027
    att = pawn_attacks(from, pos->turn);
1028
    if (pos->ep != 0 && ((att & board(pos->ep)) != 0)) {
1029
      unsigned to = pos->ep;
1030
      moves = add_move(moves, false, from, to);
1031
    }
1032
    att &= them;
1033
    if ((board(next) & occ) == 0) {
1034
      att |= board(next);
1035
      unsigned next2 = from + (pos->turn ? 16 : -16);
1036
      if ((pos->turn ? rank(from) == 1 : rank(from) == 6) &&
1037
          ((board(next2) & occ) == 0))
1038
        att |= board(next2);
1039
    }
1040
    for (; att; att = poplsb(att)) {
1041
      unsigned to = _lsb(att);
1042
      moves = add_move(moves, (rank(to) == 7 || rank(to) == 0), from, to);
1043
    }
1044
  }
1045
  return moves;
1046
}
1047
 
1048
/*
1049
 * Test if the given move is an en passant capture.
1050
 */
1051
static bool is_en_passant(const struct pos *pos, uint16_t move) {
1052
  uint16_t from = move_from(move);
1053
  uint16_t to = move_to(move);
1054
  uint64_t us = (pos->turn ? pos->white : pos->black);
1055
  if (pos->ep == 0)
1056
    return false;
1057
  if (to != pos->ep)
1058
    return false;
1059
  if ((board(from) & us & pos->pawns) != 0)
1060
    return false;
1061
  return true;
1062
}
1063
 
1064
/*
1065
 * Test if the given position is legal (can the king be captured?)
1066
 */
1067
static bool is_legal(const struct pos *pos) {
1068
  uint64_t occ = pos->white | pos->black;
1069
  uint64_t us = (pos->turn ? pos->black : pos->white), them =
1070
      (pos->turn ? pos->white : pos->black);
1071
  uint64_t king = pos->kings & us;
1072
  unsigned sq = _lsb(king);
1073
  if (king_attacks(sq) & (pos->kings & them))
1074
    return false;
1075
  uint64_t ratt = rook_attacks(sq, occ);
1076
  uint64_t batt = bishop_attacks(sq, occ);
1077
  if (ratt & (pos->rooks & them))
1078
    return false;
1079
  if (batt & (pos->bishops & them))
1080
    return false;
1081
  if ((ratt | batt) & (pos->queens & them))
1082
    return false;
1083
  if (knight_attacks(sq) & (pos->knights & them))
1084
    return false;
1085
  if (pawn_attacks(sq, !pos->turn) & (pos->pawns & them))
1086
    return false;
1087
  return true;
1088
}
1089
 
1090
/*
1091
 * Test if the king is in check.
1092
 */
1093
static bool is_check(const struct pos *pos) {
1094
  uint64_t occ = pos->white | pos->black;
1095
  uint64_t us = (pos->turn ? pos->white : pos->black), them =
1096
      (pos->turn ? pos->black : pos->white);
1097
  uint64_t king = pos->kings & us;
1098
  unsigned sq = _lsb(king);
1099
  uint64_t ratt = rook_attacks(sq, occ);
1100
  uint64_t batt = bishop_attacks(sq, occ);
1101
  if (ratt & (pos->rooks & them))
1102
    return true;
1103
  if (batt & (pos->bishops & them))
1104
    return true;
1105
  if ((ratt | batt) & (pos->queens & them))
1106
    return true;
1107
  if (knight_attacks(sq) & (pos->knights & them))
1108
    return true;
1109
  if (pawn_attacks(sq, pos->turn) & (pos->pawns & them))
1110
    return true;
1111
  return false;
1112
}
1113
 
1114
/*
1115
 * Test if the king is in checkmate.
1116
 */
1117
static bool is_mate(const struct pos *pos) {
1118
  if (!is_check(pos))
1119
    return false;
1120
  uint16_t moves0[MAX_MOVES];
1121
  uint16_t *moves = moves0;
1122
  uint16_t *end = gen_moves(pos, moves);
1123
  for (; moves < end; moves++) {
1124
    struct pos pos1;
1125
    if (do_move(&pos1, pos, *moves))
1126
      return false;
1127
  }
1128
  return true;
1129
}
1130
 
1131
/*
1132
 * Test if the position is valid.
1133
 */
1134
static bool is_valid(const struct pos *pos) {
1135
  if (popcount(pos->kings) != 2)
1136
    return false;
1137
  if (popcount(pos->kings & pos->white) != 1)
1138
    return false;
1139
  if (popcount(pos->kings & pos->black) != 1)
1140
    return false;
1141
  if ((pos->white & pos->black) != 0)
1142
    return false;
1143
  if ((pos->kings & pos->queens) != 0)
1144
    return false;
1145
  if ((pos->kings & pos->rooks) != 0)
1146
    return false;
1147
  if ((pos->kings & pos->bishops) != 0)
1148
    return false;
1149
  if ((pos->kings & pos->knights) != 0)
1150
    return false;
1151
  if ((pos->kings & pos->pawns) != 0)
1152
    return false;
1153
  if ((pos->queens & pos->rooks) != 0)
1154
    return false;
1155
  if ((pos->queens & pos->bishops) != 0)
1156
    return false;
1157
  if ((pos->queens & pos->knights) != 0)
1158
    return false;
1159
  if ((pos->queens & pos->pawns) != 0)
1160
    return false;
1161
  if ((pos->rooks & pos->bishops) != 0)
1162
    return false;
1163
  if ((pos->rooks & pos->knights) != 0)
1164
    return false;
1165
  if ((pos->rooks & pos->pawns) != 0)
1166
    return false;
1167
  if ((pos->bishops & pos->knights) != 0)
1168
    return false;
1169
  if ((pos->bishops & pos->pawns) != 0)
1170
    return false;
1171
  if ((pos->knights & pos->pawns) != 0)
1172
    return false;
1173
  if ((pos->white | pos->black) !=
1174
      (pos->kings | pos->queens | pos->rooks | pos->
1175
          bishops | pos->knights | pos->pawns))
1176
    return false;
1177
  return is_legal(pos);
1178
}
1179
 
1180
#define do_bb_move(b, from, to)                                         \
1181
    (((b) & (~board(to)) & (~board(from))) |                            \
1182
        ((((b) >> (from)) & 0x1) << (to)))
1183
 
1184
static bool do_move(struct pos *pos, const struct pos *pos0, uint16_t move) {
1185
  unsigned from = move_from(move);
1186
  unsigned to = move_to(move);
1187
  unsigned promotes = move_promotes(move);
1188
  pos->turn = !pos0->turn;
1189
  pos->white = do_bb_move(pos0->white, from, to);
1190
  pos->black = do_bb_move(pos0->black, from, to);
1191
  pos->kings = do_bb_move(pos0->kings, from, to);
1192
  pos->queens = do_bb_move(pos0->queens, from, to);
1193
  pos->rooks = do_bb_move(pos0->rooks, from, to);
1194
  pos->bishops = do_bb_move(pos0->bishops, from, to);
1195
  pos->knights = do_bb_move(pos0->knights, from, to);
1196
  pos->pawns = do_bb_move(pos0->pawns, from, to);
1197
  pos->ep = 0;
1198
  if (promotes != TB_PROMOTES_NONE) {
1199
    pos->pawns &= ~board(to); // Promotion
1200
    switch (promotes) {
1201
      case TB_PROMOTES_QUEEN:
1202
        pos->queens |= board(to);
1203
        break;
1204
      case TB_PROMOTES_ROOK:
1205
        pos->rooks |= board(to);
1206
        break;
1207
      case TB_PROMOTES_BISHOP:
1208
        pos->bishops |= board(to);
1209
        break;
1210
      case TB_PROMOTES_KNIGHT:
1211
        pos->knights |= board(to);
1212
        break;
1213
    }
1214
    pos->rule50 = 0;
1215
  } else if ((board(from) & pos0->pawns) != 0) {
1216
    pos->rule50 = 0; // Pawn move
1217
    if (rank(from) == 1 && rank(to) == 3 &&
1218
        (pawn_attacks(from + 8, true) & pos0->pawns & pos0->black) != 0)
1219
      pos->ep = from + 8;
1220
    else if (rank(from) == 6 && rank(to) == 4 &&
1221
        (pawn_attacks(from - 8, false) & pos0->pawns & pos0->white) != 0)
1222
      pos->ep = from - 8;
1223
    else if (to == pos0->ep) {
1224
      unsigned ep_to = (pos0->turn ? to + 8 : to - 8);
1225
      uint64_t ep_mask = ~board(ep_to);
1226
      pos->white &= ep_mask;
1227
      pos->black &= ep_mask;
1228
      pos->pawns &= ep_mask;
1229
    }
1230
  } else if ((board(to) & (pos0->white | pos0->black)) != 0)
1231
    pos->rule50 = 0; // Capture
1232
  else
1233
    pos->rule50 = pos0->rule50 + 1; // Normal move
1234
  if (!is_legal(pos))
1235
    return false;
1236
  return true;
1237
}
1238
 
1239
static int probe_ab(const struct pos *pos, int alpha, int beta, int *success) {
1240
  int v;
1241
  uint16_t moves0[64];
1242
  uint16_t *moves = moves0;
1243
  uint16_t *end = gen_captures_or_promotions(pos, moves);
1244
  for (; moves < end; moves++) {
1245
    if (is_en_passant(pos, *moves))
1246
      continue;
1247
    struct pos pos1;
1248
    if (!do_move(&pos1, pos, *moves))
1249
      continue;
1250
    v = -probe_ab(&pos1, -beta, -alpha, success);
1251
    if (*success == 0)
1252
      return 0;
1253
    if (v > alpha) {
1254
      if (v >= beta) {
1255
        *success = 2;
1256
        return v;
1257
      }
1258
      alpha = v;
1259
    }
1260
  }
1261
 
1262
  v = probe_wdl_table(pos, success);
1263
  if (*success == 0)
1264
    return 0;
1265
  if (alpha >= v) {
1266
    *success = 1 + (alpha > 0);
1267
    return alpha;
1268
  } else {
1269
    *success = 1;
1270
    return v;
1271
  }
1272
}
1273
 
1274
static int probe_wdl(const struct pos *pos, int *success) {
1275
  *success = 1;
1276
  int v = probe_ab(pos, -2, 2, success);
1277
  if (*success == 0)
1278
    return 0;
1279
 
1280
 // If en passant is not possible, we are done.
1281
  if (pos->ep == 0)
1282
    return v;
1283
 
1284
 // Now handle en passant.
1285
  int v1 = -3;
1286
  uint16_t moves0[2];           // Max=2 possible en-passant captures.
1287
  uint16_t *moves = moves0;
1288
  uint16_t *end = gen_pawn_ep_captures(pos, moves);
1289
  for (; moves < end; moves++) {
1290
    struct pos pos1;
1291
    if (!do_move(&pos1, pos, *moves))
1292
      continue;
1293
    int v0 = -probe_ab(pos, -2, 2, success);
1294
    if (*success == 0)
1295
      return 0;
1296
    if (v0 > v1)
1297
      v1 = v0;
1298
  }
1299
  if (v1 > -3) {
1300
    if (v1 >= v)
1301
      v = v1;
1302
    else if (v == 0) {
1303
     // Check whether there is at least one legal non-ep move.
1304
      uint16_t moves0[MAX_MOVES];
1305
      uint16_t *moves = moves0;
1306
      uint16_t *end = gen_moves(pos, moves);
1307
      bool found = false;
1308
      for (; moves < end; moves++) {
1309
        if (is_en_passant(pos, *moves))
1310
          continue;
1311
        struct pos pos1;
1312
        if (do_move(&pos1, pos, *moves)) {
1313
          found = true;
1314
          break;
1315
        }
1316
      }
1317
      if (!found)
1318
        v = v1; // Forced to play the losing ep capture.
1319
    }
1320
  }
1321
 
1322
  return v;
1323
}
1324
 
1325
static int probe_dtz_no_ep(const struct pos *pos, int *success) {
1326
  int wdl, dtz;
1327
  wdl = probe_ab(pos, -2, 2, success);
1328
  if (wdl == 0)
1329
    return 0;
1330
  if (*success == 2)
1331
    return wdl == 2 ? 1 : 101;
1332
 
1333
  uint16_t moves0[MAX_MOVES];
1334
  uint16_t *moves = moves0, *end = NULL;
1335
 
1336
  if (wdl > 0) {
1337
   // Generate at least all legal non-capturing pawn moves
1338
   // including non-capturing promotions.
1339
    end = gen_pawn_quiets_or_promotions(pos, moves);
1340
    for (; moves < end; moves++) {
1341
      struct pos pos1;
1342
      if (!do_move(&pos1, pos, *moves))
1343
        continue;
1344
     //int v = pos.ep_square() == SQ_NONE ? -probe_ab(pos, -2, -wdl + 1, success)
1345
     //                                   : -probe_wdl(pos, success);
1346
     //int v = -probe_ab(&pos1, -2, -wdl + 1, success);removed mfb
1347
      int v = (pos1.ep == 0 ? -probe_ab(&pos1, -2, -wdl + 1, success) : -probe_wdl(&pos1, success)); //added mfb
1348
      if (*success == 0)
1349
        return 0;
1350
      if (v == wdl)
1351
        return (v == 2 ? 1 : 101);
1352
    }
1353
  }
1354
 
1355
  dtz = 1 + probe_dtz_table(pos, wdl, success);
1356
  if (*success >= 0) {
1357
    if (wdl & 1)
1358
      dtz += 100;
1359
    return (wdl >= 0 ? dtz : -dtz);
1360
  }
1361
 
1362
  if (wdl > 0) {
1363
    int best = BEST_NONE;
1364
    moves = moves0;
1365
    end = gen_moves(pos, moves);
1366
    for (; moves < end; moves++) {
1367
      struct pos pos1;
1368
      if (!do_move(&pos1, pos, *moves))
1369
        continue;
1370
      if (pos1.rule50 == 0)
1371
        continue;
1372
      int v = -probe_dtz(&pos1, success);
1373
      if (*success == 0)
1374
        return 0;
1375
      if (v > 0 && v + 1 < best)
1376
        best = v + 1;
1377
    }
1378
    assert(best != BEST_NONE);
1379
    return best;
1380
  } else {
1381
    int best = -1;
1382
    end = gen_moves(pos, moves);
1383
    for (; moves < end; moves++) {
1384
      int v;
1385
      struct pos pos1;
1386
      if (!do_move(&pos1, pos, *moves))
1387
        continue;
1388
      if (pos1.rule50 == 0) {
1389
        if (wdl == -2)
1390
          v = -1;
1391
        else {
1392
          v = probe_ab(&pos1, 1, 2, success);
1393
          v = (v == 2) ? 0 : -101;
1394
        }
1395
      } else
1396
        v = -probe_dtz(&pos1, success) - 1;
1397
      if (*success == 0)
1398
        return 0;
1399
      if (v < best)
1400
        best = v;
1401
    }
1402
    return best;
1403
  }
1404
}
1405
 
1406
static const int wdl_to_dtz[] = {
1407
  -1, -101, 0, 101, 1
1408
};
1409
 
1410
/*
1411
 * Probe the DTZ table for a particular position.
1412
 * If *success != 0, the probe was successful.
1413
 * The return value is from the point of view of the side to move:
1414
 *         n < -100 : loss, but draw under 50-move rule
1415
 * -100 <= n < -1   : loss in n ply (assuming 50-move counter == 0)
1416
 *         0            : draw
1417
 *     1 < n <= 100 : win in n ply (assuming 50-move counter == 0)
1418
 *   100 < n        : win, but draw under 50-move rule
1419
 *
1420
 * The return value n can be off by 1: a return value -n can mean a loss
1421
 * in n+1 ply and a return value +n can mean a win in n+1 ply. This
1422
 * cannot happen for tables with positions exactly on the "edge" of
1423
 * the 50-move rule.
1424
 *
1425
 * This implies that if dtz > 0 is returned, the position is certainly
1426
 * a win if dtz + 50-move-counter <= 99. Care must be taken that the engine
1427
 * picks moves that preserve dtz + 50-move-counter <= 99.
1428
 *
1429
 * If n = 100 immediately after a capture or pawn move, then the position
1430
 * is also certainly a win, and during the whole phase until the next
1431
 * capture or pawn move, the inequality to be preserved is
1432
 * dtz + 50-movecounter <= 100.
1433
 *
1434
 * In short, if a move is available resulting in dtz + 50-move-counter <= 99,
1435
 * then do not accept moves leading to dtz + 50-move-counter == 100.
1436
 */
1437
static int probe_dtz(const struct pos *pos, int *success) {
1438
  *success = 1;
1439
  int v = probe_dtz_no_ep(pos, success);
1440
  if (*success == 0)
1441
    return 0;
1442
 
1443
  if (pos->ep == 0)
1444
    return v;
1445
 
1446
  int v1 = -3;
1447
  uint16_t moves0[2];           // Max=2 possible en-passant captures.
1448
  uint16_t *moves = moves0;
1449
  uint16_t *end = gen_pawn_ep_captures(pos, moves);
1450
  for (; moves < end; moves++) {
1451
    struct pos pos1;
1452
    if (!do_move(&pos1, pos, *moves))
1453
      continue;
1454
    int v0 = -probe_ab(pos, -2, 2, success);
1455
    if (*success == 0)
1456
      return 0;
1457
    if (v0 > v1)
1458
      v1 = v0;
1459
  }
1460
 
1461
  if (v1 > -3) {
1462
    v1 = wdl_to_dtz[v1 + 2];
1463
    if (v < -100) {
1464
      if (v1 >= 0)
1465
        v = v1;
1466
    } else if (v < 0) {
1467
      if (v1 >= 0 || v1 < -100)
1468
        v = v1;
1469
    } else if (v > 100) {
1470
      if (v1 > 0)
1471
        v = v1;
1472
    } else if (v > 0) {
1473
      if (v1 == 1)
1474
        v = v1;
1475
    } else if (v1 >= 0)
1476
      v = v1;
1477
    else {
1478
      uint16_t moves0[MAX_MOVES];
1479
      uint16_t *moves = moves0;
1480
      uint16_t *end = gen_moves(pos, moves);
1481
      bool found = false;
1482
      for (; moves < end; moves++) {
1483
        if (is_en_passant(pos, *moves))
1484
          continue;
1485
        struct pos pos1;
1486
        if (do_move(&pos1, pos, *moves)) {
1487
          found = true;
1488
          break;
1489
        }
1490
      }
1491
      if (!found)
1492
        v = v1; // Forced to play the losing ep capture.
1493
    }
1494
  }
1495
 
1496
  return v;
1497
}
1498
 
1499
unsigned dtz_to_wdl(int cnt50, int dtz) {
1500
  int wdl = 0;
1501
  if (dtz > 0)
1502
    wdl = (dtz + cnt50 <= 100 ? 2 : 1);
1503
  else if (dtz < 0)
1504
    wdl = (-dtz + cnt50 <= 100 ? -2 : -1);
1505
  return wdl + 2;
1506
}
1507
 
1508
static uint16_t probe_root(const struct pos *pos, int *score,
1509
    unsigned *results) {
1510
  int success;
1511
  int dtz = probe_dtz(pos, &success);
1512
  if (!success)
1513
    return 0;
1514
 
1515
  int16_t scores[MAX_MOVES];
1516
  uint16_t moves0[MAX_MOVES];
1517
  uint16_t *moves = moves0;
1518
  uint16_t *end = gen_moves(pos, moves);
1519
  size_t len = end - moves;
1520
  size_t num_draw = 0;
1521
  unsigned j = 0;
1522
  unsigned i = 0;               //mfb
1523
  for (i = 0; i < len; i++) {
1524
    struct pos pos1;
1525
    if (!do_move(&pos1, pos, moves[i])) {
1526
      scores[i] = SCORE_ILLEGAL;
1527
      continue;
1528
    }
1529
    int v = 0;
1530
    if (dtz > 0 && is_mate(&pos1))
1531
      v = 1;
1532
    else {
1533
      if (pos1.rule50 != 0) {
1534
        v = -probe_dtz(&pos1, &success);
1535
        if (v > 0)
1536
          v++;
1537
        else if (v < 0)
1538
          v--;
1539
      } else {
1540
        v = -probe_wdl(&pos1, &success);
1541
        v = wdl_to_dtz[v + 2];
1542
      }
1543
    }
1544
    num_draw += (v == 0);
1545
    if (!success)
1546
      return 0;
1547
    scores[i] = v;
1548
    if (results != NULL) {
1549
      unsigned res = 0;
1550
      res = TB_SET_WDL(res, dtz_to_wdl(pos->rule50, v));
1551
      res = TB_SET_FROM(res, move_from(moves[i]));
1552
      res = TB_SET_TO(res, move_to(moves[i]));
1553
      res = TB_SET_PROMOTES(res, move_promotes(moves[i]));
1554
      res = TB_SET_EP(res, is_en_passant(pos, moves[i]));
1555
      res = TB_SET_DTZ(res, (dtz < 0 ? -dtz : dtz));
1556
      results[j++] = res;
1557
    }
1558
  }
1559
  if (results != NULL)
1560
    results[j++] = TB_RESULT_FAILED;
1561
  if (score != NULL)
1562
    *score = dtz;
1563
 
1564
 // Now be a bit smart about filtering out moves.
1565
  if (dtz > 0) // winning (or 50-move rule draw)
1566
  {
1567
    int best = BEST_NONE;
1568
    uint16_t best_move = 0;
1569
    for (i = 0; i < len; i++) {
1570
      int v = scores[i];
1571
      if (v == SCORE_ILLEGAL)
1572
        continue;
1573
      if (v > 0 && v < best) {
1574
        best = v;
1575
        best_move = moves[i];
1576
      }
1577
    }
1578
    return (best == BEST_NONE ? 0 : best_move);
1579
  } else if (dtz < 0) // losing (or 50-move rule draw)
1580
  {
1581
    int best = 0;
1582
    uint16_t best_move = 0;
1583
    for (i = 0; i < len; i++) {
1584
      int v = scores[i];
1585
      if (v == SCORE_ILLEGAL)
1586
        continue;
1587
      if (v < best) {
1588
        best = v;
1589
        best_move = moves[i];
1590
      }
1591
    }
1592
    return (best == 0 ? MOVE_CHECKMATE : best_move);
1593
  } else // drawing
1594
  {
1595
   // Check for stalemate:
1596
    if (num_draw == 0)
1597
      return MOVE_STALEMATE;
1598
 
1599
   // Select a "random" move that preserves the draw.
1600
   // Uses calc_key as the PRNG.
1601
    size_t count = calc_key(pos, !pos->turn) % num_draw;
1602
    for (i = 0; i < len; i++) {
1603
      int v = scores[i];
1604
      if (v == SCORE_ILLEGAL)
1605
        continue;
1606
      if (v == 0) {
1607
        if (count == 0)
1608
          return moves[i];
1609
        count--;
1610
      }
1611
    }
1612
    return 0;
1613
  }
1614
}
1615
 
1616
extern bool tb_init_impl(const char *path) {
1617
  if (sizeof(uint64_t) != 8 && // Paranoid check
1618
      sizeof(uint32_t) != 4 && sizeof(uint16_t) != 2 && sizeof(uint8_t) != 1)
1619
    return false;
1620
  king_attacks_init();
1621
  knight_attacks_init();
1622
  bishop_attacks_init();
1623
  rook_attacks_init();
1624
  pawn_attacks_init();
1625
  if (path == NULL)
1626
    path = "";
1627
  init_tablebases(path);
1628
  return true;
1629
}
1630
 
1631
extern unsigned tb_probe_wdl_impl(uint64_t white, uint64_t black,
1632
    uint64_t kings, uint64_t queens, uint64_t rooks, uint64_t bishops,
1633
    uint64_t knights, uint64_t pawns, unsigned ep, bool turn, uint64_t hash) {
1634
  struct pos pos = {
1635
    white,
1636
    black,
1637
    kings,
1638
    queens,
1639
    rooks,
1640
    bishops,
1641
    knights,
1642
    pawns,
1643
    0,
1644
    ep,
1645
    turn
1646
  };
1647
  static uint64_t cache[4096] = { 0 };
1648
  uint64_t idx = hash % 1024;
1649
  if ((cache[idx] & ~0x7) == (hash & ~0x7)) {
1650
   // Hit
1651
//        FILE *F = fopen("debug.txt", "a");
1652
//        fprintf(F, "CACHE_HIT = %.16lX (result=%u)\n", cache[idx],
1653
//            (unsigned)(cache[idx] & 0x7));
1654
//        fclose(F);
1655
    return (cache[idx] & 0x7);
1656
  }
1657
 // Miss
1658
  int success;
1659
  int v = probe_wdl(&pos, &success);
1660
  if (success == 0)
1661
    return TB_RESULT_FAILED;
1662
  unsigned result = (unsigned) (v + 2);
1663
  hash &= ~0x7;
1664
  hash |= (uint64_t) result;
1665
  cache[idx] = hash;
1666
  return result;
1667
}
1668
 
1669
extern unsigned tb_probe_root_impl(uint64_t white, uint64_t black,
1670
    uint64_t kings, uint64_t queens, uint64_t rooks, uint64_t bishops,
1671
    uint64_t knights, uint64_t pawns, unsigned rule50, unsigned ep, bool turn,
1672
    unsigned *results) {
1673
  struct pos pos = {
1674
    white,
1675
    black,
1676
    kings,
1677
    queens,
1678
    rooks,
1679
    bishops,
1680
    knights,
1681
    pawns,
1682
    rule50,
1683
    ep,
1684
    turn
1685
  };
1686
  int dtz;
1687
  if (!is_valid(&pos))
1688
    return TB_RESULT_FAILED;
1689
  uint16_t move = probe_root(&pos, &dtz, results);
1690
  if (move == 0)
1691
    return TB_RESULT_FAILED;
1692
  if (move == MOVE_CHECKMATE)
1693
    return TB_RESULT_CHECKMATE;
1694
  if (move == MOVE_STALEMATE)
1695
    return TB_RESULT_STALEMATE;
1696
  unsigned res = 0;
1697
  res = TB_SET_WDL(res, dtz_to_wdl(rule50, dtz));
1698
  res = TB_SET_FROM(res, move_from(move));
1699
  res = TB_SET_TO(res, move_to(move));
1700
  res = TB_SET_PROMOTES(res, move_promotes(move));
1701
  res = TB_SET_EP(res, is_en_passant(&pos, move));
1702
  return res;
1703
}
1704
 
1705
#ifndef TB_NO_HELPER_API
1706
 
1707
unsigned tb_pop_count(uint64_t bb) {
1708
  return popcount(bb);
1709
}
1710
 
1711
unsigned tb_lsb(uint64_t bb) {
1712
  return _lsb(bb);
1713
}
1714
 
1715
uint64_t tb_pop_lsb(uint64_t bb) {
1716
  return poplsb(bb);
1717
}
1718
 
1719
uint64_t tb_king_attacks(unsigned sq) {
1720
  return king_attacks(sq);
1721
}
1722
 
1723
uint64_t tb_queen_attacks(unsigned sq, uint64_t occ) {
1724
  return queen_attacks(sq, occ);
1725
}
1726
 
1727
uint64_t tb_rook_attacks(unsigned sq, uint64_t occ) {
1728
  return rook_attacks(sq, occ);
1729
}
1730
 
1731
uint64_t tb_bishop_attacks(unsigned sq, uint64_t occ) {
1732
  return bishop_attacks(sq, occ);
1733
}
1734
 
1735
uint64_t tb_knight_attacks(unsigned sq) {
1736
  return knight_attacks(sq);
1737
}
1738
 
1739
uint64_t tb_pawn_attacks(unsigned sq, bool color) {
1740
  return pawn_attacks(sq, color);
1741
}
1742
 
1743
#endif                          /* TB_NO_HELPER_API */