Subversion Repositories Games.Chess Giants

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
99 pmbaty 1
/*
2
  Copyright (c) 2011-2013 Ronald de Man
3
  This file may be redistributed and/or modified without restrictions.
4
 
5
  tbcore.c contains engine-independent routines of the tablebase probing code.
6
  This file should not need to much adaptation to add tablebase probing to
7
  a particular engine, provided the engine is written in C or C++.
8
*/
9
 
10
#include <stdio.h>
11
#include <stdint.h>
12
#include <stdlib.h>
13
#include <string.h>
14
#include <sys/stat.h>
15
#include <fcntl.h>
16
#include <mutex>
17
#include <atomic>
18
#ifndef _WIN32
19
#include <unistd.h>
20
#include <sys/mman.h>
21
#endif
22
#include "rtb-core.hpp"
23
 
24
 
25
#define TBMAX_PIECE 254
26
#define TBMAX_PAWN 256
27
#define HSHMAX 4
28
 
29
#define Swap(a,b) {int tmp=a;a=b;b=tmp;}
30
 
31
#define TB_PAWN 1
32
#define TB_KNIGHT 2
33
#define TB_BISHOP 3
34
#define TB_ROOK 4
35
#define TB_QUEEN 5
36
#define TB_KING 6
37
 
38
#define TB_WPAWN TB_PAWN
39
#define TB_BPAWN (TB_PAWN | 8)
40
 
41
static std::mutex TB_mutex;
42
 
43
static bool initialized = false;
44
static int num_paths = 0;
45
static char *path_string = NULL;
46
static char **paths = NULL;
47
 
48
static int TBnum_piece, TBnum_pawn;
49
static struct TBEntry_piece TB_piece[TBMAX_PIECE];
50
static struct TBEntry_pawn TB_pawn[TBMAX_PAWN];
51
 
52
static struct TBHashEntry WDL_hash[1 << TBHASHBITS][HSHMAX];
53
static struct DTZTableEntry DTZ_hash[1 << TBHASHBITS][HSHMAX];
54
 
55
static void init_indices(void);
56
static uint64_t calc_key_from_pcs(const int *pcs, bool mirror);
57
static void free_wdl_entry(struct TBEntry *entry);
58
static void free_dtz_entry(struct TBEntry *entry);
59
 
60
static FD open_tb(const char *str, const char *suffix)
61
{
62
    for (int  i = 0; i < num_paths; i++) {
63
        std::string file(paths[i]);
64
        file += '/';
65
        file += str;
66
        file += suffix;
67
#ifndef _WIN32
68
        FD fd = open(file.c_str(), O_RDONLY);
69
#else
70
        FD fd = CreateFile(file.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL,
71
                           OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
72
#endif
73
        if (fd != FD_ERR) return fd;
74
    }
75
    return FD_ERR;
76
}
77
 
78
static void close_tb(FD fd)
79
{
80
#ifndef _WIN32
81
    close(fd);
82
#else
83
    CloseHandle(fd);
84
#endif
85
}
86
 
87
static char *map_file(const char *name, const char *suffix, uint64_t *mapping)
88
{
89
    FD fd = open_tb(name, suffix);
90
    if (fd == FD_ERR)
91
        return NULL;
92
#ifndef _WIN32
93
    struct stat statbuf;
94
    fstat(fd, &statbuf);
95
    *mapping = statbuf.st_size;
96
    char *data = (char *)mmap(NULL, statbuf.st_size, PROT_READ,
97
                              MAP_SHARED, fd, 0);
98
    if (data == (char *)(-1)) {
99
        std::cout << "Could not mmap() " << name << std::endl;
100
        close_tb(fd);
101
        return NULL;
102
    }
103
#else
104
    DWORD size_low, size_high;
105
    size_low = GetFileSize(fd, &size_high);
106
    //  *size = ((uint64_t)size_high) << 32 | ((uint64_t)size_low);
107
    HANDLE map = CreateFileMapping(fd, NULL, PAGE_READONLY, size_high, size_low,
108
                                   NULL);
109
    if (map == NULL) {
110
        std::cout << "CreateFileMapping() failed" << std::endl;
111
        close_tb(fd);
112
        return NULL;
113
    }
114
    *mapping = (uint64_t)map;
115
    char *data = (char *)MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
116
    if (data == NULL) {
117
        std::cout << "MapViewOfFile() failed, name = " << name << suffix << ", error = " << GetLastError() << std::endl;
118
        close_tb(fd);
119
        return NULL;
120
    }
121
#endif
122
    close_tb(fd);
123
    return data;
124
}
125
 
126
#ifndef _WIN32
127
static void unmap_file(char *data, uint64_t size)
128
{
129
    if (!data) return;
130
    munmap(data, size);
131
}
132
#else
133
static void unmap_file(char *data, uint64_t mapping)
134
{
135
    if (!data) return;
136
    UnmapViewOfFile(data);
137
    CloseHandle((HANDLE)mapping);
138
}
139
#endif
140
 
141
static void add_to_hash(struct TBEntry *ptr, uint64_t key)
142
{
143
    int i, hshidx;
144
 
145
    hshidx = key >> (64 - TBHASHBITS);
146
    i = 0;
147
    while (i < HSHMAX && WDL_hash[hshidx][i].ptr)
148
        i++;
149
    assert(i < HSHMAX);
150
    WDL_hash[hshidx][i].key = key;
151
    WDL_hash[hshidx][i].ptr = ptr;
152
}
153
 
154
static void add_to_dtz_hash(uint64_t key1, uint64_t key2)
155
{
156
    int i, hshidx;
157
 
158
    hshidx = key1 >> (64 - TBHASHBITS);
159
    i = 0;
160
    while (i < HSHMAX && DTZ_hash[hshidx][i].key1)
161
        i++;
162
    assert(i < HSHMAX);
163
    DTZ_hash[hshidx][i].key1 = key1;
164
    DTZ_hash[hshidx][i].key2 = key2;
165
    DTZ_hash[hshidx][i].entry = NULL;
166
}
167
 
168
static char pchr[] = {'K', 'Q', 'R', 'B', 'N', 'P'};
169
 
170
static void init_tb(char *str)
171
{
172
    FD fd;
173
    struct TBEntry *entry;
174
    int i, j, pcs[16];
175
    uint64_t key, key2;
176
    int color;
177
    char *s;
178
 
179
    fd = open_tb(str, WDLSUFFIX);
180
    if (fd == FD_ERR) return;
181
    close_tb(fd);
182
 
183
    for (i = 0; i < 16; i++)
184
        pcs[i] = 0;
185
    color = 0;
186
    for (s = str; *s; s++)
187
        switch (*s) {
188
        case 'P':
189
            pcs[TB_PAWN | color]++;
190
            break;
191
        case 'N':
192
            pcs[TB_KNIGHT | color]++;
193
            break;
194
        case 'B':
195
            pcs[TB_BISHOP | color]++;
196
            break;
197
        case 'R':
198
            pcs[TB_ROOK | color]++;
199
            break;
200
        case 'Q':
201
            pcs[TB_QUEEN | color]++;
202
            break;
203
        case 'K':
204
            pcs[TB_KING | color]++;
205
            break;
206
        case 'v':
207
            color = 0x08;
208
            break;
209
        }
210
    for (i = 0; i < 8; i++)
211
        if (pcs[i] != pcs[i+8])
212
            break;
213
    key = calc_key_from_pcs(pcs, false);
214
    key2 = calc_key_from_pcs(pcs, true);
215
    if (pcs[TB_WPAWN] + pcs[TB_BPAWN] == 0) {
216
        assert(TBnum_piece < TBMAX_PIECE);
217
        entry = (struct TBEntry *)&TB_piece[TBnum_piece++];
218
    } else {
219
        assert(TBnum_pawn < TBMAX_PAWN);
220
        entry = (struct TBEntry *)&TB_pawn[TBnum_pawn++];
221
    }
222
    entry->key = key;
223
    entry->ready = 0;
224
    entry->num = 0;
225
    for (i = 0; i < 16; i++)
226
        entry->num += pcs[i];
227
    entry->symmetric = (key == key2);
228
    entry->has_pawns = (pcs[TB_WPAWN] + pcs[TB_BPAWN] > 0);
229
    if (entry->num > Syzygy::TBLargest)
230
        Syzygy::TBLargest = entry->num;
231
 
232
    if (entry->has_pawns) {
233
        struct TBEntry_pawn *ptr = (struct TBEntry_pawn *)entry;
234
        ptr->pawns[0] = pcs[TB_WPAWN];
235
        ptr->pawns[1] = pcs[TB_BPAWN];
236
        if (pcs[TB_BPAWN] > 0
237
            && (pcs[TB_WPAWN] == 0 || pcs[TB_BPAWN] < pcs[TB_WPAWN])) {
238
            ptr->pawns[0] = pcs[TB_BPAWN];
239
            ptr->pawns[1] = pcs[TB_WPAWN];
240
        }
241
    } else {
242
        struct TBEntry_piece *ptr = (struct TBEntry_piece *)entry;
243
        for (i = 0, j = 0; i < 16; i++)
244
            if (pcs[i] == 1) j++;
245
        if (j >= 3) ptr->enc_type = 0;
246
        else if (j == 2) ptr->enc_type = 2;
247
        else { /* only for suicide */
248
            j = 16;
249
            for (i = 0; i < 16; i++) {
250
                if (pcs[i] < j && pcs[i] > 1) j = pcs[i];
251
                ptr->enc_type = 1 + j;
252
            }
253
        }
254
    }
255
    add_to_hash(entry, key);
256
    if (key2 != key) add_to_hash(entry, key2);
257
    add_to_dtz_hash(key, key2);
258
}
259
 
260
void Syzygy::init(const std::string& path)
261
{
262
    char str[16];
263
    int i, j, k, l;
264
 
265
    { // The probing code currently expects a little-endian architecture
266
        static_assert(sizeof(uint32_t) == 4, "Unsupported architecture");
267
        uint32_t test = 0x01020304;
268
        unsigned char* p = (unsigned char*)&test;
269
        if (p[0] != 4 || p[1] != 3 || p[2] != 2 || p[3] != 1)
270
            return;
271
    }
272
 
273
    if (initialized) {
274
        free(path_string); path_string = NULL;
275
        free(paths); paths = NULL;
276
        struct TBEntry *entry;
277
        for (i = 0; i < TBnum_piece; i++) {
278
            entry = (struct TBEntry *)&TB_piece[i];
279
            free_wdl_entry(entry);
280
        }
281
        for (i = 0; i < TBnum_pawn; i++) {
282
            entry = (struct TBEntry *)&TB_pawn[i];
283
            free_wdl_entry(entry);
284
        }
285
        for (i = 0; i < (1 << TBHASHBITS); i++)
286
            for (j = 0; j < HSHMAX; j++) {
287
                if ((void*) DTZ_hash[i][j].entry) { // Pierre-Marie Baty -- added type cast
288
                    free_dtz_entry(DTZ_hash[i][j].entry);
289
                    DTZ_hash[i][j].entry = NULL;
290
                }
291
            }
292
        TBnum_piece = TBnum_pawn = 0;
293
        TBLargest = 0;
294
    } else {
295
        init_indices();
296
        initialized = true;
297
    }
298
 
299
    const char *p = path.c_str();
300
    if (strlen(p) == 0)
301
        return;
302
    path_string = (char *)malloc(strlen(p) + 1);
303
    strcpy_s(path_string, strlen(p) + 1, p); // Pierre-Marie Baty -- use strcpy_s() instead of strcpy
304
    num_paths = 0;
305
    for (i = 0;; i++) {
306
        if (path_string[i] && path_string[i] != SEP_CHAR)
307
            num_paths++;
308
        while (path_string[i] && path_string[i] != SEP_CHAR)
309
            i++;
310
        if (!path_string[i]) break;
311
        path_string[i] = 0;
312
    }
313
    paths = (char **)malloc(num_paths * sizeof(char *));
314
    for (i = j = 0; i < num_paths; i++) {
315
        while (!path_string[j]) j++;
316
        paths[i] = &path_string[j];
317
        while (path_string[j]) j++;
318
    }
319
 
320
    for (i = 0; i < (1 << TBHASHBITS); i++)
321
        for (j = 0; j < HSHMAX; j++) {
322
            WDL_hash[i][j].key = 0ULL;
323
            WDL_hash[i][j].ptr = NULL;
324
        }
325
 
326
    for (i = 0; i < (1 << TBHASHBITS); i++)
327
        for (j = 0; j < HSHMAX; j++) {
328
            DTZ_hash[i][j].key1 = 0ULL;
329
            DTZ_hash[i][j].key2 = 0ULL;
330
            DTZ_hash[i][j].entry = NULL;
331
        }
332
 
333
    for (i = 1; i < 6; i++) {
334
        sprintf_s(str, sizeof(str), "K%cvK", pchr[i]); // Pierre-Marie Baty -- using sprintf_s() instead of sprintf
335
        init_tb(str);
336
    }
337
 
338
    for (i = 1; i < 6; i++)
339
        for (j = i; j < 6; j++) {
340
            sprintf_s(str, sizeof(str), "K%cvK%c", pchr[i], pchr[j]); // Pierre-Marie Baty -- using sprintf_s() instead of sprintf
341
            init_tb(str);
342
        }
343
 
344
    for (i = 1; i < 6; i++)
345
        for (j = i; j < 6; j++) {
346
            sprintf_s(str, sizeof(str), "K%c%cvK", pchr[i], pchr[j]); // Pierre-Marie Baty -- using sprintf_s() instead of sprintf
347
            init_tb(str);
348
        }
349
 
350
    for (i = 1; i < 6; i++)
351
        for (j = i; j < 6; j++)
352
            for (k = 1; k < 6; k++) {
353
                sprintf_s(str, sizeof(str), "K%c%cvK%c", pchr[i], pchr[j], pchr[k]); // Pierre-Marie Baty -- using sprintf_s() instead of sprintf
354
                init_tb(str);
355
            }
356
 
357
    for (i = 1; i < 6; i++)
358
        for (j = i; j < 6; j++)
359
            for (k = j; k < 6; k++) {
360
                sprintf_s(str, sizeof(str), "K%c%c%cvK", pchr[i], pchr[j], pchr[k]); // Pierre-Marie Baty -- using sprintf_s() instead of sprintf
361
                init_tb(str);
362
            }
363
 
364
    // 6-piece tables are only supported for 64-bit, because tables are mmap()ed into memory
365
    if (sizeof(char*) >= 8) {
366
        for (i = 1; i < 6; i++)
367
            for (j = i; j < 6; j++)
368
                for (k = i; k < 6; k++)
369
                    for (l = (i == k) ? j : k; l < 6; l++) {
370
                        sprintf_s(str, sizeof(str), "K%c%cvK%c%c", pchr[i], pchr[j], pchr[k], pchr[l]); // Pierre-Marie Baty -- using sprintf_s() instead of sprintf
371
                        init_tb(str);
372
                    }
373
 
374
        for (i = 1; i < 6; i++)
375
            for (j = i; j < 6; j++)
376
                for (k = j; k < 6; k++)
377
                    for (l = 1; l < 6; l++) {
378
                        sprintf_s(str, sizeof(str), "K%c%c%cvK%c", pchr[i], pchr[j], pchr[k], pchr[l]); // Pierre-Marie Baty -- using sprintf_s() instead of sprintf
379
                        init_tb(str);
380
                    }
381
 
382
        for (i = 1; i < 6; i++)
383
            for (j = i; j < 6; j++)
384
                for (k = j; k < 6; k++)
385
                    for (l = k; l < 6; l++) {
386
                        sprintf_s(str, sizeof(str), "K%c%c%c%cvK", pchr[i], pchr[j], pchr[k], pchr[l]); // Pierre-Marie Baty -- using sprintf_s() instead of sprintf
387
                        init_tb(str);
388
                    }
389
    }
390
 
391
    std::cout << "info string Found " << (TBnum_piece + TBnum_pawn) << " syzygy tablebases" << std::endl;
392
}
393
 
394
static const signed char offdiag[] = {
395
    0,-1,-1,-1,-1,-1,-1,-1,
396
    1, 0,-1,-1,-1,-1,-1,-1,
397
    1, 1, 0,-1,-1,-1,-1,-1,
398
    1, 1, 1, 0,-1,-1,-1,-1,
399
    1, 1, 1, 1, 0,-1,-1,-1,
400
    1, 1, 1, 1, 1, 0,-1,-1,
401
    1, 1, 1, 1, 1, 1, 0,-1,
402
    1, 1, 1, 1, 1, 1, 1, 0
403
};
404
 
405
static const ubyte triangle[] = {
406
    6, 0, 1, 2, 2, 1, 0, 6,
407
    0, 7, 3, 4, 4, 3, 7, 0,
408
    1, 3, 8, 5, 5, 8, 3, 1,
409
    2, 4, 5, 9, 9, 5, 4, 2,
410
    2, 4, 5, 9, 9, 5, 4, 2,
411
    1, 3, 8, 5, 5, 8, 3, 1,
412
    0, 7, 3, 4, 4, 3, 7, 0,
413
    6, 0, 1, 2, 2, 1, 0, 6
414
};
415
 
416
static const ubyte invtriangle[] = {
417
    1, 2, 3, 10, 11, 19, 0, 9, 18, 27
418
};
419
 
420
static const ubyte invdiag[] = {
421
    0, 9, 18, 27, 36, 45, 54, 63,
422
    7, 14, 21, 28, 35, 42, 49, 56
423
};
424
 
425
static const ubyte flipdiag[] = {
426
    0,  8, 16, 24, 32, 40, 48, 56,
427
    1,  9, 17, 25, 33, 41, 49, 57,
428
    2, 10, 18, 26, 34, 42, 50, 58,
429
    3, 11, 19, 27, 35, 43, 51, 59,
430
    4, 12, 20, 28, 36, 44, 52, 60,
431
    5, 13, 21, 29, 37, 45, 53, 61,
432
    6, 14, 22, 30, 38, 46, 54, 62,
433
    7, 15, 23, 31, 39, 47, 55, 63
434
};
435
 
436
static const ubyte lower[] = {
437
    28,  0,  1,  2,  3,  4,  5,  6,
438
    0, 29,  7,  8,  9, 10, 11, 12,
439
    1,  7, 30, 13, 14, 15, 16, 17,
440
    2,  8, 13, 31, 18, 19, 20, 21,
441
    3,  9, 14, 18, 32, 22, 23, 24,
442
    4, 10, 15, 19, 22, 33, 25, 26,
443
    5, 11, 16, 20, 23, 25, 34, 27,
444
    6, 12, 17, 21, 24, 26, 27, 35
445
};
446
 
447
static const ubyte diag[] = {
448
    0,  0,  0,  0,  0,  0,  0,  8,
449
    0,  1,  0,  0,  0,  0,  9,  0,
450
    0,  0,  2,  0,  0, 10,  0,  0,
451
    0,  0,  0,  3, 11,  0,  0,  0,
452
    0,  0,  0, 12,  4,  0,  0,  0,
453
    0,  0, 13,  0,  0,  5,  0,  0,
454
    0, 14,  0,  0,  0,  0,  6,  0,
455
    15,  0,  0,  0,  0,  0,  0,  7
456
};
457
 
458
static const ubyte flap[] = {
459
    0, 0, 0, 0, 0, 0, 0, 0,
460
    0, 6, 12, 18, 18, 12, 6, 0,
461
    1, 7, 13, 19, 19, 13, 7, 1,
462
    2, 8, 14, 20, 20, 14, 8, 2,
463
    3, 9, 15, 21, 21, 15, 9, 3,
464
    4, 10, 16, 22, 22, 16, 10, 4,
465
    5, 11, 17, 23, 23, 17, 11, 5,
466
    0, 0, 0, 0, 0, 0, 0, 0
467
};
468
 
469
static const ubyte ptwist[] = {
470
    0, 0, 0, 0, 0, 0, 0, 0,
471
    47, 35, 23, 11, 10, 22, 34, 46,
472
    45, 33, 21, 9, 8, 20, 32, 44,
473
    43, 31, 19, 7, 6, 18, 30, 42,
474
    41, 29, 17, 5, 4, 16, 28, 40,
475
    39, 27, 15, 3, 2, 14, 26, 38,
476
    37, 25, 13, 1, 0, 12, 24, 36,
477
    0, 0, 0, 0, 0, 0, 0, 0
478
};
479
 
480
static const ubyte invflap[] = {
481
    8, 16, 24, 32, 40, 48,
482
    9, 17, 25, 33, 41, 49,
483
    10, 18, 26, 34, 42, 50,
484
    11, 19, 27, 35, 43, 51
485
};
486
 
487
static const ubyte invptwist[] = {
488
    52, 51, 44, 43, 36, 35, 28, 27, 20, 19, 12, 11,
489
    53, 50, 45, 42, 37, 34, 29, 26, 21, 18, 13, 10,
490
    54, 49, 46, 41, 38, 33, 30, 25, 22, 17, 14, 9,
491
    55, 48, 47, 40, 39, 32, 31, 24, 23, 16, 15, 8
492
};
493
 
494
static const ubyte file_to_file[] = {
495
    0, 1, 2, 3, 3, 2, 1, 0
496
};
497
 
498
static const short KK_idx[10][64] = {
499
    { -1, -1, -1,  0,  1,  2,  3,  4,
500
      -1, -1, -1,  5,  6,  7,  8,  9,
501
      10, 11, 12, 13, 14, 15, 16, 17,
502
      18, 19, 20, 21, 22, 23, 24, 25,
503
      26, 27, 28, 29, 30, 31, 32, 33,
504
      34, 35, 36, 37, 38, 39, 40, 41,
505
      42, 43, 44, 45, 46, 47, 48, 49,
506
      50, 51, 52, 53, 54, 55, 56, 57 },
507
    { 58, -1, -1, -1, 59, 60, 61, 62,
508
      63, -1, -1, -1, 64, 65, 66, 67,
509
      68, 69, 70, 71, 72, 73, 74, 75,
510
      76, 77, 78, 79, 80, 81, 82, 83,
511
      84, 85, 86, 87, 88, 89, 90, 91,
512
      92, 93, 94, 95, 96, 97, 98, 99,
513
      100,101,102,103,104,105,106,107,
514
      108,109,110,111,112,113,114,115},
515
    {116,117, -1, -1, -1,118,119,120,
516
     121,122, -1, -1, -1,123,124,125,
517
     126,127,128,129,130,131,132,133,
518
     134,135,136,137,138,139,140,141,
519
     142,143,144,145,146,147,148,149,
520
     150,151,152,153,154,155,156,157,
521
     158,159,160,161,162,163,164,165,
522
     166,167,168,169,170,171,172,173 },
523
    {174, -1, -1, -1,175,176,177,178,
524
     179, -1, -1, -1,180,181,182,183,
525
     184, -1, -1, -1,185,186,187,188,
526
     189,190,191,192,193,194,195,196,
527
     197,198,199,200,201,202,203,204,
528
     205,206,207,208,209,210,211,212,
529
     213,214,215,216,217,218,219,220,
530
     221,222,223,224,225,226,227,228 },
531
    {229,230, -1, -1, -1,231,232,233,
532
     234,235, -1, -1, -1,236,237,238,
533
     239,240, -1, -1, -1,241,242,243,
534
     244,245,246,247,248,249,250,251,
535
     252,253,254,255,256,257,258,259,
536
     260,261,262,263,264,265,266,267,
537
     268,269,270,271,272,273,274,275,
538
     276,277,278,279,280,281,282,283 },
539
    {284,285,286,287,288,289,290,291,
540
     292,293, -1, -1, -1,294,295,296,
541
     297,298, -1, -1, -1,299,300,301,
542
     302,303, -1, -1, -1,304,305,306,
543
     307,308,309,310,311,312,313,314,
544
     315,316,317,318,319,320,321,322,
545
     323,324,325,326,327,328,329,330,
546
     331,332,333,334,335,336,337,338 },
547
    { -1, -1,339,340,341,342,343,344,
548
      -1, -1,345,346,347,348,349,350,
549
      -1, -1,441,351,352,353,354,355,
550
      -1, -1, -1,442,356,357,358,359,
551
      -1, -1, -1, -1,443,360,361,362,
552
      -1, -1, -1, -1, -1,444,363,364,
553
      -1, -1, -1, -1, -1, -1,445,365,
554
      -1, -1, -1, -1, -1, -1, -1,446 },
555
    { -1, -1, -1,366,367,368,369,370,
556
      -1, -1, -1,371,372,373,374,375,
557
      -1, -1, -1,376,377,378,379,380,
558
      -1, -1, -1,447,381,382,383,384,
559
      -1, -1, -1, -1,448,385,386,387,
560
      -1, -1, -1, -1, -1,449,388,389,
561
      -1, -1, -1, -1, -1, -1,450,390,
562
      -1, -1, -1, -1, -1, -1, -1,451 },
563
    {452,391,392,393,394,395,396,397,
564
     -1, -1, -1, -1,398,399,400,401,
565
     -1, -1, -1, -1,402,403,404,405,
566
     -1, -1, -1, -1,406,407,408,409,
567
     -1, -1, -1, -1,453,410,411,412,
568
     -1, -1, -1, -1, -1,454,413,414,
569
     -1, -1, -1, -1, -1, -1,455,415,
570
     -1, -1, -1, -1, -1, -1, -1,456 },
571
    {457,416,417,418,419,420,421,422,
572
     -1,458,423,424,425,426,427,428,
573
     -1, -1, -1, -1, -1,429,430,431,
574
     -1, -1, -1, -1, -1,432,433,434,
575
     -1, -1, -1, -1, -1,435,436,437,
576
     -1, -1, -1, -1, -1,459,438,439,
577
     -1, -1, -1, -1, -1, -1,460,440,
578
     -1, -1, -1, -1, -1, -1, -1,461 }
579
};
580
 
581
static int binomial[5][64];
582
static int pawnidx[5][24];
583
static int pfactor[5][4];
584
 
585
static void init_indices(void)
586
{
587
    int i, j, k;
588
 
589
    // binomial[k-1][n] = Bin(n, k)
590
    for (i = 0; i < 5; i++)
591
        for (j = 0; j < 64; j++) {
592
            int f = j;
593
            int l = 1;
594
            for (k = 1; k <= i; k++) {
595
                f *= (j - k);
596
                l *= (k + 1);
597
            }
598
            binomial[i][j] = f / l;
599
        }
600
 
601
    for (i = 0; i < 5; i++) {
602
        int s = 0;
603
        for (j = 0; j < 6; j++) {
604
            pawnidx[i][j] = s;
605
            s += (i == 0) ? 1 : binomial[i - 1][ptwist[invflap[j]]];
606
        }
607
        pfactor[i][0] = s;
608
        s = 0;
609
        for (; j < 12; j++) {
610
            pawnidx[i][j] = s;
611
            s += (i == 0) ? 1 : binomial[i - 1][ptwist[invflap[j]]];
612
        }
613
        pfactor[i][1] = s;
614
        s = 0;
615
        for (; j < 18; j++) {
616
            pawnidx[i][j] = s;
617
            s += (i == 0) ? 1 : binomial[i - 1][ptwist[invflap[j]]];
618
        }
619
        pfactor[i][2] = s;
620
        s = 0;
621
        for (; j < 24; j++) {
622
            pawnidx[i][j] = s;
623
            s += (i == 0) ? 1 : binomial[i - 1][ptwist[invflap[j]]];
624
        }
625
        pfactor[i][3] = s;
626
    }
627
}
628
 
629
static uint64_t encode_piece(struct TBEntry_piece *ptr, ubyte *norm, int *pos, int *factor)
630
{
631
    uint64_t idx = 0;
632
    int i, j, k, m, l, p;
633
    int n = ptr->num;
634
 
635
    if (pos[0] & 0x04) {
636
        for (i = 0; i < n; i++)
637
            pos[i] ^= 0x07;
638
    }
639
    if (pos[0] & 0x20) {
640
        for (i = 0; i < n; i++)
641
            pos[i] ^= 0x38;
642
    }
643
 
644
    for (i = 0; i < n; i++)
645
        if (offdiag[pos[i]]) break;
646
    if (i < (ptr->enc_type == 0 ? 3 : 2) && offdiag[pos[i]] > 0)
647
        for (i = 0; i < n; i++)
648
            pos[i] = flipdiag[pos[i]];
649
 
650
    switch (ptr->enc_type) {
651
 
652
    case 0: /* 111 */
653
        i = (pos[1] > pos[0]);
654
        j = (pos[2] > pos[0]) + (pos[2] > pos[1]);
655
 
656
        if (offdiag[pos[0]])
657
            idx = triangle[pos[0]] * 63*62 + (pos[1] - i) * 62 + (pos[2] - j);
658
        else if (offdiag[pos[1]])
659
            idx = 6*63*62 + diag[pos[0]] * 28*62 + lower[pos[1]] * 62 + pos[2] - j;
660
        else if (offdiag[pos[2]])
661
            idx = 6*63*62 + 4*28*62 + (diag[pos[0]]) * 7*28 + (diag[pos[1]] - i) * 28 + lower[pos[2]];
662
        else
663
            idx = 6*63*62 + 4*28*62 + 4*7*28 + (diag[pos[0]] * 7*6) + (diag[pos[1]] - i) * 6 + (diag[pos[2]] - j);
664
        i = 3;
665
        break;
666
 
667
    case 1: /* K3 */
668
        j = (pos[2] > pos[0]) + (pos[2] > pos[1]);
669
 
670
        idx = KK_idx[triangle[pos[0]]][pos[1]];
671
        if (idx < 441)
672
            idx = idx + 441 * (pos[2] - j);
673
        else {
674
            idx = 441*62 + (idx - 441) + 21 * lower[pos[2]];
675
            if (!offdiag[pos[2]])
676
                idx -= j * 21;
677
        }
678
        i = 3;
679
        break;
680
 
681
    default: /* K2 */
682
        idx = KK_idx[triangle[pos[0]]][pos[1]];
683
        i = 2;
684
        break;
685
    }
686
    idx *= factor[0];
687
 
688
    for (; i < n;) {
689
        int t = norm[i];
690
        for (j = i; j < i + t; j++)
691
            for (k = j + 1; k < i + t; k++)
692
                if (pos[j] > pos[k]) Swap(pos[j], pos[k]);
693
        int s = 0;
694
        for (m = i; m < i + t; m++) {
695
            p = pos[m];
696
            for (l = 0, j = 0; l < i; l++)
697
                j += (p > pos[l]);
698
            s += binomial[m - i][p - j];
699
        }
700
        idx += ((uint64_t)s) * ((uint64_t)factor[i]);
701
        i += t;
702
    }
703
 
704
    return idx;
705
}
706
 
707
// determine file of leftmost pawn and sort pawns
708
static int pawn_file(struct TBEntry_pawn *ptr, int *pos)
709
{
710
    int i;
711
 
712
    for (i = 1; i < ptr->pawns[0]; i++)
713
        if (flap[pos[0]] > flap[pos[i]])
714
            Swap(pos[0], pos[i]);
715
 
716
    return file_to_file[pos[0] & 0x07];
717
}
718
 
719
static uint64_t encode_pawn(struct TBEntry_pawn *ptr, ubyte *norm, int *pos, int *factor)
720
{
721
    uint64_t idx;
722
    int i, j, k, m, s, t;
723
    int n = ptr->num;
724
 
725
    if (pos[0] & 0x04)
726
        for (i = 0; i < n; i++)
727
            pos[i] ^= 0x07;
728
 
729
    for (i = 1; i < ptr->pawns[0]; i++)
730
        for (j = i + 1; j < ptr->pawns[0]; j++)
731
            if (ptwist[pos[i]] < ptwist[pos[j]])
732
                Swap(pos[i], pos[j]);
733
 
734
    t = ptr->pawns[0] - 1;
735
    idx = pawnidx[t][flap[pos[0]]];
736
    for (i = t; i > 0; i--)
737
        idx += binomial[t - i][ptwist[pos[i]]];
738
    idx *= factor[0];
739
 
740
    // remaining pawns
741
    i = ptr->pawns[0];
742
    t = i + ptr->pawns[1];
743
    if (t > i) {
744
        for (j = i; j < t; j++)
745
            for (k = j + 1; k < t; k++)
746
                if (pos[j] > pos[k]) Swap(pos[j], pos[k]);
747
        s = 0;
748
        for (m = i; m < t; m++) {
749
            int p = pos[m];
750
            for (k = 0, j = 0; k < i; k++)
751
                j += (p > pos[k]);
752
            s += binomial[m - i][p - j - 8];
753
        }
754
        idx += ((uint64_t)s) * ((uint64_t)factor[i]);
755
        i = t;
756
    }
757
 
758
    for (; i < n;) {
759
        t = norm[i];
760
        for (j = i; j < i + t; j++)
761
            for (k = j + 1; k < i + t; k++)
762
                if (pos[j] > pos[k]) Swap(pos[j], pos[k]);
763
        s = 0;
764
        for (m = i; m < i + t; m++) {
765
            int p = pos[m];
766
            for (k = 0, j = 0; k < i; k++)
767
                j += (p > pos[k]);
768
            s += binomial[m - i][p - j];
769
        }
770
        idx += ((uint64_t)s) * ((uint64_t)factor[i]);
771
        i += t;
772
    }
773
 
774
    return idx;
775
}
776
 
777
static ubyte decompress_pairs(struct PairsData *d, uint64_t index);
778
 
779
// place k like pieces on n squares
780
static int subfactor(int k, int n)
781
{
782
    int i, f, l;
783
 
784
    f = n;
785
    l = 1;
786
    for (i = 1; i < k; i++) {
787
        f *= n - i;
788
        l *= i + 1;
789
    }
790
 
791
    return f / l;
792
}
793
 
794
static uint64_t calc_factors_piece(int *factor, int num, int order, ubyte *norm, ubyte enc_type)
795
{
796
    int i, k, n;
797
    uint64_t f;
798
    static int pivfac[] = { 31332, 28056, 462 };
799
 
800
    n = 64 - norm[0];
801
 
802
    f = 1;
803
    for (i = norm[0], k = 0; i < num || k == order; k++) {
804
        if (k == order) {
805
            factor[0] = (int)f; // Pierre-Marie Baty -- added type cast
806
            f *= pivfac[enc_type];
807
        } else {
808
            factor[i] = (int)f; // Pierre-Marie Baty -- added type cast
809
            f *= subfactor(norm[i], n);
810
            n -= norm[i];
811
            i += norm[i];
812
        }
813
    }
814
 
815
    return f;
816
}
817
 
818
static uint64_t calc_factors_pawn(int *factor, int num, int order, int order2, ubyte *norm, int file)
819
{
820
    int i, k, n;
821
    uint64_t f;
822
 
823
    i = norm[0];
824
    if (order2 < 0x0f) i += norm[i];
825
    n = 64 - i;
826
 
827
    f = 1;
828
    for (k = 0; i < num || k == order || k == order2; k++) {
829
        if (k == order) {
830
            factor[0] = (int)f; // Pierre-Marie Baty -- added type cast
831
            f *= pfactor[norm[0] - 1][file];
832
        } else if (k == order2) {
833
            factor[norm[0]] = (int)f; // Pierre-Marie Baty -- added type cast
834
            f *= subfactor(norm[norm[0]], 48 - norm[0]);
835
        } else {
836
            factor[i] = (int)f; // Pierre-Marie Baty -- added type cast
837
            f *= subfactor(norm[i], n);
838
            n -= norm[i];
839
            i += norm[i];
840
        }
841
    }
842
 
843
    return f;
844
}
845
 
846
static void set_norm_piece(struct TBEntry_piece *ptr, ubyte *norm, ubyte *pieces)
847
{
848
    int i, j;
849
 
850
    for (i = 0; i < ptr->num; i++)
851
        norm[i] = 0;
852
 
853
    switch (ptr->enc_type) {
854
    case 0:
855
        norm[0] = 3;
856
        break;
857
    case 2:
858
        norm[0] = 2;
859
        break;
860
    default:
861
        norm[0] = ptr->enc_type - 1;
862
        break;
863
    }
864
 
865
    for (i = norm[0]; i < ptr->num; i += norm[i])
866
        for (j = i; j < ptr->num && pieces[j] == pieces[i]; j++)
867
            norm[i]++;
868
}
869
 
870
static void set_norm_pawn(struct TBEntry_pawn *ptr, ubyte *norm, ubyte *pieces)
871
{
872
    int i, j;
873
 
874
    for (i = 0; i < ptr->num; i++)
875
        norm[i] = 0;
876
 
877
    norm[0] = ptr->pawns[0];
878
    if (ptr->pawns[1]) norm[ptr->pawns[0]] = ptr->pawns[1];
879
 
880
    for (i = ptr->pawns[0] + ptr->pawns[1]; i < ptr->num; i += norm[i])
881
        for (j = i; j < ptr->num && pieces[j] == pieces[i]; j++)
882
            norm[i]++;
883
}
884
 
885
static void setup_pieces_piece(struct TBEntry_piece *ptr, unsigned char *data, uint64_t *tb_size)
886
{
887
    int i;
888
    int order;
889
 
890
    for (i = 0; i < ptr->num; i++)
891
        ptr->pieces[0][i] = data[i + 1] & 0x0f;
892
    order = data[0] & 0x0f;
893
    set_norm_piece(ptr, ptr->norm[0], ptr->pieces[0]);
894
    tb_size[0] = calc_factors_piece(ptr->factor[0], ptr->num, order, ptr->norm[0], ptr->enc_type);
895
 
896
    for (i = 0; i < ptr->num; i++)
897
        ptr->pieces[1][i] = data[i + 1] >> 4;
898
    order = data[0] >> 4;
899
    set_norm_piece(ptr, ptr->norm[1], ptr->pieces[1]);
900
    tb_size[1] = calc_factors_piece(ptr->factor[1], ptr->num, order, ptr->norm[1], ptr->enc_type);
901
}
902
 
903
static void setup_pieces_piece_dtz(struct DTZEntry_piece *ptr, unsigned char *data, uint64_t *tb_size)
904
{
905
    int i;
906
    int order;
907
 
908
    for (i = 0; i < ptr->num; i++)
909
        ptr->pieces[i] = data[i + 1] & 0x0f;
910
    order = data[0] & 0x0f;
911
    set_norm_piece((struct TBEntry_piece *)ptr, ptr->norm, ptr->pieces);
912
    tb_size[0] = calc_factors_piece(ptr->factor, ptr->num, order, ptr->norm, ptr->enc_type);
913
}
914
 
915
static void setup_pieces_pawn(struct TBEntry_pawn *ptr, unsigned char *data, uint64_t *tb_size, int f)
916
{
917
    int i, j;
918
    int order, order2;
919
 
920
    j = 1 + (ptr->pawns[1] > 0);
921
    order = data[0] & 0x0f;
922
    order2 = ptr->pawns[1] ? (data[1] & 0x0f) : 0x0f;
923
    for (i = 0; i < ptr->num; i++)
924
        ptr->file[f].pieces[0][i] = data[i + j] & 0x0f;
925
    set_norm_pawn(ptr, ptr->file[f].norm[0], ptr->file[f].pieces[0]);
926
    tb_size[0] = calc_factors_pawn(ptr->file[f].factor[0], ptr->num, order, order2, ptr->file[f].norm[0], f);
927
 
928
    order = data[0] >> 4;
929
    order2 = ptr->pawns[1] ? (data[1] >> 4) : 0x0f;
930
    for (i = 0; i < ptr->num; i++)
931
        ptr->file[f].pieces[1][i] = data[i + j] >> 4;
932
    set_norm_pawn(ptr, ptr->file[f].norm[1], ptr->file[f].pieces[1]);
933
    tb_size[1] = calc_factors_pawn(ptr->file[f].factor[1], ptr->num, order, order2, ptr->file[f].norm[1], f);
934
}
935
 
936
static void setup_pieces_pawn_dtz(struct DTZEntry_pawn *ptr, unsigned char *data, uint64_t *tb_size, int f)
937
{
938
    int i, j;
939
    int order, order2;
940
 
941
    j = 1 + (ptr->pawns[1] > 0);
942
    order = data[0] & 0x0f;
943
    order2 = ptr->pawns[1] ? (data[1] & 0x0f) : 0x0f;
944
    for (i = 0; i < ptr->num; i++)
945
        ptr->file[f].pieces[i] = data[i + j] & 0x0f;
946
    set_norm_pawn((struct TBEntry_pawn *)ptr, ptr->file[f].norm, ptr->file[f].pieces);
947
    tb_size[0] = calc_factors_pawn(ptr->file[f].factor, ptr->num, order, order2, ptr->file[f].norm, f);
948
}
949
 
950
static void calc_symlen(struct PairsData *d, int s, char *tmp)
951
{
952
    int s1, s2;
953
 
954
    int w = *(int *)(d->sympat + 3 * s);
955
    s2 = (w >> 12) & 0x0fff;
956
    if (s2 == 0x0fff)
957
        d->symlen[s] = 0;
958
    else {
959
        s1 = w & 0x0fff;
960
        if (!tmp[s1]) calc_symlen(d, s1, tmp);
961
        if (!tmp[s2]) calc_symlen(d, s2, tmp);
962
        d->symlen[s] = d->symlen[s1] + d->symlen[s2] + 1;
963
    }
964
    tmp[s] = 1;
965
}
966
 
967
static struct PairsData *setup_pairs(unsigned char *data, uint64_t tb_size, uint64_t *size, unsigned char **next, ubyte *flags, int wdl)
968
{
969
    struct PairsData *d;
970
    int i;
971
 
972
    *flags = data[0];
973
    if (data[0] & 0x80) {
974
        d = (struct PairsData *)malloc(sizeof(struct PairsData));
975
        d->idxbits = 0;
976
        if (wdl)
977
            d->min_len = data[1];
978
        else
979
            d->min_len = 0;
980
        *next = data + 2;
981
        size[0] = size[1] = size[2] = 0;
982
        return d;
983
    }
984
 
985
    int blocksize = data[1];
986
    int idxbits = data[2];
987
    int real_num_blocks = *(uint32_t *)(&data[4]);
988
    int num_blocks = real_num_blocks + *(ubyte *)(&data[3]);
989
    int max_len = data[8];
990
    int min_len = data[9];
991
    int h = max_len - min_len + 1;
992
    int num_syms = *(ushort *)(&data[10 + 2 * h]);
993
    d = (struct PairsData *)malloc(sizeof(struct PairsData) + (h - 1) * sizeof(base_t) + num_syms);
994
    d->blocksize = blocksize;
995
    d->idxbits = idxbits;
996
    d->offset = (ushort *)(&data[10]);
997
    d->symlen = ((ubyte *)d) + sizeof(struct PairsData) + (h - 1) * sizeof(base_t);
998
    d->sympat = &data[12 + 2 * h];
999
    d->min_len = min_len;
1000
    *next = &data[12 + 2 * h + 3 * num_syms + (num_syms & 1)];
1001
 
1002
    int num_indices = (int)((tb_size + (1ULL << idxbits) - 1) >> idxbits); // Pierre-Marie Baty -- added type cast
1003
    size[0] = 6ULL * num_indices;
1004
    size[1] = 2ULL * num_blocks;
1005
    size[2] = (1ULL << blocksize) * real_num_blocks;
1006
 
1007
    // char tmp[num_syms];
1008
    char tmp[4096];
1009
    for (i = 0; i < num_syms; i++)
1010
        tmp[i] = 0;
1011
    for (i = 0; i < num_syms; i++)
1012
        if (!tmp[i])
1013
            calc_symlen(d, i, tmp);
1014
 
1015
    d->base[h - 1] = 0;
1016
    for (i = h - 2; i >= 0; i--)
1017
        d->base[i] = (d->base[i + 1] + d->offset[i] - d->offset[i + 1]) / 2;
1018
    for (i = 0; i < h; i++)
1019
        d->base[i] <<= 64 - (min_len + i);
1020
 
1021
    d->offset -= d->min_len;
1022
 
1023
    return d;
1024
}
1025
 
1026
static int init_table_wdl(struct TBEntry *entry, const char *str)
1027
{
1028
    ubyte *next;
1029
    int f, s;
1030
    uint64_t tb_size[8];
1031
    uint64_t size[8 * 3];
1032
    ubyte flags;
1033
 
1034
    // first mmap the table into memory
1035
 
1036
    entry->data = map_file(str, WDLSUFFIX, &entry->mapping);
1037
    if (!entry->data) {
1038
        std::cout << "Could not find " << str << WDLSUFFIX << std::endl;
1039
        return 0;
1040
    }
1041
 
1042
    ubyte *data = (ubyte *)entry->data;
1043
    if (((uint32_t *)data)[0] != WDL_MAGIC) {
1044
        std::cout << "Corrupted table" << std::endl;
1045
        unmap_file(entry->data, entry->mapping);
1046
        entry->data = 0;
1047
        return 0;
1048
    }
1049
 
1050
    int split = data[4] & 0x01;
1051
    int files = data[4] & 0x02 ? 4 : 1;
1052
 
1053
    data += 5;
1054
 
1055
    if (!entry->has_pawns) {
1056
        struct TBEntry_piece *ptr = (struct TBEntry_piece *)entry;
1057
        setup_pieces_piece(ptr, data, &tb_size[0]);
1058
        data += ptr->num + 1;
1059
        data += ((uintptr_t)data) & 0x01;
1060
 
1061
        ptr->precomp[0] = setup_pairs(data, tb_size[0], &size[0], &next, &flags, 1);
1062
        data = next;
1063
        if (split) {
1064
            ptr->precomp[1] = setup_pairs(data, tb_size[1], &size[3], &next, &flags, 1);
1065
            data = next;
1066
        } else
1067
            ptr->precomp[1] = NULL;
1068
 
1069
        ptr->precomp[0]->indextable = (char *)data;
1070
        data += size[0];
1071
        if (split) {
1072
            ptr->precomp[1]->indextable = (char *)data;
1073
            data += size[3];
1074
        }
1075
 
1076
        ptr->precomp[0]->sizetable = (ushort *)data;
1077
        data += size[1];
1078
        if (split) {
1079
            ptr->precomp[1]->sizetable = (ushort *)data;
1080
            data += size[4];
1081
        }
1082
 
1083
        data = (ubyte *)((((uintptr_t)data) + 0x3f) & ~0x3f);
1084
        ptr->precomp[0]->data = data;
1085
        data += size[2];
1086
        if (split) {
1087
            data = (ubyte *)((((uintptr_t)data) + 0x3f) & ~0x3f);
1088
            ptr->precomp[1]->data = data;
1089
        }
1090
    } else {
1091
        struct TBEntry_pawn *ptr = (struct TBEntry_pawn *)entry;
1092
        s = 1 + (ptr->pawns[1] > 0);
1093
        for (f = 0; f < 4; f++) {
1094
            setup_pieces_pawn((struct TBEntry_pawn *)ptr, data, &tb_size[2 * f], f);
1095
            data += ptr->num + s;
1096
        }
1097
        data += ((uintptr_t)data) & 0x01;
1098
 
1099
        for (f = 0; f < files; f++) {
1100
            ptr->file[f].precomp[0] = setup_pairs(data, tb_size[2 * f], &size[6 * f], &next, &flags, 1);
1101
            data = next;
1102
            if (split) {
1103
                ptr->file[f].precomp[1] = setup_pairs(data, tb_size[2 * f + 1], &size[6 * f + 3], &next, &flags, 1);
1104
                data = next;
1105
            } else
1106
                ptr->file[f].precomp[1] = NULL;
1107
        }
1108
 
1109
        for (f = 0; f < files; f++) {
1110
            ptr->file[f].precomp[0]->indextable = (char *)data;
1111
            data += size[6 * f];
1112
            if (split) {
1113
                ptr->file[f].precomp[1]->indextable = (char *)data;
1114
                data += size[6 * f + 3];
1115
            }
1116
        }
1117
 
1118
        for (f = 0; f < files; f++) {
1119
            ptr->file[f].precomp[0]->sizetable = (ushort *)data;
1120
            data += size[6 * f + 1];
1121
            if (split) {
1122
                ptr->file[f].precomp[1]->sizetable = (ushort *)data;
1123
                data += size[6 * f + 4];
1124
            }
1125
        }
1126
 
1127
        for (f = 0; f < files; f++) {
1128
            data = (ubyte *)((((uintptr_t)data) + 0x3f) & ~0x3f);
1129
            ptr->file[f].precomp[0]->data = data;
1130
            data += size[6 * f + 2];
1131
            if (split) {
1132
                data = (ubyte *)((((uintptr_t)data) + 0x3f) & ~0x3f);
1133
                ptr->file[f].precomp[1]->data = data;
1134
                data += size[6 * f + 5];
1135
            }
1136
        }
1137
    }
1138
 
1139
    return 1;
1140
}
1141
 
1142
static int init_table_dtz(struct TBEntry *entry)
1143
{
1144
    ubyte *data = (ubyte *)entry->data;
1145
    ubyte *next;
1146
    int f, s;
1147
    uint64_t tb_size[4];
1148
    uint64_t size[4 * 3];
1149
 
1150
    if (!data)
1151
        return 0;
1152
 
1153
    if (((uint32_t *)data)[0] != DTZ_MAGIC) {
1154
        std::cout << "Corrupted table" << std::endl;
1155
        return 0;
1156
    }
1157
 
1158
    int files = data[4] & 0x02 ? 4 : 1;
1159
 
1160
    data += 5;
1161
 
1162
    if (!entry->has_pawns) {
1163
        struct DTZEntry_piece *ptr = (struct DTZEntry_piece *)entry;
1164
        setup_pieces_piece_dtz(ptr, data, &tb_size[0]);
1165
        data += ptr->num + 1;
1166
        data += ((uintptr_t)data) & 0x01;
1167
 
1168
        ptr->precomp = setup_pairs(data, tb_size[0], &size[0], &next, &(ptr->flags), 0);
1169
        data = next;
1170
 
1171
        ptr->map = data;
1172
        if (ptr->flags & 2) {
1173
            int i;
1174
            for (i = 0; i < 4; i++) {
1175
                ptr->map_idx[i] = (data + 1 - ptr->map);
1176
                data += 1 + data[0];
1177
            }
1178
            data += ((uintptr_t)data) & 0x01;
1179
        }
1180
 
1181
        ptr->precomp->indextable = (char *)data;
1182
        data += size[0];
1183
 
1184
        ptr->precomp->sizetable = (ushort *)data;
1185
        data += size[1];
1186
 
1187
        data = (ubyte *)((((uintptr_t)data) + 0x3f) & ~0x3f);
1188
        ptr->precomp->data = data;
1189
        data += size[2];
1190
    } else {
1191
        struct DTZEntry_pawn *ptr = (struct DTZEntry_pawn *)entry;
1192
        s = 1 + (ptr->pawns[1] > 0);
1193
        for (f = 0; f < 4; f++) {
1194
            setup_pieces_pawn_dtz(ptr, data, &tb_size[f], f);
1195
            data += ptr->num + s;
1196
        }
1197
        data += ((uintptr_t)data) & 0x01;
1198
 
1199
        for (f = 0; f < files; f++) {
1200
            ptr->file[f].precomp = setup_pairs(data, tb_size[f], &size[3 * f], &next, &(ptr->flags[f]), 0);
1201
            data = next;
1202
        }
1203
 
1204
        ptr->map = data;
1205
        for (f = 0; f < files; f++) {
1206
            if (ptr->flags[f] & 2) {
1207
                int i;
1208
                for (i = 0; i < 4; i++) {
1209
                    ptr->map_idx[f][i] = (data + 1 - ptr->map);
1210
                    data += 1 + data[0];
1211
                }
1212
            }
1213
        }
1214
        data += ((uintptr_t)data) & 0x01;
1215
 
1216
        for (f = 0; f < files; f++) {
1217
            ptr->file[f].precomp->indextable = (char *)data;
1218
            data += size[3 * f];
1219
        }
1220
 
1221
        for (f = 0; f < files; f++) {
1222
            ptr->file[f].precomp->sizetable = (ushort *)data;
1223
            data += size[3 * f + 1];
1224
        }
1225
 
1226
        for (f = 0; f < files; f++) {
1227
            data = (ubyte *)((((uintptr_t)data) + 0x3f) & ~0x3f);
1228
            ptr->file[f].precomp->data = data;
1229
            data += size[3 * f + 2];
1230
        }
1231
    }
1232
 
1233
    return 1;
1234
}
1235
 
1236
static inline uint64_t bswap64(uint64_t val) {
1237
#ifndef _MSC_VER
1238
    return __builtin_bswap64(val);
1239
#else
1240
    return _byteswap_uint64(val);
1241
#endif
1242
}
1243
 
1244
static inline uint32_t bswap32(uint32_t val) {
1245
#ifndef _MSC_VER
1246
    return __builtin_bswap32(val);
1247
#else
1248
    return _byteswap_ulong(val);
1249
#endif
1250
}
1251
 
1252
static ubyte decompress_pairs(struct PairsData *d, uint64_t idx)
1253
{
1254
    if (!d->idxbits)
1255
        return d->min_len;
1256
 
1257
    uint32_t mainidx = (uint32_t)(idx >> d->idxbits); // Pierre-Marie Baty -- added type cast
1258
    int litidx = (idx & ((1LL << d->idxbits) - 1)) - (1LL << (d->idxbits - 1)); // Pierre-Marie Baty -- added constant casts
1259
    uint32_t block = *(uint32_t *)(d->indextable + 6 * mainidx);
1260
    litidx += *(ushort *)(d->indextable + 6 * mainidx + 4);
1261
    if (litidx < 0) {
1262
        do {
1263
            litidx += d->sizetable[--block] + 1;
1264
        } while (litidx < 0);
1265
    } else {
1266
        while (litidx > d->sizetable[block])
1267
            litidx -= d->sizetable[block++] + 1;
1268
    }
1269
 
1270
    uint32_t *ptr = (uint32_t *)(d->data + (block << d->blocksize));
1271
 
1272
    int m = d->min_len;
1273
    ushort *offset = d->offset;
1274
    base_t *base = d->base - m;
1275
    ubyte *symlen = d->symlen;
1276
    int sym, bitcnt;
1277
 
1278
    uint64_t code = bswap64(*((uint64_t *)ptr));
1279
    ptr += 2;
1280
    bitcnt = 0; // number of "empty bits" in code
1281
    for (;;) {
1282
        int l = m;
1283
        while (code < base[l]) l++;
1284
        sym = (int)(offset[l] + ((code - base[l]) >> (64 - l))); // Pierre-Marie Baty -- added type cast
1285
        if (litidx < (int)symlen[sym] + 1) break;
1286
        litidx -= (int)symlen[sym] + 1;
1287
        code <<= l;
1288
        bitcnt += l;
1289
        if (bitcnt >= 32) {
1290
            bitcnt -= 32;
1291
            code |= ((uint64_t)(bswap32(*ptr++))) << bitcnt;
1292
        }
1293
    }
1294
 
1295
    ubyte *sympat = d->sympat;
1296
    while (symlen[sym] != 0) {
1297
        int w = *(int *)(sympat + 3 * sym);
1298
        int s1 = w & 0x0fff;
1299
        if (litidx < (int)symlen[s1] + 1)
1300
            sym = s1;
1301
        else {
1302
            litidx -= (int)symlen[s1] + 1;
1303
            sym = (w >> 12) & 0x0fff;
1304
        }
1305
    }
1306
 
1307
    return *(sympat + 3 * sym);
1308
}
1309
 
1310
TBEntry* load_dtz_table(const char* str, uint64_t key1, uint64_t key2)
1311
{
1312
    int i;
1313
    struct TBEntry *ptr, *ptr3;
1314
    struct TBHashEntry *ptr2;
1315
 
1316
    // find corresponding WDL entry
1317
    ptr2 = WDL_hash[key1 >> (64 - TBHASHBITS)];
1318
    for (i = 0; i < HSHMAX; i++)
1319
        if (ptr2[i].key == key1) break;
1320
    if (i == HSHMAX) return NULL;
1321
    ptr = ptr2[i].ptr;
1322
 
1323
    ptr3 = (struct TBEntry *)malloc(ptr->has_pawns
1324
                                    ? sizeof(struct DTZEntry_pawn)
1325
                                    : sizeof(struct DTZEntry_piece));
1326
 
1327
    ptr3->data = map_file(str, DTZSUFFIX, &ptr3->mapping);
1328
    ptr3->key = ptr->key;
1329
    ptr3->num = ptr->num;
1330
    ptr3->symmetric = ptr->symmetric;
1331
    ptr3->has_pawns = ptr->has_pawns;
1332
    if (ptr3->has_pawns) {
1333
        struct DTZEntry_pawn *entry = (struct DTZEntry_pawn *)ptr3;
1334
        entry->pawns[0] = ((struct TBEntry_pawn *)ptr)->pawns[0];
1335
        entry->pawns[1] = ((struct TBEntry_pawn *)ptr)->pawns[1];
1336
    } else {
1337
        struct DTZEntry_piece *entry = (struct DTZEntry_piece *)ptr3;
1338
        entry->enc_type = ((struct TBEntry_piece *)ptr)->enc_type;
1339
    }
1340
    if (!init_table_dtz(ptr3)) {
1341
        free(ptr3);
1342
        return NULL;
1343
    }
1344
    return ptr3;
1345
}
1346
 
1347
static void free_wdl_entry(struct TBEntry *entry)
1348
{
1349
    unmap_file(entry->data, entry->mapping);
1350
    entry->data = NULL;
1351
    if (!entry->has_pawns) {
1352
        struct TBEntry_piece *ptr = (struct TBEntry_piece *)entry;
1353
        free(ptr->precomp[0]); ptr->precomp[0] = NULL;
1354
        free(ptr->precomp[1]); ptr->precomp[1] = NULL;
1355
    } else {
1356
        struct TBEntry_pawn *ptr = (struct TBEntry_pawn *)entry;
1357
        int f;
1358
        for (f = 0; f < 4; f++) {
1359
            free(ptr->file[f].precomp[0]); ptr->file[f].precomp[0] = NULL;
1360
            free(ptr->file[f].precomp[1]); ptr->file[f].precomp[1] = NULL;
1361
        }
1362
    }
1363
}
1364
 
1365
static void free_dtz_entry(struct TBEntry *entry)
1366
{
1367
    unmap_file(entry->data, entry->mapping);
1368
    entry->data = NULL;
1369
    if (!entry->has_pawns) {
1370
        struct DTZEntry_piece *ptr = (struct DTZEntry_piece *)entry;
1371
        free(ptr->precomp); ptr->precomp = NULL;
1372
    } else {
1373
        struct DTZEntry_pawn *ptr = (struct DTZEntry_pawn *)entry;
1374
        int f;
1375
        for (f = 0; f < 4; f++) {
1376
            free(ptr->file[f].precomp); ptr->file[f].precomp = NULL;
1377
        }
1378
    }
1379
    free(entry);
1380
}
1381
 
1382
static int wdl_to_map[5] = { 1, 3, 0, 2, 0 };
1383
static ubyte pa_flags[5] = { 8, 0, 0, 0, 4 };