Subversion Repositories Games.Chess Giants

Rev

Details | Last modification | View Log | RSS feed

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