Subversion Repositories Games.Chess Giants

Rev

Rev 33 | Rev 154 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
33 pmbaty 1
#include <stddef.h>
108 pmbaty 2
#include <math.h>
33 pmbaty 3
#include "chess.h"
4
#include "data.h"
5
#if defined(UNIX)
6
#  include <unistd.h>
7
#  include <sys/types.h>
8
#else
108 pmbaty 9
#  include <fcntl.h> /* needed for definition of "_O_BINARY" */
33 pmbaty 10
#endif
11
/*
12
 *******************************************************************************
13
 *                                                                             *
14
 *   Initialize() performs routine initialization before anything else is      *
15
 *   attempted.  It uses a group of service routines to initialize various     *
16
 *   data structures that are needed before the engine can do anything at all. *
17
 *                                                                             *
18
 *******************************************************************************
19
 */
20
void Initialize() {
21
  TREE *tree;
108 pmbaty 22
  int /*i, */j, v, major, id/*, node*/; // Pierre-Marie Baty -- unreferenced variables
33 pmbaty 23
 
24
  tree = block[0];
108 pmbaty 25
  for (j = 1; j <= MAX_BLOCKS; j++)
33 pmbaty 26
    block[j] = NULL;
27
  InitializeMasks();
28
  InitializeMagic();
29
  InitializeSMP();
30
  InitializeAttackBoards();
31
  InitializePawnMasks();
32
  InitializeChessBoard(tree);
33
  InitializeKillers();
34
#if !defined(UNIX)
108 pmbaty 35
  _fmode = _O_BINARY; /* set file mode binary to avoid text translation */
33 pmbaty 36
#endif
37
#if defined(EPD)
38
  EGInit();
39
#endif
40
  tree->last[0] = tree->move_list;
41
  tree->last[1] = tree->move_list;
42
  sprintf(log_filename, "%s/book.bin", book_path);
43
  book_file = fopen(log_filename, "rb+");
44
  if (!book_file) {
45
    book_file = fopen(log_filename, "rb");
46
    if (!book_file) {
108 pmbaty 47
      Print(2048, "unable to open book file [%s/book.bin].\n", book_path);
48
      Print(32, "book is disabled\n");
33 pmbaty 49
    } else {
108 pmbaty 50
      Print(2048, "unable to open book file [%s/book.bin] for \"write\".\n",
33 pmbaty 51
          book_path);
108 pmbaty 52
      Print(32, "learning is disabled\n");
33 pmbaty 53
    }
54
  }
55
  sprintf(log_filename, "%s/books.bin", book_path);
56
  normal_bs_file = fopen(log_filename, "rb");
57
  books_file = normal_bs_file;
58
  if (!normal_bs_file)
108 pmbaty 59
    Print(32, "unable to open book file [%s/books.bin].\n", book_path);
33 pmbaty 60
  sprintf(log_filename, "%s/bookc.bin", book_path);
61
  computer_bs_file = fopen(log_filename, "rb");
62
  if (computer_bs_file)
108 pmbaty 63
    Print(32, "found computer opening book file [%s/bookc.bin].\n",
33 pmbaty 64
        book_path);
65
  if (book_file) {
66
    int maj_min;
108 pmbaty 67
    fseek(book_file, 0-sizeof(int), SEEK_END); // Pierre-Marie Baty -- signedness warning fix
68
    v = fread(&maj_min, 4, 1, book_file);
69
    if (v <= 0)
70
      perror("Initialize() fread error: ");
33 pmbaty 71
    major = BookIn32((unsigned char *) &maj_min);
72
    major = major >> 16;
73
    if (major < 23) {
74
      Print(4095, "\nERROR!  book.bin not made by version 23.0 or later\n");
75
      fclose(book_file);
76
      fclose(books_file);
77
      book_file = 0;
78
      books_file = 0;
79
    }
80
  }
81
  id = InitializeGetLogID();
82
  sprintf(log_filename, "%s/log.%03d", log_path, id);
83
  sprintf(history_filename, "%s/game.%03d", log_path, id);
84
  log_file = fopen(log_filename, "w");
85
  history_file = fopen(history_filename, "w+");
86
  if (!history_file) {
87
    printf("ERROR, unable to open game history file, exiting\n");
88
    CraftyExit(1);
89
  }
108 pmbaty 90
  AlignedMalloc((void *) ((void *) &hash_table), 64,
33 pmbaty 91
      sizeof(HASH_ENTRY) * hash_table_size);
108 pmbaty 92
  AlignedMalloc((void *) ((void *) &hash_path), 64,
33 pmbaty 93
      sizeof(HPATH_ENTRY) * hash_path_size);
108 pmbaty 94
  AlignedMalloc((void *) ((void *) &pawn_hash_table), 64,
33 pmbaty 95
      sizeof(PAWN_HASH_ENTRY) * pawn_hash_table_size);
108 pmbaty 96
  AlignedMalloc((void *) ((void *) &eval_hash_table), 64,
97
      sizeof(uint64_t) * eval_hash_table_size);
98
  if (!hash_table) {
99
    Print(2048,
33 pmbaty 100
        "AlignedMalloc() failed, not enough memory (primary trans/ref table).\n");
101
    hash_table_size = 0;
108 pmbaty 102
    hash_table = 0;
33 pmbaty 103
  }
104
  if (!pawn_hash_table) {
108 pmbaty 105
    Print(2048,
33 pmbaty 106
        "AlignedMalloc() failed, not enough memory (pawn hash table).\n");
107
    pawn_hash_table_size = 0;
108
    pawn_hash_table = 0;
109
  }
110
/*
111
 ************************************************************
112
 *                                                          *
113
 *  Now for some NUMA stuff.  We need to allocate the local *
114
 *  memory for each processor, but we can't touch it here   *
115
 *  or it will be faulted in and be allocated on the        *
116
 *  current CPU, which is not where it should be located    *
117
 *  for optimal NUMA performance.  ThreadInit() will do the *
118
 *  actual initialization after each new process is created *
119
 *  so that the pages of local memory will be faulted in on *
120
 *  the correct processor and use local node memory for     *
121
 *  optimal performance.                                    *
122
 *                                                          *
123
 *  If we are using CPU affinity, we need to set this up    *
124
 *  for thread 0 BEFORE we initialize the split blocks so   *
108 pmbaty 125
 *  that they will page fault in on the correct NUMA node.  *
33 pmbaty 126
 *                                                          *
127
 ************************************************************
128
 */
108 pmbaty 129
#if (CPUS > 1)
130
  ThreadAffinity(smp_affinity);
131
#  if !defined(UNIX)
33 pmbaty 132
  ThreadMalloc((int) 0);
108 pmbaty 133
#  else
33 pmbaty 134
  for (i = 0; i < CPUS; i++) {
108 pmbaty 135
    for (j = 0; j < 64; j++) {
136
      AlignedMalloc((void **) &block[i * 64 + j + 1], 2048,
33 pmbaty 137
          (size_t) sizeof(TREE));
138
    }
139
  }
108 pmbaty 140
  for (i = 1; i < 64; i++) {
33 pmbaty 141
    memset((void *) block[i], 0, sizeof(TREE));
142
    LockInit(block[i]->lock);
143
  }
108 pmbaty 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
33 pmbaty 153
#endif
108 pmbaty 154
  thread[0].blocks = 0xffffffffffffffffull;
33 pmbaty 155
  initialized_threads++;
108 pmbaty 156
  InitializeHashTables(1);
33 pmbaty 157
  InitializeKingSafety();
108 pmbaty 158
  InitializeReductions();
33 pmbaty 159
}
160
 
161
/*
162
 *******************************************************************************
163
 *                                                                             *
164
 *   InitializeAttackBoards() is used to initialize the basic bitboards that   *
165
 *   deal with what squares a piece attacks.                                   *
166
 *                                                                             *
167
 *******************************************************************************
168
 */
169
void InitializeAttackBoards(void) {
108 pmbaty 170
  int i, j, d, s, t, frank, ffile, trank, tfile;
33 pmbaty 171
  int sq, lastsq;
172
  static const int knightsq[8] = { -17, -15, -10, -6, 6, 10, 15, 17 };
173
  static const int bishopsq[4] = { -9, -7, 7, 9 };
174
  static const int rooksq[4] = { -8, -1, 1, 8 };
175
  uint64_t sqs;
176
 
177
/*
178
 initialize pawn attack boards
179
 */
180
  for (i = 0; i < 64; i++) {
181
    pawn_attacks[white][i] = 0;
182
    if (i < 56)
183
      for (j = 2; j < 4; j++) {
184
        sq = i + bishopsq[j];
185
        if (Abs(Rank(sq) - Rank(i)) == 1 && Abs(File(sq) - File(i)) == 1 &&
186
            sq < 64 && sq > -1)
187
          pawn_attacks[white][i] =
188
              pawn_attacks[white][i] | (uint64_t) 1 << sq;
189
      }
190
    pawn_attacks[black][i] = 0;
191
    if (i > 7)
192
      for (j = 0; j < 2; j++) {
193
        sq = i + bishopsq[j];
194
        if (Abs(Rank(sq) - Rank(i)) == 1 && Abs(File(sq) - File(i)) == 1 &&
195
            sq < 64 && sq > -1)
196
          pawn_attacks[black][i] =
197
              pawn_attacks[black][i] | (uint64_t) 1 << sq;
198
      }
199
  }
200
/*
201
 initialize knight attack board
202
 */
203
  for (i = 0; i < 64; i++) {
204
    knight_attacks[i] = 0;
205
    frank = Rank(i);
206
    ffile = File(i);
207
    for (j = 0; j < 8; j++) {
208
      sq = i + knightsq[j];
209
      if (sq < 0 || sq > 63)
210
        continue;
211
      trank = Rank(sq);
212
      tfile = File(sq);
213
      if (Abs(frank - trank) > 2 || Abs(ffile - tfile) > 2)
214
        continue;
215
      knight_attacks[i] = knight_attacks[i] | (uint64_t) 1 << sq;
216
    }
217
  }
218
/*
219
 initialize bishop/queen attack boards and masks
220
 */
221
  for (i = 0; i < 64; i++) {
222
    for (j = 0; j < 4; j++) {
223
      sq = i;
224
      lastsq = sq;
225
      sq = sq + bishopsq[j];
226
      while (Abs(Rank(sq) - Rank(lastsq)) == 1 &&
227
          Abs(File(sq) - File(lastsq)) == 1 && sq < 64 && sq > -1) {
228
        if (bishopsq[j] == 7)
229
          plus7dir[i] = plus7dir[i] | (uint64_t) 1 << sq;
230
        else if (bishopsq[j] == 9)
231
          plus9dir[i] = plus9dir[i] | (uint64_t) 1 << sq;
232
        else if (bishopsq[j] == -7)
233
          minus7dir[i] = minus7dir[i] | (uint64_t) 1 << sq;
234
        else
235
          minus9dir[i] = minus9dir[i] | (uint64_t) 1 << sq;
236
        lastsq = sq;
237
        sq = sq + bishopsq[j];
238
      }
239
    }
240
  }
241
  plus1dir[64] = 0;
242
  plus7dir[64] = 0;
243
  plus8dir[64] = 0;
244
  plus9dir[64] = 0;
245
  minus1dir[64] = 0;
246
  minus7dir[64] = 0;
247
  minus8dir[64] = 0;
248
  minus9dir[64] = 0;
249
/*
250
 initialize rook/queen attack boards
251
 */
252
  for (i = 0; i < 64; i++) {
253
    for (j = 0; j < 4; j++) {
254
      sq = i;
255
      lastsq = sq;
256
      sq = sq + rooksq[j];
257
      while (((Abs(Rank(sq) - Rank(lastsq)) == 1 &&
258
                  Abs(File(sq) - File(lastsq)) == 0)
259
              || (Abs(Rank(sq) - Rank(lastsq)) == 0 &&
260
                  Abs(File(sq) - File(lastsq)) == 1)) && sq < 64 && sq > -1) {
261
        if (rooksq[j] == 1)
262
          plus1dir[i] = plus1dir[i] | (uint64_t) 1 << sq;
263
        else if (rooksq[j] == 8)
264
          plus8dir[i] = plus8dir[i] | (uint64_t) 1 << sq;
265
        else if (rooksq[j] == -1)
266
          minus1dir[i] = minus1dir[i] | (uint64_t) 1 << sq;
267
        else
268
          minus8dir[i] = minus8dir[i] | (uint64_t) 1 << sq;
269
        lastsq = sq;
270
        sq = sq + rooksq[j];
271
      }
272
    }
273
  }
274
/*
275
 initialize bishop attack board
276
 */
277
  for (i = 0; i < 64; i++) {
278
    bishop_attacks[i] =
279
        plus9dir[i] | minus9dir[i] | plus7dir[i] | minus7dir[i];
280
  }
281
/*
282
 initialize rook attack board
283
 */
284
  for (i = 0; i < 64; i++) {
285
    rook_attacks[i] = file_mask[File(i)] | rank_mask[Rank(i)];
286
  }
287
/*
288
 initialize king attack board
289
 */
290
  for (i = 0; i < 64; i++) {
291
    king_attacks[i] = 0;
292
    for (j = 0; j < 64; j++) {
293
      if (Distance(i, j) == 1)
294
        king_attacks[i] = king_attacks[i] | SetMask(j);
295
    }
296
  }
297
/*
108 pmbaty 298
 directions[sq1][sq2] gives the "move direction" to move from
33 pmbaty 299
 sq1 to sq2.  intervening[sq1][sq2] gives a bit vector that indicates
300
 which squares must be unoccupied in order for <sq1> to attack <sq2>,
108 pmbaty 301
 assuming a sliding piece is involved.  To use this, you simply have
33 pmbaty 302
 to Or(intervening[sq1][sq2],occupied_squares) and if the result is
303
 "0" then a sliding piece on sq1 would attack sq2 and vice-versa.
304
 */
305
  for (i = 0; i < 64; i++) {
306
    for (j = 0; j < 64; j++)
307
      intervening[i][j] = 0;
308
    sqs = plus1dir[i];
309
    while (sqs) {
310
      j = LSB(sqs);
311
      directions[i][j] = 1;
312
      intervening[i][j] = plus1dir[i] ^ plus1dir[j - 1];
313
      sqs &= sqs - 1;
314
    }
315
    sqs = plus7dir[i];
316
    while (sqs) {
317
      j = LSB(sqs);
318
      directions[i][j] = 7;
319
      intervening[i][j] = plus7dir[i] ^ plus7dir[j - 7];
320
      sqs &= sqs - 1;
321
    }
322
    sqs = plus8dir[i];
323
    while (sqs) {
324
      j = LSB(sqs);
325
      directions[i][j] = 8;
326
      intervening[i][j] = plus8dir[i] ^ plus8dir[j - 8];
327
      sqs &= sqs - 1;
328
    }
329
    sqs = plus9dir[i];
330
    while (sqs) {
331
      j = LSB(sqs);
332
      directions[i][j] = 9;
333
      intervening[i][j] = plus9dir[i] ^ plus9dir[j - 9];
334
      sqs &= sqs - 1;
335
    }
336
    sqs = minus1dir[i];
337
    while (sqs) {
338
      j = LSB(sqs);
339
      directions[i][j] = -1;
340
      intervening[i][j] = minus1dir[i] ^ minus1dir[j + 1];
341
      sqs &= sqs - 1;
342
    }
343
    sqs = minus7dir[i];
344
    while (sqs) {
345
      j = LSB(sqs);
346
      directions[i][j] = -7;
347
      intervening[i][j] = minus7dir[i] ^ minus7dir[j + 7];
348
      sqs &= sqs - 1;
349
    }
350
    sqs = minus8dir[i];
351
    while (sqs) {
352
      j = LSB(sqs);
353
      directions[i][j] = -8;
354
      intervening[i][j] = minus8dir[i] ^ minus8dir[j + 8];
355
      sqs &= sqs - 1;
356
    }
357
    sqs = minus9dir[i];
358
    while (sqs) {
359
      j = LSB(sqs);
360
      directions[i][j] = -9;
361
      intervening[i][j] = minus9dir[i] ^ minus9dir[j + 9];
362
      sqs &= sqs - 1;
363
    }
364
  }
108 pmbaty 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);
379
    }
380
  }
33 pmbaty 381
}
382
 
383
/*
384
 *******************************************************************************
385
 *                                                                             *
386
 *   InitializeMagic() initializes the magic number tables used in the new     *
387
 *   magic move generation algorithm.  We also initialize a set of parallel    *
388
 *   tables that contain mobility scores for each possible set of magic attack *
389
 *   vectors, which saves significant time in the evaluation, since it is done *
390
 *   here before the game actually starts.                                     *
391
 *                                                                             *
392
 *******************************************************************************
393
 */
394
void InitializeMagic(void) {
108 pmbaty 395
  int i, j, m;
33 pmbaty 396
  int initmagicmoves_bitpos64_database[64] = {
397
    63, 0, 58, 1, 59, 47, 53, 2,
398
    60, 39, 48, 27, 54, 33, 42, 3,
399
    61, 51, 37, 40, 49, 18, 28, 20,
400
    55, 30, 34, 11, 43, 14, 22, 4,
401
    62, 57, 46, 52, 38, 26, 32, 41,
402
    50, 36, 17, 19, 29, 10, 13, 21,
403
    56, 45, 25, 31, 35, 16, 9, 12,
404
    44, 24, 15, 8, 23, 7, 6, 5
405
  };
406
/*
407
 Bishop attacks and mobility
408
 */
409
  for (i = 0; i < 64; i++) {
410
    int squares[64];
411
    int numsquares = 0;
412
    uint64_t temp = magic_bishop_mask[i];
413
 
414
    while (temp) {
108 pmbaty 415
      uint64_t abit = temp & (0-temp); // Pierre-Marie Baty -- signedness warning fix
33 pmbaty 416
 
417
      squares[numsquares++] =
418
          initmagicmoves_bitpos64_database[(abit *
419
              0x07EDD5E59A4E28C2ull) >> 58];
420
      temp ^= abit;
421
    }
422
    for (temp = 0; temp < (uint64_t) 1 << numsquares; temp++) {
423
      uint64_t moves;
424
      uint64_t tempoccupied =
425
          InitializeMagicOccupied(squares, numsquares, temp);
426
      moves = InitializeMagicBishop(i, tempoccupied);
427
      *(magic_bishop_indices[i] +
428
          (tempoccupied * magic_bishop[i] >> magic_bishop_shift[i])) = moves;
429
      moves |= SetMask(i);
108 pmbaty 430
      m = -lower_b;
33 pmbaty 431
      for (j = 0; j < 4; j++)
108 pmbaty 432
        m += PopCnt(moves & mobility_mask_b[j]) * mobility_score_b[j];
433
      if (m < 0)
434
        m *= 2;
33 pmbaty 435
      *(magic_bishop_mobility_indices[i] +
108 pmbaty 436
          (tempoccupied * magic_bishop[i] >> magic_bishop_shift[i])) = m;
33 pmbaty 437
    }
438
  }
439
/*
440
 Rook attacks and mobility
441
 */
442
  for (i = 0; i < 64; i++) {
443
    int squares[64];
444
    int numsquares = 0;
445
    uint64_t temp = magic_rook_mask[i];
446
 
447
    while (temp) {
108 pmbaty 448
      uint64_t abit = temp & (0-temp); // Pierre-Marie Baty -- signedness warning fix
33 pmbaty 449
 
450
      squares[numsquares++] =
451
          initmagicmoves_bitpos64_database[(abit *
452
              0x07EDD5E59A4E28C2ull) >> 58];
453
      temp ^= abit;
454
    }
455
    for (temp = 0; temp < (uint64_t) 1 << numsquares; temp++) {
456
      uint64_t tempoccupied =
457
          InitializeMagicOccupied(squares, numsquares, temp);
458
      uint64_t moves = InitializeMagicRook(i, tempoccupied);
459
      *(magic_rook_indices[i] +
460
          (tempoccupied * magic_rook[i] >> magic_rook_shift[i])) = moves;
461
      moves |= SetMask(i);
108 pmbaty 462
      m = -1;
33 pmbaty 463
      for (j = 0; j < 4; j++)
108 pmbaty 464
        m += PopCnt(moves & mobility_mask_r[j]) * mobility_score_r[j];
33 pmbaty 465
      *(magic_rook_mobility_indices[i] +
466
          (tempoccupied * magic_rook[i] >> magic_rook_shift[i])) =
108 pmbaty 467
          mob_curve_r[m];
33 pmbaty 468
    }
469
  }
470
}
471
 
472
/*
473
 *******************************************************************************
474
 *                                                                             *
475
 *   InitializeMagicBishop() does the bishop-specific initialization for a     *
476
 *   particular square on the board.                                           *
477
 *                                                                             *
478
 *******************************************************************************
479
 */
480
uint64_t InitializeMagicBishop(int square, uint64_t occupied) {
481
  uint64_t ret = 0;
482
  uint64_t abit;
483
  uint64_t abit2;
484
  uint64_t rowbits = (uint64_t) 0xFF << 8 * (square / 8);
485
 
486
  abit = (uint64_t) 1 << square;
487
  abit2 = abit;
488
  do {
489
    abit <<= 8 - 1;
490
    abit2 >>= 1;
491
    if (abit2 & rowbits)
492
      ret |= abit;
493
    else
494
      break;
495
  } while (abit && !(abit & occupied));
496
  abit = (uint64_t) 1 << square;
497
  abit2 = abit;
498
  do {
499
    abit <<= 8 + 1;
500
    abit2 <<= 1;
501
    if (abit2 & rowbits)
502
      ret |= abit;
503
    else
504
      break;
505
  } while (abit && !(abit & occupied));
506
  abit = (uint64_t) 1 << square;
507
  abit2 = abit;
508
  do {
509
    abit >>= 8 - 1;
510
    abit2 <<= 1;
511
    if (abit2 & rowbits)
512
      ret |= abit;
513
    else
514
      break;
515
  } while (abit && !(abit & occupied));
516
  abit = (uint64_t) 1 << square;
517
  abit2 = abit;
518
  do {
519
    abit >>= 8 + 1;
520
    abit2 >>= 1;
521
    if (abit2 & rowbits)
522
      ret |= abit;
523
    else
524
      break;
525
  } while (abit && !(abit & occupied));
526
  return ret;
527
}
528
 
529
/*
530
 *******************************************************************************
531
 *                                                                             *
532
 *   InitializeMagicOccupied() generates a specific occupied-square bitboard   *
533
 *   needed during initialization.                                             *
534
 *                                                                             *
535
 *******************************************************************************
536
 */
537
uint64_t InitializeMagicOccupied(int *squares, int numSquares,
538
    uint64_t linoccupied) {
539
  int i;
540
  uint64_t ret = 0;
541
 
542
  for (i = 0; i < numSquares; i++)
543
    if (linoccupied & (uint64_t) 1 << i)
544
      ret |= (uint64_t) 1 << squares[i];
545
  return ret;
546
}
547
 
548
/*
549
 *******************************************************************************
550
 *                                                                             *
551
 *   InitializeMagicRook() does the rook-specific initialization for a         *
552
 *   particular square on the board.                                           *
553
 *                                                                             *
554
 *******************************************************************************
555
 */
556
uint64_t InitializeMagicRook(int square, uint64_t occupied) {
557
  uint64_t ret = 0;
558
  uint64_t abit;
559
  uint64_t rowbits = (uint64_t) 0xFF << 8 * (square / 8);
560
 
561
  abit = (uint64_t) 1 << square;
562
  do {
563
    abit <<= 8;
564
    ret |= abit;
565
  } while (abit && !(abit & occupied));
566
  abit = (uint64_t) 1 << square;
567
  do {
568
    abit >>= 8;
569
    ret |= abit;
570
  } while (abit && !(abit & occupied));
571
  abit = (uint64_t) 1 << square;
572
  do {
573
    abit <<= 1;
574
    if (abit & rowbits)
575
      ret |= abit;
576
    else
577
      break;
578
  } while (!(abit & occupied));
579
  abit = (uint64_t) 1 << square;
580
  do {
581
    abit >>= 1;
582
    if (abit & rowbits)
583
      ret |= abit;
584
    else
585
      break;
586
  } while (!(abit & occupied));
587
  return ret;
588
}
589
 
590
/*
591
 *******************************************************************************
592
 *                                                                             *
593
 *   InitializeChessBoard() initializes the chess board to the normal starting *
108 pmbaty 594
 *   position.  It then calls SetChessBitboards() to correctly set the usual   *
33 pmbaty 595
 *   occupied-square bitboards to correspond to the starting position.         *
596
 *                                                                             *
597
 *******************************************************************************
598
 */
599
void InitializeChessBoard(TREE * tree) {
600
  int i;
601
 
602
  if (strlen(initial_position)) {
603
    int nargs;
604
 
108 pmbaty 605
    nargs = ReadParse(initial_position, args, " \t;");
33 pmbaty 606
    SetBoard(tree, nargs, args, 1);
607
  } else {
608
    for (i = 0; i < 64; i++)
609
      PcOnSq(i) = empty;
610
    game_wtm = 1;
611
/*
612
 place pawns
613
 */
614
    for (i = 0; i < 8; i++) {
615
      PcOnSq(i + 8) = pawn;
616
      PcOnSq(i + 48) = -pawn;
617
    }
618
/*
619
 place knights
620
 */
621
    PcOnSq(B1) = knight;
622
    PcOnSq(G1) = knight;
623
    PcOnSq(B8) = -knight;
624
    PcOnSq(G8) = -knight;
625
/*
626
 place bishops
627
 */
628
    PcOnSq(C1) = bishop;
629
    PcOnSq(F1) = bishop;
630
    PcOnSq(C8) = -bishop;
631
    PcOnSq(F8) = -bishop;
632
/*
633
 place rooks
634
 */
635
    PcOnSq(A1) = rook;
636
    PcOnSq(H1) = rook;
637
    PcOnSq(A8) = -rook;
638
    PcOnSq(H8) = -rook;
639
/*
640
 place queens
641
 */
642
    PcOnSq(D1) = queen;
643
    PcOnSq(D8) = -queen;
644
/*
645
 place kings
646
 */
647
    PcOnSq(E1) = king;
648
    PcOnSq(E8) = -king;
649
/*
650
 initialize castling status so all castling is legal.
651
 */
652
    Castle(0, black) = 3;
653
    Castle(0, white) = 3;
654
/*
655
 initialize enpassant status.
656
 */
657
    EnPassant(0) = 0;
658
/*
659
 now, set the bit-boards.
660
 */
661
    SetChessBitBoards(tree);
662
  }
663
/*
664
 initialize 50 move counter and repetition list/index.
665
 */
666
  Reversible(0) = 0;
108 pmbaty 667
  rep_index = 0;
33 pmbaty 668
  tree->rep_list[0] = HashKey;
669
}
670
 
671
/*
672
 *******************************************************************************
673
 *                                                                             *
674
 *   SetChessBitBoards() is used to set the occupied-square bitboards so that  *
675
 *   they agree with the current real chessboard.                              *
676
 *                                                                             *
677
 *******************************************************************************
678
 */
679
void SetChessBitBoards(TREE * tree) {
680
  int side, piece, square;
681
 
682
  HashKey = 0;
683
  PawnHashKey = 0;
684
  Material = 0;
685
  for (side = black; side <= white; side++)
686
    for (piece = empty; piece <= king; piece++)
687
      Pieces(side, piece) = 0;
688
  for (square = 0; square < 64; square++) {
689
    if (!PcOnSq(square))
690
      continue;
691
    piece = PcOnSq(square);
692
    side = (piece > 0) ? 1 : 0;
693
    Pieces(side, Abs(piece)) |= SetMask(square);
694
    Occupied(side) |= SetMask(square);
695
    Hash(side, Abs(piece), square);
696
    if (Abs(piece) == pawn)
697
      HashP(side, square);
698
    Material += PieceValues(side, Abs(piece));
699
  }
700
  if (Pieces(white, king))
701
    KingSQ(white) = LSB(Pieces(white, king));
702
  if (Pieces(black, king))
703
    KingSQ(black) = LSB(Pieces(black, king));
704
  if (EnPassant(0))
705
    HashEP(EnPassant(0));
706
  if (!(Castle(0, white) & 1))
707
    HashCastle(0, white);
708
  if (!(Castle(0, white) & 2))
709
    HashCastle(1, white);
710
  if (!(Castle(0, black) & 1))
711
    HashCastle(0, black);
712
  if (!(Castle(0, black) & 2))
713
    HashCastle(1, black);
714
/*
715
 initialize black/white piece counts.
716
 */
717
  for (side = black; side <= white; side++)
718
    for (piece = pawn; piece <= king; piece++)
719
      TotalPieces(side, piece) = PopCnt(Pieces(side, piece));
720
  for (side = black; side <= white; side++) {
721
    TotalPieces(side, occupied) = 0;
722
    for (piece = knight; piece < king; piece++)
723
      TotalPieces(side, occupied) +=
724
          PopCnt(Pieces(side, piece)) * p_vals[piece];
725
  }
726
  TotalAllPieces = PopCnt(OccupiedSquares);
108 pmbaty 727
  rep_index = 0;
33 pmbaty 728
  tree->rep_list[0] = HashKey;
729
}
730
 
731
/*
732
 *******************************************************************************
733
 *                                                                             *
734
 *   InitializeGetLogID() is used to determine the nnn (in log.nnn) to use for *
735
 *   the current game.  It is typically the ID of the last log + 1, but we do  *
736
 *   not know what that is if we just started the engine.  We simply look thru *
737
 *   existing log files in the current directory and use the next un-used name *
738
 *   in sequence.                                                              *
739
 *                                                                             *
740
 *******************************************************************************
741
 */
742
int InitializeGetLogID(void) {
108 pmbaty 743
  int t;
33 pmbaty 744
#if defined(UNIX)
745
  struct stat *fileinfo = malloc(sizeof(struct stat));
746
#endif
747
 
748
  if (!log_id) {
749
    for (log_id = 1; log_id < 300; log_id++) {
750
      sprintf(log_filename, "%s/log.%03d", log_path, log_id);
751
      sprintf(history_filename, "%s/game.%03d", log_path, log_id);
752
      log_file = fopen(log_filename, "r");
753
      if (!log_file)
754
        break;
755
      fclose(log_file);
756
    }
108 pmbaty 757
  }
33 pmbaty 758
#if defined(UNIX)
759
/*  a kludge to work around an xboard 4.2.3 problem.  It sends two "quit"
760
   commands, which causes every other log.nnn file to be empty.  this code
761
   looks for a very small log.nnn file as the last one, and if it is small,
762
   then we simply overwrite it to solve this problem temporarily.  this will
763
   be removed when the nexto xboard version comes out to fix this extra quit
108 pmbaty 764
   problem.                                                                  */
765
  {
766
    char tfn[128];
767
    FILE *tlog;
33 pmbaty 768
 
108 pmbaty 769
    sprintf(tfn, "%s/log.%03d", log_path, log_id - 1);
770
    tlog = fopen(tfn, "r+");
771
    if (tlog) {
772
      fstat(fileno(tlog), fileinfo);
773
      if (fileinfo->st_size < 2000)
774
        log_id--;
33 pmbaty 775
    }
108 pmbaty 776
  }
33 pmbaty 777
#endif
778
  t = log_id++;
779
  return t;
780
}
781
 
782
/*
783
 *******************************************************************************
784
 *                                                                             *
785
 *   InitializeHashTables() is used to clear all hash entries completely, so   *
786
 *   that no old information remains to interefere with a new game or test     *
787
 *   position.                                                                 *
788
 *                                                                             *
108 pmbaty 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.                                  *
801
 *                                                                             *
33 pmbaty 802
 *******************************************************************************
803
 */
108 pmbaty 804
void InitializeHashTables(fault_in) {
805
  uint64_t mem_per_node;
806
  int node;
33 pmbaty 807
 
808
  transposition_age = 0;
108 pmbaty 809
  if (fault_in && smp_numa) {
810
/*
811
 ************************************************************
812
 *                                                          *
813
 *  First, initialize the primary transposition/refutation  *
814
 *  (hash) table, using the NUMA trick to place part of     *
815
 *  the trans/ref on each node of the NUMA system.          *
816
 *                                                          *
817
 ************************************************************
818
 */
819
    mem_per_node =
820
        hash_table_size * sizeof(HASH_ENTRY) / Max(smp_max_threads, 1);
821
    for (node = 0; node < (int) smp_max_threads; node++) { // Pierre-Marie Baty -- added type cast
822
      ThreadAffinity(node);
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!
33 pmbaty 824
    }
108 pmbaty 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));
33 pmbaty 920
  }
921
}
922
 
923
/*
924
 *******************************************************************************
925
 *                                                                             *
926
 *   InitializeKillers() is used to zero the killer moves so that old killers  *
108 pmbaty 927
 *   don't screw up ordering while processing test suites.  Ditto for history  *
928
 *   counters.                                                                 *
33 pmbaty 929
 *                                                                             *
930
 *******************************************************************************
931
 */
932
void InitializeKillers(void) {
933
  int i;
934
 
935
  for (i = 0; i < MAXPLY; i++) {
936
    block[0]->killers[i].move1 = 0;
937
    block[0]->killers[i].move2 = 0;
938
  }
108 pmbaty 939
  for (i = 0; i < 1024; i++)
940
    history[i] = 1024;
33 pmbaty 941
}
942
 
943
/*
944
 *******************************************************************************
945
 *                                                                             *
946
 *   InitializeMasks() is used to initialize the various bitboard masks that   *
947
 *   are used throughout Crafty.                                               *
948
 *                                                                             *
949
 *******************************************************************************
950
 */
951
void InitializeMasks(void) {
952
  int i, j;
953
 
954
/*
955
 masks to set/clear a bit on a specific square
956
 */
957
  for (i = 0; i < 64; i++) {
958
    ClearMask(i) = ~((uint64_t) 1 << i);
959
    SetMask(i) = (uint64_t) 1 << i;
960
  }
961
  ClearMask(BAD_SQUARE) = 0;
962
  SetMask(BAD_SQUARE) = 0;
963
/*
964
 masks to select bits on a specific rank or file
965
 */
966
  rank_mask[0] = (uint64_t) 255;
967
  for (i = 1; i < 8; i++)
968
    rank_mask[i] = rank_mask[i - 1] << 8;
969
  file_mask[FILEA] = (uint64_t) 1;
970
  for (i = 1; i < 8; i++)
971
    file_mask[FILEA] = file_mask[FILEA] | file_mask[FILEA] << 8;
972
  for (i = 1; i < 8; i++)
973
    file_mask[i] = file_mask[i - 1] << 1;
974
/*
975
 masks to determine if a pawn has nearby neighbors or not.
976
 */
977
#if !defined(INLINEASM)
978
  msb[0] = 64;
979
  lsb[0] = 16;
980
  for (i = 1; i < 65536; i++) {
981
    lsb[i] = 16;
982
    for (j = 0; j < 16; j++)
983
      if (i & (1 << j)) {
984
        msb[i] = j;
985
        if (lsb[i] == 16)
986
          lsb[i] = j;
987
      }
988
  }
989
#endif
990
  msb_8bit[0] = 8;
991
  lsb_8bit[0] = 8;
992
  pop_cnt_8bit[0] = 0;
993
  for (i = 1; i < 256; i++) {
994
    pop_cnt_8bit[i] = 0;
995
    for (j = 0; j < 8; j++)
996
      if (i & (1 << j))
997
        pop_cnt_8bit[i]++;
998
    lsb_8bit[i] = 8;
999
    for (j = 0; j < 8; j++) {
1000
      if (i & (1 << j)) {
1001
        msb_8bit[i] = j;
1002
        if (lsb_8bit[i] == 8)
1003
          lsb_8bit[i] = j;
1004
      }
1005
    }
1006
  }
1007
}
1008
 
1009
/*
1010
 *******************************************************************************
1011
 *                                                                             *
1012
 *   InitializePawnMasks() is used to initialize the various bitboard masks    *
1013
 *   that are used in pawn evaluation.                                         *
1014
 *                                                                             *
1015
 *******************************************************************************
1016
 */
1017
void InitializePawnMasks(void) {
1018
  int i, j;
1019
 
1020
/*
1021
 initialize isolated pawn masks, which are nothing more than 1's on
1022
 the files adjacent to the pawn file.
1023
 */
1024
  for (i = 0; i < 64; i++) {
1025
    if (!File(i))
1026
      mask_pawn_isolated[i] = file_mask[File(i) + 1];
1027
    else if (File(i) == 7)
1028
      mask_pawn_isolated[i] = file_mask[File(i) - 1];
1029
    else
1030
      mask_pawn_isolated[i] = file_mask[File(i) - 1] | file_mask[File(i) + 1];
1031
  }
1032
/*
1033
 initialize passed pawn masks, which are nothing more than 1's on
1034
 the pawn's file and the adjacent files, but only on ranks that are
1035
 in "front" of the pawn.
1036
 */
1037
  for (i = 0; i < 64; i++) {
1038
    if (!File(i)) {
1039
      mask_passed[white][i] = plus8dir[i] | plus8dir[i + 1];
1040
      mask_passed[black][i] = minus8dir[i] | minus8dir[i + 1];
1041
    } else if (File(i) == 7) {
1042
      mask_passed[white][i] = plus8dir[i - 1] | plus8dir[i];
1043
      mask_passed[black][i] = minus8dir[i - 1] | minus8dir[i];
1044
    } else {
1045
      mask_passed[white][i] = plus8dir[i - 1] | plus8dir[i] | plus8dir[i + 1];
1046
      mask_passed[black][i] =
1047
          minus8dir[i - 1] | minus8dir[i] | minus8dir[i + 1];
1048
    }
1049
  }
1050
/*
108 pmbaty 1051
 masks to determine if a pawn has supporting contact with friendly pawns.
33 pmbaty 1052
 */
108 pmbaty 1053
  for (i = 8; i < 56; i++) {
1054
    if (File(i) > 0 && File(i) < 7) {
1055
      mask_pawn_connected[white][i] =
1056
          SetMask(i - 1) | SetMask(i + 1) | SetMask(i - 9) | SetMask(i - 7);
1057
      mask_pawn_connected[black][i] =
1058
          SetMask(i - 1) | SetMask(i + 1) | SetMask(i + 9) | SetMask(i + 7);
1059
    } else if (File(i) == 0) {
1060
      mask_pawn_connected[white][i] = SetMask(i + 1) | SetMask(i - 7);
1061
      mask_pawn_connected[black][i] = SetMask(i + 1) | SetMask(i + 9);
1062
    } else if (File(i) == 7) {
1063
      mask_pawn_connected[white][i] = SetMask(i - 1) | SetMask(i - 9);
1064
      mask_pawn_connected[black][i] = SetMask(i - 1) | SetMask(i + 7);
33 pmbaty 1065
    }
1066
  }
1067
/*
1068
 these masks are used to determine if the other side has any pawns
1069
 that can attack [square].
1070
 */
1071
  for (i = 8; i < 56; i++) {
1072
    if (!File(i)) {
108 pmbaty 1073
      mask_pattacks[white][i] = minus8dir[i + 1];
1074
      mask_pattacks[black][i] = plus8dir[i + 1];
33 pmbaty 1075
    } else if (File(i) == 7) {
108 pmbaty 1076
      mask_pattacks[white][i] = minus8dir[i - 1];
1077
      mask_pattacks[black][i] = plus8dir[i - 1];
33 pmbaty 1078
    } else {
108 pmbaty 1079
      mask_pattacks[white][i] = minus8dir[i - 1] | minus8dir[i + 1];
1080
      mask_pattacks[black][i] = plus8dir[i + 1] | plus8dir[i - 1];
33 pmbaty 1081
    }
1082
  }
1083
/*
1084
 enpassant pawns are on either file adjacent to the current file, and
1085
 on the same rank.
1086
 */
1087
  for (i = 0; i < 64; i++)
1088
    mask_eptest[i] = 0;
1089
  for (i = 25; i < 31; i++)
1090
    mask_eptest[i] = SetMask(i - 1) | SetMask(i + 1);
1091
  for (i = 33; i < 39; i++)
1092
    mask_eptest[i] = SetMask(i - 1) | SetMask(i + 1);
1093
  mask_eptest[A4] = SetMask(B4);
1094
  mask_eptest[H4] = SetMask(G4);
1095
  mask_eptest[A5] = SetMask(B5);
1096
  mask_eptest[H5] = SetMask(G5);
1097
/*
108 pmbaty 1098
 Initialize masks used to evaluate pawn races.  These masks are
33 pmbaty 1099
 used to determine if the opposing king is in a position to stop a
108 pmbaty 1100
 passed pawn from racing down and queening.  The data is organized
33 pmbaty 1101
 as pawn_race[side][onmove][square], where side is black or white,
108 pmbaty 1102
 and onmove indicates which side is to move for proper tempo
33 pmbaty 1103
 evaluation.
1104
 */
1105
  for (i = 0; i < 64; i++) {
1106
    pawn_race[white][white][i] = 0;
1107
    pawn_race[white][black][i] = 0;
1108
    pawn_race[black][white][i] = 0;
1109
    pawn_race[black][black][i] = 0;
1110
  }
1111
  for (j = 8; j < 56; j++) {
1112
    for (i = 0; i < 64; i++) {
1113
/* white pawn, wtm */
1114
      if (j < 16) {
1115
        if (KingPawnSquare(j + 8, i, File(j) + 56, 1))
1116
          pawn_race[white][white][j] |= SetMask(i);
1117
      } else {
1118
        if (KingPawnSquare(j, i, File(j) + 56, 1))
1119
          pawn_race[white][white][j] |= SetMask(i);
1120
      }
1121
/* white pawn, btm */
1122
      if (j < 16) {
1123
        if (KingPawnSquare(j + 8, i, File(j) + 56, 0))
1124
          pawn_race[white][black][j] |= SetMask(i);
1125
      } else {
1126
        if (KingPawnSquare(j, i, File(j) + 56, 0))
1127
          pawn_race[white][black][j] |= SetMask(i);
1128
      }
1129
/* black pawn, wtm */
1130
      if (j > 47) {
1131
        if (KingPawnSquare(j - 8, i, File(j), 0))
1132
          pawn_race[black][white][j] |= SetMask(i);
1133
      } else {
1134
        if (KingPawnSquare(j, i, File(j), 0))
1135
          pawn_race[black][white][j] |= SetMask(i);
1136
      }
1137
/* black pawn, btm */
1138
      if (j > 47) {
1139
        if (KingPawnSquare(j - 8, i, File(j), 1))
1140
          pawn_race[black][black][j] |= SetMask(i);
1141
      } else {
1142
        if (KingPawnSquare(j, i, File(j), 1))
1143
          pawn_race[black][black][j] |= SetMask(i);
1144
      }
1145
    }
1146
  }
108 pmbaty 1147
}
1148
 
33 pmbaty 1149
/*
108 pmbaty 1150
 *******************************************************************************
1151
 *                                                                             *
1152
 *   InitializeReductions() is used to initialize the reduction matrix used to *
1153
 *   set the reduction value for LMR for each move searched.  It is indexed by *
1154
 *   depth remaining and # moves searched.                                     *
1155
 *                                                                             *
1156
 *******************************************************************************
33 pmbaty 1157
 */
108 pmbaty 1158
void InitializeReductions() {
1159
  int d, m;
33 pmbaty 1160
 
108 pmbaty 1161
  for (d = 0; d < 32; d++)
1162
    for (m = 0; m < 64; m++)
1163
      LMR[d][m] = 0;
1164
  for (d = 3; d < 32; d++)
1165
    for (m = 1; m < 64; m++) {
1166
      LMR[d][m] = (uint8_t) // Pierre-Marie Baty -- added type cast
1167
          Max(Min(log(d * LMR_db) * log(m * LMR_mb) / LMR_s, LMR_max),
1168
          LMR_min);
1169
      LMR[d][m] = Min(LMR[d][m], Max(d - 1 - LMR_rdepth, 0));
33 pmbaty 1170
    }
1171
}
1172
 
1173
/*
1174
 *******************************************************************************
1175
 *                                                                             *
1176
 *   InitlializeSMP() is used to initialize the pthread lock variables.        *
1177
 *                                                                             *
1178
 *******************************************************************************
1179
 */
1180
void InitializeSMP(void) {
1181
  LockInit(lock_smp);
1182
  LockInit(lock_io);
1183
  LockInit(block[0]->lock);
1184
#if defined(UNIX) && (CPUS > 1)
1185
  pthread_attr_init(&attributes);
1186
  pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED);
1187
#endif
1188
}