Subversion Repositories Games.Chess Giants

Rev

Rev 33 | Rev 154 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 33 Rev 108
Line 1... Line 1...
1
#include <stddef.h>
1
#include <stddef.h>
-
 
2
#include <math.h>
2
#include "chess.h"
3
#include "chess.h"
3
#include "data.h"
4
#include "data.h"
4
#if defined(UNIX)
5
#if defined(UNIX)
5
#  include <unistd.h>
6
#  include <unistd.h>
6
#  include <sys/types.h>
7
#  include <sys/types.h>
7
#  include <sys/stat.h>
-
 
8
#else
8
#else
9
#  include <fcntl.h>    /* needed for definition of "_O_BINARY" */
9
#  include <fcntl.h> /* needed for definition of "_O_BINARY" */
10
#endif
10
#endif
11
/*
11
/*
12
 *******************************************************************************
12
 *******************************************************************************
13
 *                                                                             *
13
 *                                                                             *
14
 *   Initialize() performs routine initialization before anything else is      *
14
 *   Initialize() performs routine initialization before anything else is      *
Line 16... Line 16...
16
 *   data structures that are needed before the engine can do anything at all. *
16
 *   data structures that are needed before the engine can do anything at all. *
17
 *                                                                             *
17
 *                                                                             *
18
 *******************************************************************************
18
 *******************************************************************************
19
 */
19
 */
20
void Initialize() {
20
void Initialize() {
21
  int /*i, */major, id; // Pierre-Marie Baty -- unused variable
-
 
22
  TREE *tree;
21
  TREE *tree;
23
  int j;
22
  int /*i, */j, v, major, id/*, node*/; // Pierre-Marie Baty -- unreferenced variables
24
 
23
 
25
  tree = block[0];
24
  tree = block[0];
26
  for (j = 1; j < MAX_BLOCKS + 1; j++)
25
  for (j = 1; j <= MAX_BLOCKS; j++)
27
    block[j] = NULL;
26
    block[j] = NULL;
28
  InitializeMasks();
27
  InitializeMasks();
29
  InitializeMagic();
28
  InitializeMagic();
30
  InitializeSMP();
29
  InitializeSMP();
31
  InitializeAttackBoards();
30
  InitializeAttackBoards();
32
  InitializePawnMasks();
31
  InitializePawnMasks();
33
  InitializeChessBoard(tree);
32
  InitializeChessBoard(tree);
34
  InitializeKillers();
33
  InitializeKillers();
35
#if !defined(UNIX)
34
#if !defined(UNIX)
36
  _fmode = _O_BINARY;   /* set file mode binary to avoid text translation */
35
  _fmode = _O_BINARY; /* set file mode binary to avoid text translation */
37
#endif
36
#endif
38
#if defined(EPD)
37
#if defined(EPD)
39
  EGInit();
38
  EGInit();
40
#endif
39
#endif
41
  tree->last[0] = tree->move_list;
40
  tree->last[0] = tree->move_list;
Line 43... Line 42...
43
  sprintf(log_filename, "%s/book.bin", book_path);
42
  sprintf(log_filename, "%s/book.bin", book_path);
44
  book_file = fopen(log_filename, "rb+");
43
  book_file = fopen(log_filename, "rb+");
45
  if (!book_file) {
44
  if (!book_file) {
46
    book_file = fopen(log_filename, "rb");
45
    book_file = fopen(log_filename, "rb");
47
    if (!book_file) {
46
    if (!book_file) {
48
      Print(128, "unable to open book file [%s/book.bin].\n", book_path);
47
      Print(2048, "unable to open book file [%s/book.bin].\n", book_path);
49
      Print(128, "book is disabled\n");
48
      Print(32, "book is disabled\n");
50
    } else {
49
    } else {
51
      Print(128, "unable to open book file [%s/book.bin] for \"write\".\n",
50
      Print(2048, "unable to open book file [%s/book.bin] for \"write\".\n",
52
          book_path);
51
          book_path);
53
      Print(128, "learning is disabled\n");
52
      Print(32, "learning is disabled\n");
54
    }
53
    }
55
  }
54
  }
56
  sprintf(log_filename, "%s/books.bin", book_path);
55
  sprintf(log_filename, "%s/books.bin", book_path);
57
  normal_bs_file = fopen(log_filename, "rb");
56
  normal_bs_file = fopen(log_filename, "rb");
58
  books_file = normal_bs_file;
57
  books_file = normal_bs_file;
59
  if (!normal_bs_file)
58
  if (!normal_bs_file)
60
    Print(128, "unable to open book file [%s/books.bin].\n", book_path);
59
    Print(32, "unable to open book file [%s/books.bin].\n", book_path);
61
  sprintf(log_filename, "%s/bookc.bin", book_path);
60
  sprintf(log_filename, "%s/bookc.bin", book_path);
62
  computer_bs_file = fopen(log_filename, "rb");
61
  computer_bs_file = fopen(log_filename, "rb");
63
  if (computer_bs_file)
62
  if (computer_bs_file)
64
    Print(128, "found computer opening book file [%s/bookc.bin].\n",
63
    Print(32, "found computer opening book file [%s/bookc.bin].\n",
65
        book_path);
64
        book_path);
66
  if (book_file) {
65
  if (book_file) {
67
    int maj_min;
66
    int maj_min;
68
    fseek(book_file, 0-sizeof(int), SEEK_END); // Pierre-Marie Baty -- fixed signedness warning
67
    fseek(book_file, 0-sizeof(int), SEEK_END); // Pierre-Marie Baty -- signedness warning fix
69
    fread(&maj_min, 4, 1, book_file);
68
    v = fread(&maj_min, 4, 1, book_file);
-
 
69
    if (v <= 0)
-
 
70
      perror("Initialize() fread error: ");
70
    major = BookIn32((unsigned char *) &maj_min);
71
    major = BookIn32((unsigned char *) &maj_min);
71
    major = major >> 16;
72
    major = major >> 16;
72
    if (major < 23) {
73
    if (major < 23) {
73
      Print(4095, "\nERROR!  book.bin not made by version 23.0 or later\n");
74
      Print(4095, "\nERROR!  book.bin not made by version 23.0 or later\n");
74
      fclose(book_file);
75
      fclose(book_file);
Line 84... Line 85...
84
  history_file = fopen(history_filename, "w+");
85
  history_file = fopen(history_filename, "w+");
85
  if (!history_file) {
86
  if (!history_file) {
86
    printf("ERROR, unable to open game history file, exiting\n");
87
    printf("ERROR, unable to open game history file, exiting\n");
87
    CraftyExit(1);
88
    CraftyExit(1);
88
  }
89
  }
89
  AlignedMalloc((void **) &trans_ref, 64,
90
  AlignedMalloc((void *) ((void *) &hash_table), 64,
90
      sizeof(HASH_ENTRY) * hash_table_size);
91
      sizeof(HASH_ENTRY) * hash_table_size);
91
  AlignedMalloc((void **) &hash_path, 64,
92
  AlignedMalloc((void *) ((void *) &hash_path), 64,
92
      sizeof(HPATH_ENTRY) * hash_path_size);
93
      sizeof(HPATH_ENTRY) * hash_path_size);
93
  AlignedMalloc((void **) &pawn_hash_table, 32,
94
  AlignedMalloc((void *) ((void *) &pawn_hash_table), 64,
94
      sizeof(PAWN_HASH_ENTRY) * pawn_hash_table_size);
95
      sizeof(PAWN_HASH_ENTRY) * pawn_hash_table_size);
-
 
96
  AlignedMalloc((void *) ((void *) &eval_hash_table), 64,
-
 
97
      sizeof(uint64_t) * eval_hash_table_size);
95
  if (!trans_ref) {
98
  if (!hash_table) {
96
    Print(128,
99
    Print(2048,
97
        "AlignedMalloc() failed, not enough memory (primary trans/ref table).\n");
100
        "AlignedMalloc() failed, not enough memory (primary trans/ref table).\n");
98
    hash_table_size = 0;
101
    hash_table_size = 0;
99
    trans_ref = 0;
102
    hash_table = 0;
100
  }
103
  }
101
  if (!pawn_hash_table) {
104
  if (!pawn_hash_table) {
102
    Print(128,
105
    Print(2048,
103
        "AlignedMalloc() failed, not enough memory (pawn hash table).\n");
106
        "AlignedMalloc() failed, not enough memory (pawn hash table).\n");
104
    pawn_hash_table_size = 0;
107
    pawn_hash_table_size = 0;
105
    pawn_hash_table = 0;
108
    pawn_hash_table = 0;
106
  }
109
  }
107
/*
110
/*
Line 117... Line 120...
117
 *  the correct processor and use local node memory for     *
120
 *  the correct processor and use local node memory for     *
118
 *  optimal performance.                                    *
121
 *  optimal performance.                                    *
119
 *                                                          *
122
 *                                                          *
120
 *  If we are using CPU affinity, we need to set this up    *
123
 *  If we are using CPU affinity, we need to set this up    *
121
 *  for thread 0 BEFORE we initialize the split blocks so   *
124
 *  for thread 0 BEFORE we initialize the split blocks so   *
122
 *  that they will fault in on the correct node.            *
125
 *  that they will page fault in on the correct NUMA node.  *
123
 *                                                          *
126
 *                                                          *
124
 ************************************************************
127
 ************************************************************
125
 */
128
 */
126
#if defined(AFFINITY)
129
#if (CPUS > 1)
127
  cpu_set_t cpuset;
-
 
128
  pthread_t current_thread = pthread_self();
130
  ThreadAffinity(smp_affinity);
129
 
-
 
130
  CPU_ZERO(&cpuset);
-
 
131
  CPU_SET(0, &cpuset);
-
 
132
  pthread_setaffinity_np(current_thread, sizeof(cpu_set_t), &cpuset);
-
 
133
#endif
-
 
134
#if !defined(UNIX)
131
#  if !defined(UNIX)
135
  ThreadMalloc((int) 0);
132
  ThreadMalloc((int) 0);
136
#else
133
#  else
137
  for (i = 0; i < CPUS; i++) {
134
  for (i = 0; i < CPUS; i++) {
138
    for (j = 0; j < MAX_BLOCKS_PER_CPU; j++) {
135
    for (j = 0; j < 64; j++) {
139
      AlignedMalloc((void **) &block[i * MAX_BLOCKS_PER_CPU + j + 1], 2048,
136
      AlignedMalloc((void **) &block[i * 64 + j + 1], 2048,
140
          (size_t) sizeof(TREE));
137
          (size_t) sizeof(TREE));
141
    }
138
    }
142
  }
139
  }
143
  for (i = 1; i < MAX_BLOCKS_PER_CPU; i++) {
140
  for (i = 1; i < 64; i++) {
144
    memset((void *) block[i], 0, sizeof(TREE));
141
    memset((void *) block[i], 0, sizeof(TREE));
145
    LockInit(block[i]->lock);
142
    LockInit(block[i]->lock);
146
  }
143
  }
-
 
144
  for (node = 1; node < CPUS; node++) {
-
 
145
    ThreadAffinity(node);
-
 
146
    for (i = 0; i < 64; i++) {
-
 
147
      memset((void *) block[node * 64 + i], 0, sizeof(TREE));
-
 
148
      LockInit(block[node * 64 + i]->lock);
-
 
149
    }
-
 
150
  }
-
 
151
  ThreadAffinity(smp_affinity);
-
 
152
#  endif
147
#endif
153
#endif
-
 
154
  thread[0].blocks = 0xffffffffffffffffull;
148
  initialized_threads++;
155
  initialized_threads++;
149
  InitializeHashTables();
156
  InitializeHashTables(1);
150
  InitializeKingSafety();
157
  InitializeKingSafety();
-
 
158
  InitializeReductions();
151
}
159
}
152
 
160
 
153
/*
161
/*
154
 *******************************************************************************
162
 *******************************************************************************
155
 *                                                                             *
163
 *                                                                             *
Line 157... Line 165...
157
 *   deal with what squares a piece attacks.                                   *
165
 *   deal with what squares a piece attacks.                                   *
158
 *                                                                             *
166
 *                                                                             *
159
 *******************************************************************************
167
 *******************************************************************************
160
 */
168
 */
161
void InitializeAttackBoards(void) {
169
void InitializeAttackBoards(void) {
162
  int i, j, frank, ffile, trank, tfile, nmobility;
170
  int i, j, d, s, t, frank, ffile, trank, tfile;
163
  int sq, lastsq;
171
  int sq, lastsq;
164
  static const int knightsq[8] = { -17, -15, -10, -6, 6, 10, 15, 17 };
172
  static const int knightsq[8] = { -17, -15, -10, -6, 6, 10, 15, 17 };
165
  static const int bishopsq[4] = { -9, -7, 7, 9 };
173
  static const int bishopsq[4] = { -9, -7, 7, 9 };
166
  static const int rooksq[4] = { -8, -1, 1, 8 };
174
  static const int rooksq[4] = { -8, -1, 1, 8 };
167
  uint64_t sqs;
175
  uint64_t sqs;
Line 204... Line 212...
204
      tfile = File(sq);
212
      tfile = File(sq);
205
      if (Abs(frank - trank) > 2 || Abs(ffile - tfile) > 2)
213
      if (Abs(frank - trank) > 2 || Abs(ffile - tfile) > 2)
206
        continue;
214
        continue;
207
      knight_attacks[i] = knight_attacks[i] | (uint64_t) 1 << sq;
215
      knight_attacks[i] = knight_attacks[i] | (uint64_t) 1 << sq;
208
    }
216
    }
209
    nmobility = -lower_n;
-
 
210
    for (j = 0; j < 4; j++)
-
 
211
      nmobility +=
-
 
212
          PopCnt(knight_attacks[i] & mobility_mask_n[j]) *
-
 
213
          mobility_score_n[j];
-
 
214
    knight_mobility_table[i] = nmobility;
-
 
215
  }
217
  }
216
/*
218
/*
217
 initialize bishop/queen attack boards and masks
219
 initialize bishop/queen attack boards and masks
218
 */
220
 */
219
  for (i = 0; i < 64; i++) {
221
  for (i = 0; i < 64; i++) {
Line 291... Line 293...
291
      if (Distance(i, j) == 1)
293
      if (Distance(i, j) == 1)
292
        king_attacks[i] = king_attacks[i] | SetMask(j);
294
        king_attacks[i] = king_attacks[i] | SetMask(j);
293
    }
295
    }
294
  }
296
  }
295
/*
297
/*
296
 direction[sq1][sq2] gives the "move direction" to move from
298
 directions[sq1][sq2] gives the "move direction" to move from
297
 sq1 to sq2.  intervening[sq1][sq2] gives a bit vector that indicates
299
 sq1 to sq2.  intervening[sq1][sq2] gives a bit vector that indicates
298
 which squares must be unoccupied in order for <sq1> to attack <sq2>,
300
 which squares must be unoccupied in order for <sq1> to attack <sq2>,
299
 assuming a sliding piece is involved.  to use this, you simply have
301
 assuming a sliding piece is involved.  To use this, you simply have
300
 to Or(intervening[sq1][sq2],occupied_squares) and if the result is
302
 to Or(intervening[sq1][sq2],occupied_squares) and if the result is
301
 "0" then a sliding piece on sq1 would attack sq2 and vice-versa.
303
 "0" then a sliding piece on sq1 would attack sq2 and vice-versa.
302
 */
304
 */
303
  for (i = 0; i < 64; i++) {
305
  for (i = 0; i < 64; i++) {
304
    for (j = 0; j < 64; j++)
306
    for (j = 0; j < 64; j++)
Line 356... Line 358...
356
    while (sqs) {
358
    while (sqs) {
357
      j = LSB(sqs);
359
      j = LSB(sqs);
358
      directions[i][j] = -9;
360
      directions[i][j] = -9;
359
      intervening[i][j] = minus9dir[i] ^ minus9dir[j + 9];
361
      intervening[i][j] = minus9dir[i] ^ minus9dir[j + 9];
360
      sqs &= sqs - 1;
362
      sqs &= sqs - 1;
-
 
363
    }
-
 
364
  }
-
 
365
/*
-
 
366
  distance_ring[square][distance] has a ring of 1's around "square" with a
-
 
367
  distance of "distance".  IE for e4, we have a ring of adjacent squares
-
 
368
  [e4][1], the next ring (2 squares away) for [e4][2], etc.  In this code,
-
 
369
  s = square being set up, d = distance from square to "ring" and t = target
-
 
370
  square that is on the ring if distance is correct.
-
 
371
 */
-
 
372
  for (s = 0; s < 64; s++) {
-
 
373
    distance_ring[s][0] = SetMask(s);
-
 
374
    for (d = 1; d < 8; d++) {
-
 
375
      distance_ring[s][d] = 0;
-
 
376
      for (t = 0; t < 64; t++)
-
 
377
        if (Distance(s, t) == d)
-
 
378
          distance_ring[s][d] |= SetMask(t);
361
    }
379
    }
362
  }
380
  }
363
}
381
}
364
 
382
 
365
/*
383
/*
Line 372... Line 390...
372
 *   here before the game actually starts.                                     *
390
 *   here before the game actually starts.                                     *
373
 *                                                                             *
391
 *                                                                             *
374
 *******************************************************************************
392
 *******************************************************************************
375
 */
393
 */
376
void InitializeMagic(void) {
394
void InitializeMagic(void) {
377
  int i, j;
395
  int i, j, m;
378
  int initmagicmoves_bitpos64_database[64] = {
396
  int initmagicmoves_bitpos64_database[64] = {
379
    63, 0, 58, 1, 59, 47, 53, 2,
397
    63, 0, 58, 1, 59, 47, 53, 2,
380
    60, 39, 48, 27, 54, 33, 42, 3,
398
    60, 39, 48, 27, 54, 33, 42, 3,
381
    61, 51, 37, 40, 49, 18, 28, 20,
399
    61, 51, 37, 40, 49, 18, 28, 20,
382
    55, 30, 34, 11, 43, 14, 22, 4,
400
    55, 30, 34, 11, 43, 14, 22, 4,
Line 392... Line 410...
392
    int squares[64];
410
    int squares[64];
393
    int numsquares = 0;
411
    int numsquares = 0;
394
    uint64_t temp = magic_bishop_mask[i];
412
    uint64_t temp = magic_bishop_mask[i];
395
 
413
 
396
    while (temp) {
414
    while (temp) {
397
      uint64_t abit = temp & (0-temp); // Pierre-Marie Baty -- fixed signedness warning
415
      uint64_t abit = temp & (0-temp); // Pierre-Marie Baty -- signedness warning fix
398
 
416
 
399
      squares[numsquares++] =
417
      squares[numsquares++] =
400
          initmagicmoves_bitpos64_database[(abit *
418
          initmagicmoves_bitpos64_database[(abit *
401
              0x07EDD5E59A4E28C2ull) >> 58];
419
              0x07EDD5E59A4E28C2ull) >> 58];
402
      temp ^= abit;
420
      temp ^= abit;
403
    }
421
    }
404
    for (temp = 0; temp < (uint64_t) 1 << numsquares; temp++) {
422
    for (temp = 0; temp < (uint64_t) 1 << numsquares; temp++) {
405
      uint64_t moves;
423
      uint64_t moves;
406
      int t = -lower_b;
-
 
407
      uint64_t tempoccupied =
424
      uint64_t tempoccupied =
408
          InitializeMagicOccupied(squares, numsquares, temp);
425
          InitializeMagicOccupied(squares, numsquares, temp);
409
      moves = InitializeMagicBishop(i, tempoccupied);
426
      moves = InitializeMagicBishop(i, tempoccupied);
410
      *(magic_bishop_indices[i] +
427
      *(magic_bishop_indices[i] +
411
          (tempoccupied * magic_bishop[i] >> magic_bishop_shift[i])) = moves;
428
          (tempoccupied * magic_bishop[i] >> magic_bishop_shift[i])) = moves;
412
      moves |= SetMask(i);
429
      moves |= SetMask(i);
-
 
430
      m = -lower_b;
413
      for (j = 0; j < 4; j++)
431
      for (j = 0; j < 4; j++)
414
        t += PopCnt(moves & mobility_mask_b[j]) * mobility_score_b[j];
432
        m += PopCnt(moves & mobility_mask_b[j]) * mobility_score_b[j];
415
      if (t < 0)
433
      if (m < 0)
416
        t *= 2;
434
        m *= 2;
417
      *(magic_bishop_mobility_indices[i] +
435
      *(magic_bishop_mobility_indices[i] +
418
          (tempoccupied * magic_bishop[i] >> magic_bishop_shift[i])) = t;
436
          (tempoccupied * magic_bishop[i] >> magic_bishop_shift[i])) = m;
419
    }
437
    }
420
  }
438
  }
421
/*
439
/*
422
 Rook attacks and mobility
440
 Rook attacks and mobility
423
 */
441
 */
424
  for (i = 0; i < 64; i++) {
442
  for (i = 0; i < 64; i++) {
425
    int squares[64];
443
    int squares[64];
426
    int numsquares = 0;
444
    int numsquares = 0;
427
    int t;
-
 
428
    uint64_t temp = magic_rook_mask[i];
445
    uint64_t temp = magic_rook_mask[i];
429
 
446
 
430
    while (temp) {
447
    while (temp) {
431
      uint64_t abit = temp & (0-temp); // Pierre-Marie Baty -- fixed signedness warning
448
      uint64_t abit = temp & (0-temp); // Pierre-Marie Baty -- signedness warning fix
432
 
449
 
433
      squares[numsquares++] =
450
      squares[numsquares++] =
434
          initmagicmoves_bitpos64_database[(abit *
451
          initmagicmoves_bitpos64_database[(abit *
435
              0x07EDD5E59A4E28C2ull) >> 58];
452
              0x07EDD5E59A4E28C2ull) >> 58];
436
      temp ^= abit;
453
      temp ^= abit;
Line 440... Line 457...
440
          InitializeMagicOccupied(squares, numsquares, temp);
457
          InitializeMagicOccupied(squares, numsquares, temp);
441
      uint64_t moves = InitializeMagicRook(i, tempoccupied);
458
      uint64_t moves = InitializeMagicRook(i, tempoccupied);
442
      *(magic_rook_indices[i] +
459
      *(magic_rook_indices[i] +
443
          (tempoccupied * magic_rook[i] >> magic_rook_shift[i])) = moves;
460
          (tempoccupied * magic_rook[i] >> magic_rook_shift[i])) = moves;
444
      moves |= SetMask(i);
461
      moves |= SetMask(i);
445
      t = -1;
462
      m = -1;
446
      for (j = 0; j < 4; j++)
463
      for (j = 0; j < 4; j++)
447
        t += PopCnt(moves & mobility_mask_r[j]) * mobility_score_r[j];
464
        m += PopCnt(moves & mobility_mask_r[j]) * mobility_score_r[j];
448
      *(magic_rook_mobility_indices[i] +
465
      *(magic_rook_mobility_indices[i] +
449
          (tempoccupied * magic_rook[i] >> magic_rook_shift[i])) =
466
          (tempoccupied * magic_rook[i] >> magic_rook_shift[i])) =
450
          mob_curve_r[t];
467
          mob_curve_r[m];
451
 
-
 
452
    }
468
    }
453
  }
469
  }
454
}
470
}
455
 
471
 
456
/*
472
/*
Line 573... Line 589...
573
 
589
 
574
/*
590
/*
575
 *******************************************************************************
591
 *******************************************************************************
576
 *                                                                             *
592
 *                                                                             *
577
 *   InitializeChessBoard() initializes the chess board to the normal starting *
593
 *   InitializeChessBoard() initializes the chess board to the normal starting *
578
 *   position.   It then calls SetChessBitboards() to correctly set the usual  *
594
 *   position.  It then calls SetChessBitboards() to correctly set the usual   *
579
 *   occupied-square bitboards to correspond to the starting position.         *
595
 *   occupied-square bitboards to correspond to the starting position.         *
580
 *                                                                             *
596
 *                                                                             *
581
 *******************************************************************************
597
 *******************************************************************************
582
 */
598
 */
583
void InitializeChessBoard(TREE * tree) {
599
void InitializeChessBoard(TREE * tree) {
584
  int i;
600
  int i;
585
 
601
 
586
  if (strlen(initial_position)) {
602
  if (strlen(initial_position)) {
587
    int nargs;
603
    int nargs;
588
 
604
 
589
    nargs = ReadParse(initial_position, args, " ;");
605
    nargs = ReadParse(initial_position, args, " \t;");
590
    SetBoard(tree, nargs, args, 1);
606
    SetBoard(tree, nargs, args, 1);
591
  } else {
607
  } else {
592
    for (i = 0; i < 64; i++)
608
    for (i = 0; i < 64; i++)
593
      PcOnSq(i) = empty;
609
      PcOnSq(i) = empty;
594
    game_wtm = 1;
610
    game_wtm = 1;
Line 642... Line 658...
642
/*
658
/*
643
 now, set the bit-boards.
659
 now, set the bit-boards.
644
 */
660
 */
645
    SetChessBitBoards(tree);
661
    SetChessBitBoards(tree);
646
  }
662
  }
647
/*
-
 
648
 clear the caches.
-
 
649
 */
-
 
650
  for (i = 0; i < 64; i++)
-
 
651
    tree->cache_n[i] = ~0ull;
-
 
652
/*
663
/*
653
 initialize 50 move counter and repetition list/index.
664
 initialize 50 move counter and repetition list/index.
654
 */
665
 */
655
  Reversible(0) = 0;
666
  Reversible(0) = 0;
656
  tree->rep_index = 0;
667
  rep_index = 0;
657
  tree->rep_list[0] = HashKey;
668
  tree->rep_list[0] = HashKey;
658
}
669
}
659
 
670
 
660
/*
671
/*
661
 *******************************************************************************
672
 *******************************************************************************
Line 711... Line 722...
711
    for (piece = knight; piece < king; piece++)
722
    for (piece = knight; piece < king; piece++)
712
      TotalPieces(side, occupied) +=
723
      TotalPieces(side, occupied) +=
713
          PopCnt(Pieces(side, piece)) * p_vals[piece];
724
          PopCnt(Pieces(side, piece)) * p_vals[piece];
714
  }
725
  }
715
  TotalAllPieces = PopCnt(OccupiedSquares);
726
  TotalAllPieces = PopCnt(OccupiedSquares);
716
/*
-
 
717
 initialize major/minor counts.
-
 
718
 */
-
 
719
  for (side = black; side <= white; side++) {
-
 
720
    TotalMajors(side) = TotalPieces(side, rook)
-
 
721
        + 2 * TotalPieces(side, queen);
-
 
722
    TotalMinors(side) = TotalPieces(side, knight)
-
 
723
        + TotalPieces(side, bishop);
-
 
724
  }
-
 
725
  tree->rep_index = 0;
727
  rep_index = 0;
726
  tree->rep_list[0] = HashKey;
728
  tree->rep_list[0] = HashKey;
727
}
729
}
728
 
730
 
729
/*
731
/*
730
 *******************************************************************************
732
 *******************************************************************************
Line 736... Line 738...
736
 *   in sequence.                                                              *
738
 *   in sequence.                                                              *
737
 *                                                                             *
739
 *                                                                             *
738
 *******************************************************************************
740
 *******************************************************************************
739
 */
741
 */
740
int InitializeGetLogID(void) {
742
int InitializeGetLogID(void) {
-
 
743
  int t;
741
#if defined(UNIX)
744
#if defined(UNIX)
742
  struct stat *fileinfo = malloc(sizeof(struct stat));
745
  struct stat *fileinfo = malloc(sizeof(struct stat));
743
#endif
746
#endif
744
  int t;
-
 
745
 
747
 
746
  if (!log_id) {
748
  if (!log_id) {
747
    for (log_id = 1; log_id < 300; log_id++) {
749
    for (log_id = 1; log_id < 300; log_id++) {
748
      sprintf(log_filename, "%s/log.%03d", log_path, log_id);
750
      sprintf(log_filename, "%s/log.%03d", log_path, log_id);
749
      sprintf(history_filename, "%s/game.%03d", log_path, log_id);
751
      sprintf(history_filename, "%s/game.%03d", log_path, log_id);
750
      log_file = fopen(log_filename, "r");
752
      log_file = fopen(log_filename, "r");
751
      if (!log_file)
753
      if (!log_file)
752
        break;
754
        break;
753
      fclose(log_file);
755
      fclose(log_file);
754
    }
756
    }
-
 
757
  }
755
#if defined(UNIX)
758
#if defined(UNIX)
756
/*  a kludge to work around an xboard 4.2.3 problem.  It sends two "quit"
759
/*  a kludge to work around an xboard 4.2.3 problem.  It sends two "quit"
757
   commands, which causes every other log.nnn file to be empty.  this code
760
   commands, which causes every other log.nnn file to be empty.  this code
758
   looks for a very small log.nnn file as the last one, and if it is small,
761
   looks for a very small log.nnn file as the last one, and if it is small,
759
   then we simply overwrite it to solve this problem temporarily.  this will
762
   then we simply overwrite it to solve this problem temporarily.  this will
760
   be removed when the nexto xboard version comes out to fix this extra quit
763
   be removed when the nexto xboard version comes out to fix this extra quit
761
   problem.                                                               */
764
   problem.                                                                  */
762
    {
765
  {
763
      char tfn[128];
766
    char tfn[128];
764
      FILE *tlog;
767
    FILE *tlog;
765
 
768
 
766
      sprintf(tfn, "%s/log.%03d", log_path, log_id - 1);
769
    sprintf(tfn, "%s/log.%03d", log_path, log_id - 1);
767
      tlog = fopen(tfn, "r+");
770
    tlog = fopen(tfn, "r+");
768
      if (tlog) {
771
    if (tlog) {
769
        fstat(fileno(tlog), fileinfo);
772
      fstat(fileno(tlog), fileinfo);
770
        if (fileinfo->st_size < 1700)
773
      if (fileinfo->st_size < 2000)
771
          log_id--;
774
        log_id--;
772
      }
-
 
773
    }
775
    }
-
 
776
  }
774
#endif
777
#endif
775
  }
-
 
776
  t = log_id++;
778
  t = log_id++;
777
  return t;
779
  return t;
778
}
780
}
779
 
781
 
780
/*
782
/*
781
 *******************************************************************************
783
 *******************************************************************************
782
 *                                                                             *
784
 *                                                                             *
783
 *   InitializeHashTables() is used to clear all hash entries completely, so   *
785
 *   InitializeHashTables() is used to clear all hash entries completely, so   *
784
 *   that no old information remains to interefere with a new game or test     *
786
 *   that no old information remains to interefere with a new game or test     *
785
 *   position.                                                                 *
787
 *   position.                                                                 *
-
 
788
 *                                                                             *
-
 
789
 *   Whenever any hash table size is changed, they are initialized by calling  *
-
 
790
 *   this procedure to make sure that in the case of NUMA hardware, the trick  *
-
 
791
 *   explained below is always executed.                                       *
-
 
792
 *                                                                             *
-
 
793
 *   This code uses the NUMA fix when using MT threads.  It clears size / MT   *
-
 
794
 *   bytes per cpu, after pinning the current thread to the correct cpu, so    *
-
 
795
 *   that the data will fault in to the correct NUMA node.  If the size is not *
-
 
796
 *   perfectly divisible by MT (max threads) it clears the final piece at the  *
-
 
797
 *   end of each loop.                                                         *
-
 
798
 *                                                                             *
-
 
799
 *   Note that if no size has changed, (fault_in = 0) then we skip the NUMA    *
-
 
800
 *   stuff and just clear the tables, period.                                  *
786
 *                                                                             *
801
 *                                                                             *
787
 *******************************************************************************
802
 *******************************************************************************
788
 */
803
 */
789
void InitializeHashTables(void) {
804
void InitializeHashTables(fault_in) {
790
  unsigned int i, side; // Pierre-Marie Baty -- fixed type
805
  uint64_t mem_per_node;
-
 
806
  int node;
791
 
807
 
792
  transposition_age = 0;
808
  transposition_age = 0;
793
  if (!trans_ref)
809
  if (fault_in && smp_numa) {
794
    return;
-
 
795
  for (i = 0; i < hash_table_size; i++) {
-
 
796
    (trans_ref + i)->word1 = 0;
-
 
797
    (trans_ref + i)->word2 = 0;
-
 
798
  }
810
/*
799
  for (i = 0; i < hash_path_size; i++)
811
 ************************************************************
800
    (hash_path + i)->hash_path_age = -99;
812
 *                                                          *
801
  if (!pawn_hash_table)
-
 
802
    return;
-
 
803
  for (i = 0; i < pawn_hash_table_size; i++) {
813
 *  First, initialize the primary transposition/refutation  *
804
    (pawn_hash_table + i)->key = 0;
-
 
805
    (pawn_hash_table + i)->score_mg = 0;
814
 *  (hash) table, using the NUMA trick to place part of     *
806
    (pawn_hash_table + i)->score_eg = 0;
815
 *  the trans/ref on each node of the NUMA system.          *
807
    for (side = black; side <= white; side++) {
816
 *                                                          *
808
      (pawn_hash_table + i)->defects_k[side] = 0;
817
 ************************************************************
-
 
818
 */
809
      (pawn_hash_table + i)->defects_e[side] = 0;
819
    mem_per_node =
810
      (pawn_hash_table + i)->defects_d[side] = 0;
820
        hash_table_size * sizeof(HASH_ENTRY) / Max(smp_max_threads, 1);
811
      (pawn_hash_table + i)->defects_q[side] = 0;
821
    for (node = 0; node < (int) smp_max_threads; node++) { // Pierre-Marie Baty -- added type cast
812
      (pawn_hash_table + i)->all[side] = 0;
822
      ThreadAffinity(node);
813
      (pawn_hash_table + i)->passed[side] = 0;
823
      memset((void *) ((size_t) hash_table + node * mem_per_node), 0, (size_t) mem_per_node); // Pierre-Marie Baty -- added type casts + missing critical parentheses!
814
    }
824
    }
-
 
825
    ThreadAffinity(0);
-
 
826
    if (mem_per_node * Max(smp_max_threads,
-
 
827
            1) < hash_table_size * sizeof(HASH_ENTRY))
-
 
828
      memset((void *) ((size_t) hash_table + smp_max_threads * mem_per_node), 0, // Pierre-Marie Baty -- added type cast + missing critical parentheses!
-
 
829
          hash_table_size * sizeof(HASH_ENTRY) -
-
 
830
          (size_t) mem_per_node * smp_max_threads); // Pierre-Marie Baty -- added type cast
-
 
831
/*
-
 
832
 ************************************************************
-
 
833
 *                                                          *
-
 
834
 *  Second, initialize the primary hash path table, using   *
-
 
835
 *  the NUMA trick to place part of the hash path table on  *
-
 
836
 *  each node of the NUMA system.                           *
-
 
837
 *                                                          *
-
 
838
 ************************************************************
-
 
839
 */
-
 
840
    mem_per_node =
-
 
841
        hash_path_size * sizeof(HPATH_ENTRY) / Max(smp_max_threads, 1);
-
 
842
    for (node = 0; node < (int) smp_max_threads; node++) { // Pierre-Marie Baty -- added type cast
-
 
843
      ThreadAffinity(node);
-
 
844
      memset((void *) ((size_t) hash_path + node * mem_per_node), 0, (size_t) mem_per_node); // Pierre-Marie Baty -- added type casts + missing critical parentheses!
-
 
845
    }
-
 
846
    ThreadAffinity(1 % Min(1, smp_max_threads));
-
 
847
    if (mem_per_node * Max(smp_max_threads,
-
 
848
            1) < hash_path_size * sizeof(HPATH_ENTRY))
-
 
849
      memset((void *) ((size_t) hash_path + smp_max_threads * mem_per_node), 0, // Pierre-Marie Baty -- added type cast + missing critical parentheses!
-
 
850
          hash_path_size * sizeof(HPATH_ENTRY) -
-
 
851
          (size_t) mem_per_node * smp_max_threads); // Pierre-Marie Baty -- added type cast
-
 
852
/*
-
 
853
 ************************************************************
-
 
854
 *                                                          *
-
 
855
 *  Third, initialize the primary pawn hash table, using    *
-
 
856
 *  the NUMA trick to place part of the pawn hash table on  *
-
 
857
 *  each node of the NUMA system.                           *
-
 
858
 *                                                          *
-
 
859
 ************************************************************
-
 
860
 */
-
 
861
    mem_per_node =
-
 
862
        pawn_hash_table_size * sizeof(PAWN_HASH_ENTRY) / Max(smp_max_threads,
-
 
863
        1);
-
 
864
    for (node = 0; node < (int) smp_max_threads; node++) { // Pierre-Marie Baty -- added type cast
-
 
865
      ThreadAffinity(node);
-
 
866
      memset((void *) ((size_t) pawn_hash_table + node * mem_per_node), 0, (size_t) mem_per_node); // Pierre-Marie Baty -- added type casts + missing critical parentheses!
-
 
867
    }
-
 
868
    ThreadAffinity(4 % Min(4, smp_max_threads));
-
 
869
    if (mem_per_node * Max(smp_max_threads,
-
 
870
            1) < pawn_hash_table_size * sizeof(PAWN_HASH_ENTRY))
-
 
871
      memset((void *) ((size_t) pawn_hash_table + smp_max_threads * mem_per_node), 0, // Pierre-Marie Baty -- added type cast + missing critical parentheses!
-
 
872
          pawn_hash_table_size * sizeof(PAWN_HASH_ENTRY) -
-
 
873
          (size_t) mem_per_node * smp_max_threads); // Pierre-Marie Baty -- added type cast
-
 
874
/*
-
 
875
 ************************************************************
-
 
876
 *                                                          *
-
 
877
 *  Finally, initialize the eval hash table, using the NUMA *
-
 
878
 *  trick to place part of the eval hash table on each node *
-
 
879
 *  of the NUMA system.                                     *
-
 
880
 *                                                          *
-
 
881
 ************************************************************
-
 
882
 */
-
 
883
    mem_per_node =
-
 
884
        eval_hash_table_size * sizeof(uint64_t) / Max(smp_max_threads, 1);
-
 
885
    for (node = 0; node < (int) smp_max_threads; node++) { // Pierre-Marie Baty -- added type cast
-
 
886
      ThreadAffinity(node);
-
 
887
      memset((void *) ((size_t) eval_hash_table + node * mem_per_node), 0, (size_t) mem_per_node); // Pierre-Marie Baty -- added type casts + missing critical parentheses!
-
 
888
    }
-
 
889
    ThreadAffinity(4 % Min(4, smp_max_threads));
-
 
890
    if (mem_per_node * Max(smp_max_threads,
-
 
891
            1) < eval_hash_table_size * sizeof(uint64_t))
-
 
892
      memset((void *) ((size_t) eval_hash_table + smp_max_threads * mem_per_node), 0, // Pierre-Marie Baty -- added type cast + missing critical parentheses!
-
 
893
          eval_hash_table_size * sizeof(uint64_t) -
-
 
894
          (size_t) mem_per_node * smp_max_threads); // Pierre-Marie Baty -- added type cast
-
 
895
/*
-
 
896
 ************************************************************
-
 
897
 *                                                          *
-
 
898
 *  Before we return, we need to re-pin this thread to the  *
-
 
899
 *  correct processor.                                      *
-
 
900
 *                                                          *
-
 
901
 ************************************************************
-
 
902
 */
-
 
903
    ThreadAffinity(smp_affinity);
-
 
904
  } else {
-
 
905
/*
-
 
906
 ************************************************************
-
 
907
 *                                                          *
-
 
908
 *  Otherwise we only need to use memset() to clear the     *
-
 
909
 *  tables since they have already been faulted in to the   *
-
 
910
 *  correct NUMA node.                                      *
-
 
911
 *                                                          *
-
 
912
 ************************************************************
-
 
913
 */
-
 
914
    memset((void *) hash_table, 0, hash_table_size * sizeof(HASH_ENTRY));
-
 
915
    memset((void *) hash_path, 0, hash_path_size * sizeof(HPATH_ENTRY));
-
 
916
    memset((void *) pawn_hash_table, 0,
-
 
917
        pawn_hash_table_size * sizeof(PAWN_HASH_ENTRY));
-
 
918
    memset((void *) eval_hash_table, 0,
-
 
919
        eval_hash_table_size * sizeof(uint64_t));
815
  }
920
  }
816
}
921
}
817
 
922
 
818
/*
923
/*
819
 *******************************************************************************
924
 *******************************************************************************
820
 *                                                                             *
925
 *                                                                             *
821
 *   InitializeKillers() is used to zero the killer moves so that old killers  *
926
 *   InitializeKillers() is used to zero the killer moves so that old killers  *
822
 *   don't screw up ordering while processing test suites.                     *
927
 *   don't screw up ordering while processing test suites.  Ditto for history  *
-
 
928
 *   counters.                                                                 *
823
 *                                                                             *
929
 *                                                                             *
824
 *******************************************************************************
930
 *******************************************************************************
825
 */
931
 */
826
void InitializeKillers(void) {
932
void InitializeKillers(void) {
827
  int i;
933
  int i;
828
 
934
 
829
  for (i = 0; i < MAXPLY; i++) {
935
  for (i = 0; i < MAXPLY; i++) {
830
    block[0]->killers[i].move1 = 0;
936
    block[0]->killers[i].move1 = 0;
831
    block[0]->killers[i].move2 = 0;
937
    block[0]->killers[i].move2 = 0;
832
  }
938
  }
833
}
-
 
834
 
-
 
835
/*
-
 
836
 *******************************************************************************
-
 
837
 *                                                                             *
-
 
838
 *   InitializeKingSafety() is used to initialize the king safety matrix.      *
-
 
839
 *   This is set so that the matrix, indexed by king safety pawn structure     *
-
 
840
 *   index and by king safety piece tropism, combines the two indices to       *
-
 
841
 *   produce a single score.  As either index rises, the king safety score     *
-
 
842
 *   tracks along, but as both rise, the king safety score rises much more     *
-
 
843
 *   quickly.                                                                  *
-
 
844
 *                                                                             *
-
 
845
 *******************************************************************************
-
 
846
 */
-
 
847
void InitializeKingSafety() {
-
 
848
  int safety, tropism;
-
 
849
 
-
 
850
  for (safety = 0; safety < 16; safety++) {
939
  for (i = 0; i < 1024; i++)
851
    for (tropism = 0; tropism < 16; tropism++) {
-
 
852
      king_safety[safety][tropism] =
-
 
853
          180 * ((safety_vector[safety] + 100) * (tropism_vector[tropism] +
-
 
854
              100) / 100 - 100) / 100;
-
 
855
    }
-
 
856
  }
-
 
857
/*
-
 
858
  for (safety = 0; safety < 16; safety++) {
-
 
859
    for (tropism = 0; tropism < 16; tropism++) {
-
 
860
      printf("%4d", king_safety[safety][tropism]);
-
 
861
    }
-
 
862
    printf("\n");
940
    history[i] = 1024;
863
  }
-
 
864
*/
-
 
865
}
941
}
866
 
942
 
867
/*
943
/*
868
 *******************************************************************************
944
 *******************************************************************************
869
 *                                                                             *
945
 *                                                                             *
Line 896... Line 972...
896
  for (i = 1; i < 8; i++)
972
  for (i = 1; i < 8; i++)
897
    file_mask[i] = file_mask[i - 1] << 1;
973
    file_mask[i] = file_mask[i - 1] << 1;
898
/*
974
/*
899
 masks to determine if a pawn has nearby neighbors or not.
975
 masks to determine if a pawn has nearby neighbors or not.
900
 */
976
 */
901
  for (i = 8; i < 56; i++) {
-
 
902
    if (File(i) > 0 && File(i) < 7)
-
 
903
      mask_pawn_connected[i] =
-
 
904
          SetMask(i - 1) | SetMask(i + 1) | SetMask(i - 9) | SetMask(i - 7)
-
 
905
          | SetMask(i + 7) | SetMask(i + 9);
-
 
906
    else if (File(i) == 0)
-
 
907
      mask_pawn_connected[i] =
-
 
908
          SetMask(i + 1) | SetMask(i - 7) | SetMask(i + 9);
-
 
909
    else if (File(i) == 7)
-
 
910
      mask_pawn_connected[i] =
-
 
911
          SetMask(i - 1) | SetMask(i - 9) | SetMask(i + 7);
-
 
912
  }
-
 
913
#if !defined(INLINEASM)
977
#if !defined(INLINEASM)
914
  msb[0] = 64;
978
  msb[0] = 64;
915
  lsb[0] = 16;
979
  lsb[0] = 16;
916
  for (i = 1; i < 65536; i++) {
980
  for (i = 1; i < 65536; i++) {
917
    lsb[i] = 16;
981
    lsb[i] = 16;
Line 982... Line 1046...
982
      mask_passed[black][i] =
1046
      mask_passed[black][i] =
983
          minus8dir[i - 1] | minus8dir[i] | minus8dir[i + 1];
1047
          minus8dir[i - 1] | minus8dir[i] | minus8dir[i + 1];
984
    }
1048
    }
985
  }
1049
  }
986
/*
1050
/*
987
 initialize hidden passed pawn masks, which are nothing more than 1's on
-
 
988
 squares where the opponent can't have pawns so that our "hidden" passed
1051
 masks to determine if a pawn has supporting contact with friendly pawns.
989
 will work (say we have pawns on h6 and g5, and our opponent has a pawn on
-
 
990
 h7.  he can't have pawns at g6 or f7 or we can't play g6 and free up our h
-
 
991
 pawn.
-
 
992
 */
1052
 */
993
  for (i = 0; i < 8; i++) {
1053
  for (i = 8; i < 56; i++) {
994
    mask_hidden_left[black][i] = 0;
-
 
995
    mask_hidden_right[black][i] = 0;
1054
    if (File(i) > 0 && File(i) < 7) {
996
    mask_hidden_left[white][i] = 0;
1055
      mask_pawn_connected[white][i] =
997
    mask_hidden_right[white][i] = 0;
-
 
998
    if (i > 0) {
-
 
999
      mask_hidden_left[white][i] |= SetMask(39 + i) | SetMask(47 + i);
1056
          SetMask(i - 1) | SetMask(i + 1) | SetMask(i - 9) | SetMask(i - 7);
1000
      mask_hidden_left[black][i] |= SetMask(15 + i) | SetMask(7 + i);
1057
      mask_pawn_connected[black][i] =
1001
    }
-
 
1002
    if (i > 1) {
-
 
1003
      mask_hidden_left[white][i] |= SetMask(46 + i) | SetMask(38 + i);
-
 
1004
      mask_hidden_left[black][i] |= SetMask(6 + i) | SetMask(14 + i);
1058
          SetMask(i - 1) | SetMask(i + 1) | SetMask(i + 9) | SetMask(i + 7);
1005
    }
-
 
1006
    if (i < 6) {
1059
    } else if (File(i) == 0) {
1007
      mask_hidden_right[white][i] |= SetMask(50 + i) | SetMask(42 + i);
1060
      mask_pawn_connected[white][i] = SetMask(i + 1) | SetMask(i - 7);
1008
      mask_hidden_right[black][i] |= SetMask(10 + i) | SetMask(18 + i);
1061
      mask_pawn_connected[black][i] = SetMask(i + 1) | SetMask(i + 9);
1009
    }
-
 
1010
    if (i < 7) {
1062
    } else if (File(i) == 7) {
1011
      mask_hidden_right[white][i] |= SetMask(41 + i) | SetMask(49 + i);
1063
      mask_pawn_connected[white][i] = SetMask(i - 1) | SetMask(i - 9);
1012
      mask_hidden_right[black][i] |= SetMask(17 + i) | SetMask(9 + i);
1064
      mask_pawn_connected[black][i] = SetMask(i - 1) | SetMask(i + 7);
1013
    }
1065
    }
1014
  }
1066
  }
1015
/*
1067
/*
1016
 these masks are used to determine if the other side has any pawns
1068
 these masks are used to determine if the other side has any pawns
1017
 that can attack [square].
1069
 that can attack [square].
1018
 */
1070
 */
1019
  for (i = 8; i < 56; i++) {
1071
  for (i = 8; i < 56; i++) {
1020
    if (!File(i)) {
1072
    if (!File(i)) {
1021
      mask_no_pattacks[white][i] = minus8dir[i + 1];
1073
      mask_pattacks[white][i] = minus8dir[i + 1];
1022
      mask_no_pattacks[black][i] = plus8dir[i + 1];
1074
      mask_pattacks[black][i] = plus8dir[i + 1];
1023
    } else if (File(i) == 7) {
1075
    } else if (File(i) == 7) {
1024
      mask_no_pattacks[white][i] = minus8dir[i - 1];
1076
      mask_pattacks[white][i] = minus8dir[i - 1];
1025
      mask_no_pattacks[black][i] = plus8dir[i - 1];
1077
      mask_pattacks[black][i] = plus8dir[i - 1];
1026
    } else {
1078
    } else {
1027
      mask_no_pattacks[white][i] = minus8dir[i - 1] | minus8dir[i + 1];
1079
      mask_pattacks[white][i] = minus8dir[i - 1] | minus8dir[i + 1];
1028
      mask_no_pattacks[black][i] = plus8dir[i + 1] | plus8dir[i - 1];
1080
      mask_pattacks[black][i] = plus8dir[i + 1] | plus8dir[i - 1];
1029
    }
1081
    }
1030
  }
1082
  }
1031
/*
1083
/*
1032
 enpassant pawns are on either file adjacent to the current file, and
1084
 enpassant pawns are on either file adjacent to the current file, and
1033
 on the same rank.
1085
 on the same rank.
Line 1041... Line 1093...
1041
  mask_eptest[A4] = SetMask(B4);
1093
  mask_eptest[A4] = SetMask(B4);
1042
  mask_eptest[H4] = SetMask(G4);
1094
  mask_eptest[H4] = SetMask(G4);
1043
  mask_eptest[A5] = SetMask(B5);
1095
  mask_eptest[A5] = SetMask(B5);
1044
  mask_eptest[H5] = SetMask(G5);
1096
  mask_eptest[H5] = SetMask(G5);
1045
/*
1097
/*
1046
 initialize masks used to evaluate pawn races.  these masks are
1098
 Initialize masks used to evaluate pawn races.  These masks are
1047
 used to determine if the opposing king is in a position to stop a
1099
 used to determine if the opposing king is in a position to stop a
1048
 passed pawn from racing down and queening.  the data is organized
1100
 passed pawn from racing down and queening.  The data is organized
1049
 as pawn_race[side][onmove][square], where side is black or white,
1101
 as pawn_race[side][onmove][square], where side is black or white,
1050
 and onmove indicates which side is to move for proper tempo
1102
 and onmove indicates which side is to move for proper tempo
1051
 evaluation.
1103
 evaluation.
1052
 */
1104
 */
1053
  for (i = 0; i < 64; i++) {
1105
  for (i = 0; i < 64; i++) {
1054
    pawn_race[white][white][i] = 0;
1106
    pawn_race[white][white][i] = 0;
1055
    pawn_race[white][black][i] = 0;
1107
    pawn_race[white][black][i] = 0;
Line 1090... Line 1142...
1090
        if (KingPawnSquare(j, i, File(j), 1))
1142
        if (KingPawnSquare(j, i, File(j), 1))
1091
          pawn_race[black][black][j] |= SetMask(i);
1143
          pawn_race[black][black][j] |= SetMask(i);
1092
      }
1144
      }
1093
    }
1145
    }
1094
  }
1146
  }
-
 
1147
}
-
 
1148
 
1095
/*
1149
/*
1096
 is_outside[p][a]
-
 
1097
 p=8 bit mask for passed pawns
-
 
1098
 a=8 bit mask for all pawns on board
-
 
1099
 p must have left-most or right-most bit set when compared to
1150
 *******************************************************************************
1100
 mask 'a'.  and this bit must be separated from the next bit
1151
 *                                                                             *
1101
 by at least one file (ie the outside passed pawn is 2 files
1152
 *   InitializeReductions() is used to initialize the reduction matrix used to *
1102
 from the rest of the pawns, at least.
1153
 *   set the reduction value for LMR for each move searched.  It is indexed by *
1103
 ppsq = square that contains a (potential) passed pawn.
1154
 *   depth remaining and # moves searched.                                     *
1104
 psql = leftmost pawn, period.
-
 
1105
 psqr = rightmost pawn, period.
-
 
1106
 0 -> passed pawn is not 'outside'
1155
 *                                                                             *
1107
 1 -> passed pawn is 'outside'
-
 
1108
 2 -> passed pawn is 'outside' on both sides of board
1156
 *******************************************************************************
1109
 */
1157
 */
1110
  for (i = 0; i < 256; i++) {
1158
void InitializeReductions() {
1111
    for (j = 0; j < 256; j++) {
-
 
1112
      int ppsq1, ppsq2, psql, psqr;
1159
  int d, m;
1113
 
1160
 
1114
      is_outside[i][j] = 0;
-
 
1115
      ppsq1 = lsb_8bit[i];
-
 
1116
      if (ppsq1 < 8) {
1161
  for (d = 0; d < 32; d++)
1117
        psql = lsb_8bit[j];
1162
    for (m = 0; m < 64; m++)
1118
        if (ppsq1 < psql - 1 || psql == 8)
-
 
1119
          is_outside[i][j] += 1;
1163
      LMR[d][m] = 0;
1120
      }
-
 
1121
      ppsq2 = msb_8bit[i];
1164
  for (d = 3; d < 32; d++)
1122
      if (ppsq2 < 8) {
1165
    for (m = 1; m < 64; m++) {
1123
        psqr = msb_8bit[j];
1166
      LMR[d][m] = (uint8_t) // Pierre-Marie Baty -- added type cast
1124
        if (ppsq2 > psqr + 1 || psqr == 8)
1167
          Max(Min(log(d * LMR_db) * log(m * LMR_mb) / LMR_s, LMR_max),
1125
          is_outside[i][j] += 1;
1168
          LMR_min);
1126
      }
-
 
1127
      if (ppsq1 == ppsq2 && is_outside[i][j] > 0)
1169
      LMR[d][m] = Min(LMR[d][m], Max(d - 1 - LMR_rdepth, 0));
1128
        is_outside[i][j] = 1;
-
 
1129
    }
1170
    }
1130
  }
-
 
1131
}
1171
}
1132
 
1172
 
1133
/*
1173
/*
1134
 *******************************************************************************
1174
 *******************************************************************************
1135
 *                                                                             *
1175
 *                                                                             *
Line 1137... Line 1177...
1137
 *                                                                             *
1177
 *                                                                             *
1138
 *******************************************************************************
1178
 *******************************************************************************
1139
 */
1179
 */
1140
void InitializeSMP(void) {
1180
void InitializeSMP(void) {
1141
  LockInit(lock_smp);
1181
  LockInit(lock_smp);
1142
  LockInit(lock_split);
-
 
1143
  LockInit(lock_io);
1182
  LockInit(lock_io);
1144
  LockInit(lock_root);
-
 
1145
  LockInit(block[0]->lock);
1183
  LockInit(block[0]->lock);
1146
#if defined(UNIX) && (CPUS > 1)
1184
#if defined(UNIX) && (CPUS > 1)
1147
  pthread_attr_init(&attributes);
1185
  pthread_attr_init(&attributes);
1148
  pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED);
1186
  pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED);
1149
#endif
1187
#endif