24#if !defined(DECOMP64) && defined(_LP64)
30#define TBMAX_PIECE 254
37#define Swap(a,b) {int tmp=a;a=b;b=tmp;}
46#define TB_WPAWN TB_PAWN
47#define TB_BPAWN (TB_PAWN | 8)
50static LOCK_T TB_MUTEX;
53#ifdef TB_CUSTOM_BSWAP32
54#define internal_bswap32(x) TB_CUSTOM_BSWAP32(x)
55#elif defined(_MSC_VER)
56#define internal_bswap32(x) _byteswap_ulong(x)
58#define internal_bswap32(x) __builtin_bswap32(x)
61#ifdef TB_CUSTOM_BSWAP64
62#define internal_bswap64(x) TB_CUSTOM_BSWAP64(x)
63#elif defined(_MSC_VER)
64#define internal_bswap64(x) _byteswap_uint64(x)
66#define internal_bswap64(x) __builtin_bswap64(x)
69static int initialized = 0;
70static int num_paths = 0;
71static char *path_string = NULL;
72static char **paths = NULL;
74static int TBnum_piece, TBnum_pawn;
78static struct TBHashEntry TB_hash[1 << TBHASHBITS][HSHMAX];
84static void init_indices(
void);
85static uint64_t calc_key_from_pcs(
int *pcs,
int mirror);
86static void free_wdl_entry(
struct TBEntry *entry);
87static void free_dtz_entry(
struct TBEntry *entry);
91static size_t safe_strncpy(
char *dst,
const char *src,
size_t size)
95 const char *srcptr = src;
97 if (tocopy && --tocopy) {
99 if (!(*dstptr++ = *srcptr++))
104 if (size) *dstptr = 0;
108 return (srcptr - src - 1);
113static size_t safe_strncat(
char *dst,
const char *src,
size_t size)
117 size_t tocopy = size;
118 const char *srcptr = src;
120 while (tocopy-- && *dstptr)
122 dstlen = dstptr - dst;
123 if (!(tocopy = size - dstlen))
124 return (dstlen + strlen(src));
134 return (dstlen + (srcptr - src));
137static FD open_tb(
const char *str,
const char *suffix)
143 for (i = 0; i < num_paths; i++) {
144 safe_strncpy(file, paths[i], 256);
146 safe_strncat(file,
"/", 256);
148 safe_strncat(file,
"\\", 256);
150 safe_strncat(file, str, 256);
151 safe_strncat(file, suffix, 256);
153 fd = open(file, O_RDONLY);
155 fd = CreateFileA(file, GENERIC_READ, FILE_SHARE_READ, NULL,
156 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
158 if (fd != FD_ERR)
return fd;
163static void close_tb(FD fd)
172static char *map_file(
const char *name,
const char *suffix, uint64 *mapping)
174 FD fd = open_tb(name, suffix);
179 if (fstat(fd, &statbuf) == -1) {
180 printf(
"Could not get file status\n");
184 *mapping = statbuf.st_size;
185 char *data = (
char *)mmap(NULL, statbuf.st_size, PROT_READ,
187 if (data == (
char *)(-1)) {
188 printf(
"Could not mmap() %s.\n", name);
192 DWORD size_low, size_high;
193 size_low = GetFileSize(fd, &size_high);
195 HANDLE map = CreateFileMapping(fd, NULL, PAGE_READONLY, size_high, size_low,
198 printf(
"CreateFileMapping() failed.\n");
201 *mapping = (uint64)map;
202 char *data = (
char *)MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
204 printf(
"MapViewOfFile() failed, name = %s%s, error = %lu.\n", name, suffix, GetLastError());
213static void unmap_file(
char *data, uint64 size)
219static void unmap_file(
char *data, uint64 mapping)
222 UnmapViewOfFile(data);
223 CloseHandle((HANDLE)mapping);
227static void add_to_hash(
struct TBEntry *ptr, uint64 key)
230 hshidx = key >> (64 - TBHASHBITS);
232 while (i < HSHMAX && TB_hash[hshidx][i].ptr)
235 printf(
"HSHMAX too low!\n");
238 TB_hash[hshidx][i].key = key;
239 TB_hash[hshidx][i].ptr = ptr;
243static char pchr[] = {
'K',
'Q',
'R',
'B',
'N',
'P'};
245static void init_tb(
char *str)
254 fd = open_tb(str, WDLSUFFIX);
255 if (fd == FD_ERR)
return;
258 for (i = 0; i < 16; i++)
261 for (s = str; *s; s++)
264 pcs[TB_PAWN | color]++;
267 pcs[TB_KNIGHT | color]++;
270 pcs[TB_BISHOP | color]++;
273 pcs[TB_ROOK | color]++;
276 pcs[TB_QUEEN | color]++;
279 pcs[TB_KING | color]++;
285 key = calc_key_from_pcs(pcs, 0);
286 key2 = calc_key_from_pcs(pcs, 1);
287 if (pcs[TB_WPAWN] + pcs[TB_BPAWN] == 0) {
288 if (TBnum_piece == TBMAX_PIECE) {
289 printf(
"TBMAX_PIECE limit too low!\n");
292 entry = (
struct TBEntry *)&TB_piece[TBnum_piece++];
294 if (TBnum_pawn == TBMAX_PAWN) {
295 printf(
"TBMAX_PAWN limit too low!\n");
298 entry = (
struct TBEntry *)&TB_pawn[TBnum_pawn++];
303 for (i = 0; i < 16; i++)
304 entry->num += pcs[i];
305 entry->symmetric = (key == key2);
306 entry->has_pawns = (pcs[TB_WPAWN] + pcs[TB_BPAWN] > 0);
307 if (entry->num > TB_LARGEST)
308 TB_LARGEST = entry->num;
310 if (entry->has_pawns) {
312 ptr->pawns[0] = pcs[TB_WPAWN];
313 ptr->pawns[1] = pcs[TB_BPAWN];
314 if (pcs[TB_BPAWN] > 0
315 && (pcs[TB_WPAWN] == 0 || pcs[TB_BPAWN] < pcs[TB_WPAWN])) {
316 ptr->pawns[0] = pcs[TB_BPAWN];
317 ptr->pawns[1] = pcs[TB_WPAWN];
321 for (i = 0, j = 0; i < 16; i++)
322 if (pcs[i] == 1) j++;
323 if (j >= 3) ptr->enc_type = 0;
324 else if (j == 2) ptr->enc_type = 2;
327 for (i = 0; i < 16; i++) {
328 if (pcs[i] < j && pcs[i] > 1) j = pcs[i];
329 ptr->enc_type = 1 + j;
333 add_to_hash(entry, key);
334 if (key2 != key) add_to_hash(entry, key2);
337void init_tablebases(
const char *path)
346 for (i = 0; i < TBnum_piece; i++) {
347 entry = (
struct TBEntry *)&TB_piece[i];
348 free_wdl_entry(entry);
350 for (i = 0; i < TBnum_pawn; i++) {
351 entry = (
struct TBEntry *)&TB_pawn[i];
352 free_wdl_entry(entry);
354 for (i = 0; i < DTZ_ENTRIES; i++)
355 if (DTZ_table[i].entry)
356 free_dtz_entry(DTZ_table[i].entry);
362 const char *p = path;
363 if (strlen(p) == 0 || !strcmp(p,
"<empty>"))
return;
364 const size_t len = strlen(p) + 1;
365 path_string = (
char *)malloc(len);
366 safe_strncpy(path_string, p, len);
369 if (path_string[i] != SEP_CHAR)
371 while (path_string[i] && path_string[i] != SEP_CHAR)
373 if (!path_string[i])
break;
376 paths = (
char **)malloc(num_paths *
sizeof(
char *));
377 for (i = j = 0; i < num_paths; i++) {
378 while (!path_string[j]) j++;
379 paths[i] = &path_string[j];
380 while (path_string[j]) j++;
385 TBnum_piece = TBnum_pawn = 0;
388 for (i = 0; i < (1 << TBHASHBITS); i++)
389 for (j = 0; j < HSHMAX; j++) {
390 TB_hash[i][j].key = 0ULL;
391 TB_hash[i][j].ptr = NULL;
394 for (i = 0; i < DTZ_ENTRIES; i++)
395 DTZ_table[i].entry = NULL;
397 for (i = 1; i < 6; i++) {
398 snprintf(str, 16,
"K%cvK", pchr[i]);
402 for (i = 1; i < 6; i++)
403 for (j = i; j < 6; j++) {
404 snprintf(str, 16,
"K%cvK%c", pchr[i], pchr[j]);
408 for (i = 1; i < 6; i++)
409 for (j = i; j < 6; j++) {
410 snprintf(str, 16,
"K%c%cvK", pchr[i], pchr[j]);
414 for (i = 1; i < 6; i++)
415 for (j = i; j < 6; j++)
416 for (k = 1; k < 6; k++) {
417 snprintf(str, 16,
"K%c%cvK%c", pchr[i], pchr[j], pchr[k]);
421 for (i = 1; i < 6; i++)
422 for (j = i; j < 6; j++)
423 for (k = j; k < 6; k++) {
424 snprintf(str, 16,
"K%c%c%cvK", pchr[i], pchr[j], pchr[k]);
428 for (i = 1; i < 6; i++)
429 for (j = i; j < 6; j++)
430 for (k = i; k < 6; k++)
431 for (l = (i == k) ? j : k; l < 6; l++) {
432 snprintf(str, 16,
"K%c%cvK%c%c", pchr[i], pchr[j], pchr[k], pchr[l]);
436 for (i = 1; i < 6; i++)
437 for (j = i; j < 6; j++)
438 for (k = j; k < 6; k++)
439 for (l = 1; l < 6; l++) {
440 snprintf(str, 16,
"K%c%c%cvK%c", pchr[i], pchr[j], pchr[k], pchr[l]);
444 for (i = 1; i < 6; i++)
445 for (j = i; j < 6; j++)
446 for (k = j; k < 6; k++)
447 for (l = k; l < 6; l++) {
448 snprintf(str, 16,
"K%c%c%c%cvK", pchr[i], pchr[j], pchr[k], pchr[l]);
455static const char offdiag[] = {
456 0,-1,-1,-1,-1,-1,-1,-1,
457 1, 0,-1,-1,-1,-1,-1,-1,
458 1, 1, 0,-1,-1,-1,-1,-1,
459 1, 1, 1, 0,-1,-1,-1,-1,
460 1, 1, 1, 1, 0,-1,-1,-1,
461 1, 1, 1, 1, 1, 0,-1,-1,
462 1, 1, 1, 1, 1, 1, 0,-1,
463 1, 1, 1, 1, 1, 1, 1, 0
466static const ubyte triangle[] = {
467 6, 0, 1, 2, 2, 1, 0, 6,
468 0, 7, 3, 4, 4, 3, 7, 0,
469 1, 3, 8, 5, 5, 8, 3, 1,
470 2, 4, 5, 9, 9, 5, 4, 2,
471 2, 4, 5, 9, 9, 5, 4, 2,
472 1, 3, 8, 5, 5, 8, 3, 1,
473 0, 7, 3, 4, 4, 3, 7, 0,
474 6, 0, 1, 2, 2, 1, 0, 6
477static const ubyte invtriangle[] = {
478 1, 2, 3, 10, 11, 19, 0, 9, 18, 27
481static const ubyte invdiag[] = {
482 0, 9, 18, 27, 36, 45, 54, 63,
483 7, 14, 21, 28, 35, 42, 49, 56
486static const ubyte flipdiag[] = {
487 0, 8, 16, 24, 32, 40, 48, 56,
488 1, 9, 17, 25, 33, 41, 49, 57,
489 2, 10, 18, 26, 34, 42, 50, 58,
490 3, 11, 19, 27, 35, 43, 51, 59,
491 4, 12, 20, 28, 36, 44, 52, 60,
492 5, 13, 21, 29, 37, 45, 53, 61,
493 6, 14, 22, 30, 38, 46, 54, 62,
494 7, 15, 23, 31, 39, 47, 55, 63
497static const ubyte lower[] = {
498 28, 0, 1, 2, 3, 4, 5, 6,
499 0, 29, 7, 8, 9, 10, 11, 12,
500 1, 7, 30, 13, 14, 15, 16, 17,
501 2, 8, 13, 31, 18, 19, 20, 21,
502 3, 9, 14, 18, 32, 22, 23, 24,
503 4, 10, 15, 19, 22, 33, 25, 26,
504 5, 11, 16, 20, 23, 25, 34, 27,
505 6, 12, 17, 21, 24, 26, 27, 35
508static const ubyte diag[] = {
509 0, 0, 0, 0, 0, 0, 0, 8,
510 0, 1, 0, 0, 0, 0, 9, 0,
511 0, 0, 2, 0, 0, 10, 0, 0,
512 0, 0, 0, 3, 11, 0, 0, 0,
513 0, 0, 0, 12, 4, 0, 0, 0,
514 0, 0, 13, 0, 0, 5, 0, 0,
515 0, 14, 0, 0, 0, 0, 6, 0,
516 15, 0, 0, 0, 0, 0, 0, 7
519static const ubyte flap[] = {
520 0, 0, 0, 0, 0, 0, 0, 0,
521 0, 6, 12, 18, 18, 12, 6, 0,
522 1, 7, 13, 19, 19, 13, 7, 1,
523 2, 8, 14, 20, 20, 14, 8, 2,
524 3, 9, 15, 21, 21, 15, 9, 3,
525 4, 10, 16, 22, 22, 16, 10, 4,
526 5, 11, 17, 23, 23, 17, 11, 5,
527 0, 0, 0, 0, 0, 0, 0, 0
530static const ubyte ptwist[] = {
531 0, 0, 0, 0, 0, 0, 0, 0,
532 47, 35, 23, 11, 10, 22, 34, 46,
533 45, 33, 21, 9, 8, 20, 32, 44,
534 43, 31, 19, 7, 6, 18, 30, 42,
535 41, 29, 17, 5, 4, 16, 28, 40,
536 39, 27, 15, 3, 2, 14, 26, 38,
537 37, 25, 13, 1, 0, 12, 24, 36,
538 0, 0, 0, 0, 0, 0, 0, 0
541static const ubyte invflap[] = {
542 8, 16, 24, 32, 40, 48,
543 9, 17, 25, 33, 41, 49,
544 10, 18, 26, 34, 42, 50,
545 11, 19, 27, 35, 43, 51
548static const ubyte invptwist[] = {
549 52, 51, 44, 43, 36, 35, 28, 27, 20, 19, 12, 11,
550 53, 50, 45, 42, 37, 34, 29, 26, 21, 18, 13, 10,
551 54, 49, 46, 41, 38, 33, 30, 25, 22, 17, 14, 9,
552 55, 48, 47, 40, 39, 32, 31, 24, 23, 16, 15, 8
555static const ubyte file_to_file[] = {
556 0, 1, 2, 3, 3, 2, 1, 0
559#ifndef CONNECTED_KINGS
560static const short KK_idx[10][64] = {
561 { -1, -1, -1, 0, 1, 2, 3, 4,
562 -1, -1, -1, 5, 6, 7, 8, 9,
563 10, 11, 12, 13, 14, 15, 16, 17,
564 18, 19, 20, 21, 22, 23, 24, 25,
565 26, 27, 28, 29, 30, 31, 32, 33,
566 34, 35, 36, 37, 38, 39, 40, 41,
567 42, 43, 44, 45, 46, 47, 48, 49,
568 50, 51, 52, 53, 54, 55, 56, 57 },
569 { 58, -1, -1, -1, 59, 60, 61, 62,
570 63, -1, -1, -1, 64, 65, 66, 67,
571 68, 69, 70, 71, 72, 73, 74, 75,
572 76, 77, 78, 79, 80, 81, 82, 83,
573 84, 85, 86, 87, 88, 89, 90, 91,
574 92, 93, 94, 95, 96, 97, 98, 99,
575 100,101,102,103,104,105,106,107,
576 108,109,110,111,112,113,114,115},
577 {116,117, -1, -1, -1,118,119,120,
578 121,122, -1, -1, -1,123,124,125,
579 126,127,128,129,130,131,132,133,
580 134,135,136,137,138,139,140,141,
581 142,143,144,145,146,147,148,149,
582 150,151,152,153,154,155,156,157,
583 158,159,160,161,162,163,164,165,
584 166,167,168,169,170,171,172,173 },
585 {174, -1, -1, -1,175,176,177,178,
586 179, -1, -1, -1,180,181,182,183,
587 184, -1, -1, -1,185,186,187,188,
588 189,190,191,192,193,194,195,196,
589 197,198,199,200,201,202,203,204,
590 205,206,207,208,209,210,211,212,
591 213,214,215,216,217,218,219,220,
592 221,222,223,224,225,226,227,228 },
593 {229,230, -1, -1, -1,231,232,233,
594 234,235, -1, -1, -1,236,237,238,
595 239,240, -1, -1, -1,241,242,243,
596 244,245,246,247,248,249,250,251,
597 252,253,254,255,256,257,258,259,
598 260,261,262,263,264,265,266,267,
599 268,269,270,271,272,273,274,275,
600 276,277,278,279,280,281,282,283 },
601 {284,285,286,287,288,289,290,291,
602 292,293, -1, -1, -1,294,295,296,
603 297,298, -1, -1, -1,299,300,301,
604 302,303, -1, -1, -1,304,305,306,
605 307,308,309,310,311,312,313,314,
606 315,316,317,318,319,320,321,322,
607 323,324,325,326,327,328,329,330,
608 331,332,333,334,335,336,337,338 },
609 { -1, -1,339,340,341,342,343,344,
610 -1, -1,345,346,347,348,349,350,
611 -1, -1,441,351,352,353,354,355,
612 -1, -1, -1,442,356,357,358,359,
613 -1, -1, -1, -1,443,360,361,362,
614 -1, -1, -1, -1, -1,444,363,364,
615 -1, -1, -1, -1, -1, -1,445,365,
616 -1, -1, -1, -1, -1, -1, -1,446 },
617 { -1, -1, -1,366,367,368,369,370,
618 -1, -1, -1,371,372,373,374,375,
619 -1, -1, -1,376,377,378,379,380,
620 -1, -1, -1,447,381,382,383,384,
621 -1, -1, -1, -1,448,385,386,387,
622 -1, -1, -1, -1, -1,449,388,389,
623 -1, -1, -1, -1, -1, -1,450,390,
624 -1, -1, -1, -1, -1, -1, -1,451 },
625 {452,391,392,393,394,395,396,397,
626 -1, -1, -1, -1,398,399,400,401,
627 -1, -1, -1, -1,402,403,404,405,
628 -1, -1, -1, -1,406,407,408,409,
629 -1, -1, -1, -1,453,410,411,412,
630 -1, -1, -1, -1, -1,454,413,414,
631 -1, -1, -1, -1, -1, -1,455,415,
632 -1, -1, -1, -1, -1, -1, -1,456 },
633 {457,416,417,418,419,420,421,422,
634 -1,458,423,424,425,426,427,428,
635 -1, -1, -1, -1, -1,429,430,431,
636 -1, -1, -1, -1, -1,432,433,434,
637 -1, -1, -1, -1, -1,435,436,437,
638 -1, -1, -1, -1, -1,459,438,439,
639 -1, -1, -1, -1, -1, -1,460,440,
640 -1, -1, -1, -1, -1, -1, -1,461 }
643static const short PP_idx[10][64] = {
644 { 0, -1, 1, 2, 3, 4, 5, 6,
645 7, 8, 9, 10, 11, 12, 13, 14,
646 15, 16, 17, 18, 19, 20, 21, 22,
647 23, 24, 25, 26, 27, 28, 29, 30,
648 31, 32, 33, 34, 35, 36, 37, 38,
649 39, 40, 41, 42, 43, 44, 45, 46,
650 -1, 47, 48, 49, 50, 51, 52, 53,
651 54, 55, 56, 57, 58, 59, 60, 61 },
652 { 62, -1, -1, 63, 64, 65, -1, 66,
653 -1, 67, 68, 69, 70, 71, 72, -1,
654 73, 74, 75, 76, 77, 78, 79, 80,
655 81, 82, 83, 84, 85, 86, 87, 88,
656 89, 90, 91, 92, 93, 94, 95, 96,
657 -1, 97, 98, 99,100,101,102,103,
658 -1,104,105,106,107,108,109, -1,
659 110, -1,111,112,113,114, -1,115 },
660 {116, -1, -1, -1,117, -1, -1,118,
661 -1,119,120,121,122,123,124, -1,
662 -1,125,126,127,128,129,130, -1,
663 131,132,133,134,135,136,137,138,
664 -1,139,140,141,142,143,144,145,
665 -1,146,147,148,149,150,151, -1,
666 -1,152,153,154,155,156,157, -1,
667 158, -1, -1,159,160, -1, -1,161 },
668 {162, -1, -1, -1, -1, -1, -1,163,
669 -1,164, -1,165,166,167,168, -1,
670 -1,169,170,171,172,173,174, -1,
671 -1,175,176,177,178,179,180, -1,
672 -1,181,182,183,184,185,186, -1,
673 -1, -1,187,188,189,190,191, -1,
674 -1,192,193,194,195,196,197, -1,
675 198, -1, -1, -1, -1, -1, -1,199 },
676 {200, -1, -1, -1, -1, -1, -1,201,
677 -1,202, -1, -1,203, -1,204, -1,
678 -1, -1,205,206,207,208, -1, -1,
679 -1,209,210,211,212,213,214, -1,
680 -1, -1,215,216,217,218,219, -1,
681 -1, -1,220,221,222,223, -1, -1,
682 -1,224, -1,225,226, -1,227, -1,
683 228, -1, -1, -1, -1, -1, -1,229 },
684 {230, -1, -1, -1, -1, -1, -1,231,
685 -1,232, -1, -1, -1, -1,233, -1,
686 -1, -1,234, -1,235,236, -1, -1,
687 -1, -1,237,238,239,240, -1, -1,
688 -1, -1, -1,241,242,243, -1, -1,
689 -1, -1,244,245,246,247, -1, -1,
690 -1,248, -1, -1, -1, -1,249, -1,
691 250, -1, -1, -1, -1, -1, -1,251 },
692 { -1, -1, -1, -1, -1, -1, -1,259,
693 -1,252, -1, -1, -1, -1,260, -1,
694 -1, -1,253, -1, -1,261, -1, -1,
695 -1, -1, -1,254,262, -1, -1, -1,
696 -1, -1, -1, -1,255, -1, -1, -1,
697 -1, -1, -1, -1, -1,256, -1, -1,
698 -1, -1, -1, -1, -1, -1,257, -1,
699 -1, -1, -1, -1, -1, -1, -1,258 },
700 { -1, -1, -1, -1, -1, -1, -1, -1,
701 -1, -1, -1, -1, -1, -1,268, -1,
702 -1, -1,263, -1, -1,269, -1, -1,
703 -1, -1, -1,264,270, -1, -1, -1,
704 -1, -1, -1, -1,265, -1, -1, -1,
705 -1, -1, -1, -1, -1,266, -1, -1,
706 -1, -1, -1, -1, -1, -1,267, -1,
707 -1, -1, -1, -1, -1, -1, -1, -1 },
708 { -1, -1, -1, -1, -1, -1, -1, -1,
709 -1, -1, -1, -1, -1, -1, -1, -1,
710 -1, -1, -1, -1, -1,274, -1, -1,
711 -1, -1, -1,271,275, -1, -1, -1,
712 -1, -1, -1, -1,272, -1, -1, -1,
713 -1, -1, -1, -1, -1,273, -1, -1,
714 -1, -1, -1, -1, -1, -1, -1, -1,
715 -1, -1, -1, -1, -1, -1, -1, -1 },
716 { -1, -1, -1, -1, -1, -1, -1, -1,
717 -1, -1, -1, -1, -1, -1, -1, -1,
718 -1, -1, -1, -1, -1, -1, -1, -1,
719 -1, -1, -1, -1,277, -1, -1, -1,
720 -1, -1, -1, -1,276, -1, -1, -1,
721 -1, -1, -1, -1, -1, -1, -1, -1,
722 -1, -1, -1, -1, -1, -1, -1, -1,
723 -1, -1, -1, -1, -1, -1, -1, -1 }
726static const ubyte test45[] = {
727 0, 0, 0, 0, 0, 0, 0, 0,
728 0, 0, 0, 0, 0, 0, 0, 0,
729 0, 0, 0, 0, 0, 0, 0, 0,
730 0, 0, 0, 0, 0, 0, 0, 0,
731 1, 1, 1, 0, 0, 0, 0, 0,
732 1, 1, 0, 0, 0, 0, 0, 0,
733 1, 0, 0, 0, 0, 0, 0, 0,
734 0, 0, 0, 0, 0, 0, 0, 0
737static const ubyte mtwist[] = {
738 15, 63, 55, 47, 40, 48, 56, 12,
739 62, 11, 39, 31, 24, 32, 8, 57,
740 54, 38, 7, 23, 16, 4, 33, 49,
741 46, 30, 22, 3, 0, 17, 25, 41,
742 45, 29, 21, 2, 1, 18, 26, 42,
743 53, 37, 6, 20, 19, 5, 34, 50,
744 61, 10, 36, 28, 27, 35, 9, 58,
745 14, 60, 52, 44, 43, 51, 59, 13
749static int binomial[5][64];
750static int pawnidx[5][24];
751static int pfactor[5][4];
752#ifdef CONNECTED_KINGS
753static int multidx[5][10];
754static int mfactor[5];
757static void init_indices(
void)
762 for (i = 0; i < 5; i++)
763 for (j = 0; j < 64; j++) {
766 for (k = 1; k <= i; k++) {
770 binomial[i][j] = f / l;
773 for (i = 0; i < 5; i++) {
775 for (j = 0; j < 6; j++) {
777 s += (i == 0) ? 1 : binomial[i - 1][ptwist[invflap[j]]];
781 for (; j < 12; j++) {
783 s += (i == 0) ? 1 : binomial[i - 1][ptwist[invflap[j]]];
787 for (; j < 18; j++) {
789 s += (i == 0) ? 1 : binomial[i - 1][ptwist[invflap[j]]];
793 for (; j < 24; j++) {
795 s += (i == 0) ? 1 : binomial[i - 1][ptwist[invflap[j]]];
800#ifdef CONNECTED_KINGS
801 for (i = 0; i < 5; i++) {
803 for (j = 0; j < 10; j++) {
805 s += (i == 0) ? 1 : binomial[i - 1][mtwist[invtriangle[j]]];
812#ifndef CONNECTED_KINGS
813static uint64 encode_piece(
struct TBEntry_piece *ptr, ubyte *norm,
int *pos,
int *factor)
816 int i, j, k, m, l, p;
820 for (i = 0; i < n; i++)
824 for (i = 0; i < n; i++)
828 for (i = 0; i < n; i++)
829 if (offdiag[pos[i]])
break;
830 if (i < (ptr->enc_type == 0 ? 3 : 2) && offdiag[pos[i]] > 0)
831 for (i = 0; i < n; i++)
832 pos[i] = flipdiag[pos[i]];
834 switch (ptr->enc_type) {
837 i = (pos[1] > pos[0]);
838 j = (pos[2] > pos[0]) + (pos[2] > pos[1]);
841 idx = triangle[pos[0]] * 63*62 + (pos[1] - i) * 62 + (pos[2] - j);
842 else if (offdiag[pos[1]])
843 idx = 6*63*62 + diag[pos[0]] * 28*62 + lower[pos[1]] * 62 + pos[2] - j;
844 else if (offdiag[pos[2]])
845 idx = 6*63*62 + 4*28*62 + (diag[pos[0]]) * 7*28 + (diag[pos[1]] - i) * 28 + lower[pos[2]];
847 idx = 6*63*62 + 4*28*62 + 4*7*28 + (diag[pos[0]] * 7*6) + (diag[pos[1]] - i) * 6 + (diag[pos[2]] - j);
852 j = (pos[2] > pos[0]) + (pos[2] > pos[1]);
854 idx = KK_idx[triangle[pos[0]]][pos[1]];
856 idx = idx + 441 * (pos[2] - j);
858 idx = 441*62 + (idx - 441) + 21 * lower[pos[2]];
859 if (!offdiag[pos[2]])
866 idx = KK_idx[triangle[pos[0]]][pos[1]];
874 for (j = i; j < i + t; j++)
875 for (k = j + 1; k < i + t; k++)
876 if (pos[j] > pos[k]) Swap(pos[j], pos[k]);
878 for (m = i; m < i + t; m++) {
880 for (l = 0, j = 0; l < i; l++)
882 s += binomial[m - i][p - j];
884 idx += ((uint64)s) * ((uint64)factor[i]);
891static uint64 encode_piece(
struct TBEntry_piece *ptr, ubyte *norm,
int *pos,
int *factor)
894 int i, j, k, m, l, p;
897 if (ptr->enc_type < 3) {
899 for (i = 0; i < n; i++)
903 for (i = 0; i < n; i++)
907 for (i = 0; i < n; i++)
908 if (offdiag[pos[i]])
break;
909 if (i < (ptr->enc_type == 0 ? 3 : 2) && offdiag[pos[i]] > 0)
910 for (i = 0; i < n; i++)
911 pos[i] = flipdiag[pos[i]];
913 switch (ptr->enc_type) {
916 i = (pos[1] > pos[0]);
917 j = (pos[2] > pos[0]) + (pos[2] > pos[1]);
920 idx = triangle[pos[0]] * 63*62 + (pos[1] - i) * 62 + (pos[2] - j);
921 else if (offdiag[pos[1]])
922 idx = 6*63*62 + diag[pos[0]] * 28*62 + lower[pos[1]] * 62 + pos[2] - j;
923 else if (offdiag[pos[2]])
924 idx = 6*63*62 + 4*28*62 + (diag[pos[0]]) * 7*28 + (diag[pos[1]] - i) * 28 + lower[pos[2]];
926 idx = 6*63*62 + 4*28*62 + 4*7*28 + (diag[pos[0]] * 7*6) + (diag[pos[1]] - i) * 6 + (diag[pos[2]] - j);
931 i = (pos[1] > pos[0]);
934 idx = triangle[pos[0]] * 63 + (pos[1] - i);
935 else if (offdiag[pos[1]])
936 idx = 6*63 + diag[pos[0]] * 28 + lower[pos[1]];
938 idx = 6*63 + 4*28 + (diag[pos[0]]) * 7 + (diag[pos[1]] - i);
943 }
else if (ptr->enc_type == 3) {
944 if (triangle[pos[0]] > triangle[pos[1]])
945 Swap(pos[0], pos[1]);
947 for (i = 0; i < n; i++)
950 for (i = 0; i < n; i++)
952 if (offdiag[pos[0]] > 0 || (offdiag[pos[0]] == 0 && offdiag[pos[1]] > 0))
953 for (i = 0; i < n; i++)
954 pos[i] = flipdiag[pos[i]];
955 if (test45[pos[1]] && triangle[pos[0]] == triangle[pos[1]]) {
956 Swap(pos[0], pos[1]);
957 for (i = 0; i < n; i++)
958 pos[i] = flipdiag[pos[i] ^ 0x38];
960 idx = PP_idx[triangle[pos[0]]][pos[1]];
963 for (i = 1; i < norm[0]; i++)
964 if (triangle[pos[0]] > triangle[pos[i]])
965 Swap(pos[0], pos[i]);
967 for (i = 0; i < n; i++)
970 for (i = 0; i < n; i++)
972 if (offdiag[pos[0]] > 0)
973 for (i = 0; i < n; i++)
974 pos[i] = flipdiag[pos[i]];
975 for (i = 1; i < norm[0]; i++)
976 for (j = i + 1; j < norm[0]; j++)
977 if (mtwist[pos[i]] > mtwist[pos[j]])
978 Swap(pos[i], pos[j]);
980 idx = multidx[norm[0] - 1][triangle[pos[0]]];
981 for (i = 1; i < norm[0]; i++)
982 idx += binomial[i - 1][mtwist[pos[i]]];
988 for (j = i; j < i + t; j++)
989 for (k = j + 1; k < i + t; k++)
990 if (pos[j] > pos[k]) Swap(pos[j], pos[k]);
992 for (m = i; m < i + t; m++) {
994 for (l = 0, j = 0; l < i; l++)
996 s += binomial[m - i][p - j];
998 idx += ((uint64)s) * ((uint64)factor[i]);
1007static int pawn_file(
struct TBEntry_pawn *ptr,
int *pos)
1011 for (i = 1; i < ptr->pawns[0]; i++)
1012 if (flap[pos[0]] > flap[pos[i]])
1013 Swap(pos[0], pos[i]);
1015 return file_to_file[pos[0] & 0x07];
1018static uint64 encode_pawn(
struct TBEntry_pawn *ptr, ubyte *norm,
int *pos,
int *factor)
1021 int i, j, k, m, s, t;
1025 for (i = 0; i < n; i++)
1028 for (i = 1; i < ptr->pawns[0]; i++)
1029 for (j = i + 1; j < ptr->pawns[0]; j++)
1030 if (ptwist[pos[i]] < ptwist[pos[j]])
1031 Swap(pos[i], pos[j]);
1033 t = ptr->pawns[0] - 1;
1034 idx = pawnidx[t][flap[pos[0]]];
1035 for (i = t; i > 0; i--)
1036 idx += binomial[t - i][ptwist[pos[i]]];
1041 t = i + ptr->pawns[1];
1043 for (j = i; j < t; j++)
1044 for (k = j + 1; k < t; k++)
1045 if (pos[j] > pos[k]) Swap(pos[j], pos[k]);
1047 for (m = i; m < t; m++) {
1049 for (k = 0, j = 0; k < i; k++)
1051 s += binomial[m - i][p - j - 8];
1053 idx += ((uint64)s) * ((uint64)factor[i]);
1059 for (j = i; j < i + t; j++)
1060 for (k = j + 1; k < i + t; k++)
1061 if (pos[j] > pos[k]) Swap(pos[j], pos[k]);
1063 for (m = i; m < i + t; m++) {
1065 for (k = 0, j = 0; k < i; k++)
1067 s += binomial[m - i][p - j];
1069 idx += ((uint64)s) * ((uint64)factor[i]);
1076static ubyte decompress_pairs(
struct PairsData *d, uint64 index);
1079static int subfactor(
int k,
int n)
1085 for (i = 1; i < k; i++) {
1093static uint64 calc_factors_piece(
int *factor,
int num,
int order, ubyte *norm, ubyte enc_type)
1097#ifndef CONNECTED_KINGS
1098 static int pivfac[] = { 31332, 28056, 462 };
1100 static int pivfac[] = { 31332, 0, 518, 278 };
1106 for (i = norm[0], k = 0; i < num || k == order; k++) {
1109#ifndef CONNECTED_KINGS
1110 f *= pivfac[enc_type];
1113 f *= pivfac[enc_type];
1115 f *= mfactor[enc_type - 2];
1119 f *= subfactor(norm[i], n);
1128static uint64 calc_factors_pawn(
int *factor,
int num,
int order,
int order2, ubyte *norm,
int file)
1134 if (order2 < 0x0f) i += norm[i];
1138 for (k = 0; i < num || k == order || k == order2; k++) {
1141 f *= pfactor[norm[0] - 1][file];
1142 }
else if (k == order2) {
1143 factor[norm[0]] = (int)f;
1144 f *= subfactor(norm[norm[0]], 48 - norm[0]);
1147 f *= subfactor(norm[i], n);
1156static void set_norm_piece(
struct TBEntry_piece *ptr, ubyte *norm, ubyte *pieces)
1160 for (i = 0; i < ptr->num; i++)
1163 switch (ptr->enc_type) {
1171 norm[0] = ptr->enc_type - 1;
1175 for (i = norm[0]; i < ptr->num; i += norm[i])
1176 for (j = i; j < ptr->num && pieces[j] == pieces[i]; j++)
1180static void set_norm_pawn(
struct TBEntry_pawn *ptr, ubyte *norm, ubyte *pieces)
1184 for (i = 0; i < ptr->num; i++)
1187 norm[0] = ptr->pawns[0];
1188 if (ptr->pawns[1]) norm[ptr->pawns[0]] = ptr->pawns[1];
1190 for (i = ptr->pawns[0] + ptr->pawns[1]; i < ptr->num; i += norm[i])
1191 for (j = i; j < ptr->num && pieces[j] == pieces[i]; j++)
1195static void setup_pieces_piece(
struct TBEntry_piece *ptr,
unsigned char *data, uint64 *tb_size)
1200 for (i = 0; i < ptr->num; i++)
1201 ptr->pieces[0][i] = data[i + 1] & 0x0f;
1202 order = data[0] & 0x0f;
1203 set_norm_piece(ptr, ptr->norm[0], ptr->pieces[0]);
1204 tb_size[0] = calc_factors_piece(ptr->factor[0], ptr->num, order, ptr->norm[0], ptr->enc_type);
1206 for (i = 0; i < ptr->num; i++)
1207 ptr->pieces[1][i] = data[i + 1] >> 4;
1208 order = data[0] >> 4;
1209 set_norm_piece(ptr, ptr->norm[1], ptr->pieces[1]);
1210 tb_size[1] = calc_factors_piece(ptr->factor[1], ptr->num, order, ptr->norm[1], ptr->enc_type);
1213static void setup_pieces_piece_dtz(
struct DTZEntry_piece *ptr,
unsigned char *data, uint64 *tb_size)
1218 for (i = 0; i < ptr->num; i++)
1219 ptr->pieces[i] = data[i + 1] & 0x0f;
1220 order = data[0] & 0x0f;
1221 set_norm_piece((
struct TBEntry_piece *)ptr, ptr->norm, ptr->pieces);
1222 tb_size[0] = calc_factors_piece(ptr->factor, ptr->num, order, ptr->norm, ptr->enc_type);
1225static void setup_pieces_pawn(
struct TBEntry_pawn *ptr,
unsigned char *data, uint64 *tb_size,
int f)
1230 j = 1 + (ptr->pawns[1] > 0);
1231 order = data[0] & 0x0f;
1232 order2 = ptr->pawns[1] ? (data[1] & 0x0f) : 0x0f;
1233 for (i = 0; i < ptr->num; i++)
1234 ptr->file[f].pieces[0][i] = data[i + j] & 0x0f;
1235 set_norm_pawn(ptr, ptr->file[f].norm[0], ptr->file[f].pieces[0]);
1236 tb_size[0] = calc_factors_pawn(ptr->file[f].factor[0], ptr->num, order, order2, ptr->file[f].norm[0], f);
1238 order = data[0] >> 4;
1239 order2 = ptr->pawns[1] ? (data[1] >> 4) : 0x0f;
1240 for (i = 0; i < ptr->num; i++)
1241 ptr->file[f].pieces[1][i] = data[i + j] >> 4;
1242 set_norm_pawn(ptr, ptr->file[f].norm[1], ptr->file[f].pieces[1]);
1243 tb_size[1] = calc_factors_pawn(ptr->file[f].factor[1], ptr->num, order, order2, ptr->file[f].norm[1], f);
1246static void setup_pieces_pawn_dtz(
struct DTZEntry_pawn *ptr,
unsigned char *data, uint64 *tb_size,
int f)
1251 j = 1 + (ptr->pawns[1] > 0);
1252 order = data[0] & 0x0f;
1253 order2 = ptr->pawns[1] ? (data[1] & 0x0f) : 0x0f;
1254 for (i = 0; i < ptr->num; i++)
1255 ptr->file[f].pieces[i] = data[i + j] & 0x0f;
1256 set_norm_pawn((
struct TBEntry_pawn *)ptr, ptr->file[f].norm, ptr->file[f].pieces);
1257 tb_size[0] = calc_factors_pawn(ptr->file[f].factor, ptr->num, order, order2, ptr->file[f].norm, f);
1260static void calc_symlen(
struct PairsData *d,
int s,
char *tmp)
1264 int w = *(
int *)(d->sympat + 3 * s);
1265 s2 = (w >> 12) & 0x0fff;
1270 if (!tmp[s1]) calc_symlen(d, s1, tmp);
1271 if (!tmp[s2]) calc_symlen(d, s2, tmp);
1272 d->symlen[s] = d->symlen[s1] + d->symlen[s2] + 1;
1277static struct PairsData *setup_pairs(
unsigned char *data, uint64 tb_size, uint64 *size,
unsigned char **next, ubyte *flags,
int wdl)
1283 if (data[0] & 0x80) {
1287 d->min_len = data[1];
1291 size[0] = size[1] = size[2] = 0;
1295 int blocksize = data[1];
1296 int idxbits = data[2];
1297 int real_num_blocks = *(uint32 *)(&data[4]);
1298 int num_blocks = real_num_blocks + *(ubyte *)(&data[3]);
1299 int max_len = data[8];
1300 int min_len = data[9];
1301 int h = max_len - min_len + 1;
1302 int num_syms = *(ushort *)(&data[10 + 2 * h]);
1303 d = (
struct PairsData *)malloc(
sizeof(
struct PairsData) + (h - 1) *
sizeof(base_t) + num_syms);
1304 d->blocksize = blocksize;
1305 d->idxbits = idxbits;
1306 d->offset = (ushort *)(&data[10]);
1307 d->symlen = ((ubyte *)d) +
sizeof(
struct PairsData) + (h - 1) *
sizeof(base_t);
1308 d->sympat = &data[12 + 2 * h];
1309 d->min_len = min_len;
1310 *next = &data[12 + 2 * h + 3 * num_syms + (num_syms & 1)];
1312 int num_indices = (int)((tb_size + (1ULL << idxbits) - 1) >> idxbits);
1313 size[0] = 6ULL * num_indices;
1314 size[1] = 2ULL * num_blocks;
1315 size[2] = (1ULL << blocksize) * real_num_blocks;
1319 for (i = 0; i < num_syms; i++)
1321 for (i = 0; i < num_syms; i++)
1323 calc_symlen(d, i, tmp);
1326 for (i = h - 2; i >= 0; i--)
1327 d->base[i] = (d->base[i + 1] + d->offset[i] - d->offset[i + 1]) / 2;
1329 for (i = 0; i < h; i++)
1330 d->base[i] <<= 64 - (min_len + i);
1332 for (i = 0; i < h; i++)
1333 d->base[i] <<= 32 - (min_len + i);
1336 d->offset -= d->min_len;
1341static int init_table_wdl(
struct TBEntry *entry,
char *str)
1350 entry->data = map_file(str, WDLSUFFIX, &entry->mapping);
1352 printf(
"Could not find %s" WDLSUFFIX
"\n", str);
1356 ubyte *data = (ubyte *)entry->data;
1357 if (((uint32 *)data)[0] != WDL_MAGIC) {
1358 printf(
"Corrupted table.\n");
1359 unmap_file(entry->data, entry->mapping);
1364 int split = data[4] & 0x01;
1365 int files = data[4] & 0x02 ? 4 : 1;
1369 if (!entry->has_pawns) {
1371 setup_pieces_piece(ptr, data, &tb_size[0]);
1372 data += ptr->num + 1;
1373 data += ((uintptr_t)data) & 0x01;
1375 ptr->precomp[0] = setup_pairs(data, tb_size[0], &size[0], &next, &flags, 1);
1378 ptr->precomp[1] = setup_pairs(data, tb_size[1], &size[3], &next, &flags, 1);
1381 ptr->precomp[1] = NULL;
1383 ptr->precomp[0]->indextable = (
char *)data;
1386 ptr->precomp[1]->indextable = (
char *)data;
1390 ptr->precomp[0]->sizetable = (ushort *)data;
1393 ptr->precomp[1]->sizetable = (ushort *)data;
1397 data = (ubyte *)((((uintptr_t)data) + 0x3f) & ~0x3f);
1398 ptr->precomp[0]->data = data;
1401 data = (ubyte *)((((uintptr_t)data) + 0x3f) & ~0x3f);
1402 ptr->precomp[1]->data = data;
1406 s = 1 + (ptr->pawns[1] > 0);
1407 for (f = 0; f < 4; f++) {
1408 setup_pieces_pawn((
struct TBEntry_pawn *)ptr, data, &tb_size[2 * f], f);
1409 data += ptr->num + s;
1411 data += ((uintptr_t)data) & 0x01;
1413 for (f = 0; f < files; f++) {
1414 ptr->file[f].precomp[0] = setup_pairs(data, tb_size[2 * f], &size[6 * f], &next, &flags, 1);
1417 ptr->file[f].precomp[1] = setup_pairs(data, tb_size[2 * f + 1], &size[6 * f + 3], &next, &flags, 1);
1420 ptr->file[f].precomp[1] = NULL;
1423 for (f = 0; f < files; f++) {
1424 ptr->file[f].precomp[0]->indextable = (
char *)data;
1425 data += size[6 * f];
1427 ptr->file[f].precomp[1]->indextable = (
char *)data;
1428 data += size[6 * f + 3];
1432 for (f = 0; f < files; f++) {
1433 ptr->file[f].precomp[0]->sizetable = (ushort *)data;
1434 data += size[6 * f + 1];
1436 ptr->file[f].precomp[1]->sizetable = (ushort *)data;
1437 data += size[6 * f + 4];
1441 for (f = 0; f < files; f++) {
1442 data = (ubyte *)((((uintptr_t)data) + 0x3f) & ~0x3f);
1443 ptr->file[f].precomp[0]->data = data;
1444 data += size[6 * f + 2];
1446 data = (ubyte *)((((uintptr_t)data) + 0x3f) & ~0x3f);
1447 ptr->file[f].precomp[1]->data = data;
1448 data += size[6 * f + 5];
1456static int init_table_dtz(
struct TBEntry *entry)
1458 ubyte *data = (ubyte *)entry->data;
1467 if (((uint32 *)data)[0] != DTZ_MAGIC) {
1468 printf(
"Corrupted table.\n");
1472 int files = data[4] & 0x02 ? 4 : 1;
1476 if (!entry->has_pawns) {
1478 setup_pieces_piece_dtz(ptr, data, &tb_size[0]);
1479 data += ptr->num + 1;
1480 data += ((uintptr_t)data) & 0x01;
1482 ptr->precomp = setup_pairs(data, tb_size[0], &size[0], &next, &(ptr->flags), 0);
1486 if (ptr->flags & 2) {
1488 for (i = 0; i < 4; i++) {
1489 ptr->map_idx[i] = (ushort)(data + 1 - ptr->map);
1490 data += 1 + data[0];
1492 data += ((uintptr_t)data) & 0x01;
1495 ptr->precomp->indextable = (
char *)data;
1498 ptr->precomp->sizetable = (ushort *)data;
1501 data = (ubyte *)((((uintptr_t)data) + 0x3f) & ~0x3f);
1502 ptr->precomp->data = data;
1506 s = 1 + (ptr->pawns[1] > 0);
1507 for (f = 0; f < 4; f++) {
1508 setup_pieces_pawn_dtz(ptr, data, &tb_size[f], f);
1509 data += ptr->num + s;
1511 data += ((uintptr_t)data) & 0x01;
1513 for (f = 0; f < files; f++) {
1514 ptr->file[f].precomp = setup_pairs(data, tb_size[f], &size[3 * f], &next, &(ptr->flags[f]), 0);
1519 for (f = 0; f < files; f++) {
1520 if (ptr->flags[f] & 2) {
1522 for (i = 0; i < 4; i++) {
1523 ptr->map_idx[f][i] = (ushort)(data + 1 - ptr->map);
1524 data += 1 + data[0];
1528 data += ((uintptr_t)data) & 0x01;
1530 for (f = 0; f < files; f++) {
1531 ptr->file[f].precomp->indextable = (
char *)data;
1532 data += size[3 * f];
1535 for (f = 0; f < files; f++) {
1536 ptr->file[f].precomp->sizetable = (ushort *)data;
1537 data += size[3 * f + 1];
1540 for (f = 0; f < files; f++) {
1541 data = (ubyte *)((((uintptr_t)data) + 0x3f) & ~0x3f);
1542 ptr->file[f].precomp->data = data;
1543 data += size[3 * f + 2];
1550static ubyte decompress_pairs(
struct PairsData *d, uint64 idx)
1555 uint32 mainidx = (uint32)(idx >> d->idxbits);
1556 int litidx = (idx & (((uint64)1 << d->idxbits) - 1)) - ((uint64)1 << (d->idxbits - 1));
1557 uint32 block = *(uint32 *)(d->indextable + 6 * mainidx);
1558 litidx += *(ushort *)(d->indextable + 6 * mainidx + 4);
1561 litidx += d->sizetable[--block] + 1;
1562 }
while (litidx < 0);
1564 while (litidx > d->sizetable[block])
1565 litidx -= d->sizetable[block++] + 1;
1568 uint32 *ptr = (uint32 *)(d->data + (block << d->blocksize));
1571 ushort *offset = d->offset;
1572 base_t *base = d->base - m;
1573 ubyte *symlen = d->symlen;
1577 uint64 code = internal_bswap64(*((uint64 *)ptr));
1582 while (code < base[l]) l++;
1583 sym = offset[l] + ((code - base[l]) >> (64 - l));
1584 if (litidx < (
int)symlen[sym] + 1)
break;
1585 litidx -= (int)symlen[sym] + 1;
1590 uint32 data = *ptr++;
1591 code |= ((uint64)(internal_bswap32(data))) << bitcnt;
1596 uint32 data = *ptr++;
1597 uint32 code = internal_bswap32(data);
1601 while (code < base[l]) l++;
1602 sym = offset[l] + ((code - base[l]) >> (32 - l));
1603 if (litidx < (
int)symlen[sym] + 1)
break;
1604 litidx -= (int)symlen[sym] + 1;
1608 code |= (next >> (32 - l));
1612 next = internal_bswap32(data);
1615 code |= (next >> (32 - l));
1621 ubyte *sympat = d->sympat;
1622 while (symlen[sym] != 0) {
1623 int w = *(
int *)(sympat + 3 * sym);
1624 int s1 = w & 0x0fff;
1625 if (litidx < (
int)symlen[s1] + 1)
1628 litidx -= (int)symlen[s1] + 1;
1629 sym = (w >> 12) & 0x0fff;
1633 return *(sympat + 3 * sym);
1636void load_dtz_table(
char *str, uint64 key1, uint64 key2)
1642 DTZ_table[0].key1 = key1;
1643 DTZ_table[0].key2 = key2;
1644 DTZ_table[0].entry = NULL;
1647 ptr2 = TB_hash[key1 >> (64 - TBHASHBITS)];
1648 for (i = 0; i < HSHMAX; i++)
1649 if (ptr2[i].key == key1)
break;
1650 if (i == HSHMAX)
return;
1653 ptr3 = (
struct TBEntry *)malloc(ptr->has_pawns
1657 ptr3->data = map_file(str, DTZSUFFIX, &ptr3->mapping);
1658 ptr3->key = ptr->key;
1659 ptr3->num = ptr->num;
1660 ptr3->symmetric = ptr->symmetric;
1661 ptr3->has_pawns = ptr->has_pawns;
1662 if (ptr3->has_pawns) {
1664 entry->pawns[0] = ((
struct TBEntry_pawn *)ptr)->pawns[0];
1665 entry->pawns[1] = ((
struct TBEntry_pawn *)ptr)->pawns[1];
1670 if (!init_table_dtz(ptr3))
1673 DTZ_table[0].entry = ptr3;
1676static void free_wdl_entry(
struct TBEntry *entry)
1678 unmap_file(entry->data, entry->mapping);
1679 if (!entry->has_pawns) {
1681 free(ptr->precomp[0]);
1682 if (ptr->precomp[1])
1683 free(ptr->precomp[1]);
1687 for (f = 0; f < 4; f++) {
1688 free(ptr->file[f].precomp[0]);
1689 if (ptr->file[f].precomp[1])
1690 free(ptr->file[f].precomp[1]);
1695static void free_dtz_entry(
struct TBEntry *entry)
1697 unmap_file(entry->data, entry->mapping);
1698 if (!entry->has_pawns) {
1704 for (f = 0; f < 4; f++)
1705 free(ptr->file[f].precomp);
1710static int wdl_to_map[5] = { 1, 3, 0, 2, 0 };
1711static ubyte pa_flags[5] = { 8, 0, 0, 0, 4 };