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 19... Line 19...
19
 *                                                                             *
19
 *                                                                             *
20
 *   64 bits:  hash key for this position.                                     *
20
 *   64 bits:  hash key for this position.                                     *
21
 *                                                                             *
21
 *                                                                             *
22
 *    8 bits:  flag bits defined as  follows:                                  *
22
 *    8 bits:  flag bits defined as  follows:                                  *
23
 *                                                                             *
23
 *                                                                             *
24
 *      0000 0001  ?? flagged move                       (0x01)                *
24
 *        0000 0001  ?? flagged move                         (0x01)            *
25
 *      0000 0010   ? flagged move                       (0x02)                *
25
 *        0000 0010   ? flagged move                         (0x02)            *
26
 *      0000 0100   = flagged move                       (0x04)                *
26
 *        0000 0100   = flagged move                         (0x04)            *
27
 *      0000 1000   ! flagged move                       (0x08)                *
27
 *        0000 1000   ! flagged move                         (0x08)            *
28
 *      0001 0000  !! flagged move                       (0x10)                *
28
 *        0001 0000  !! flagged move                         (0x10)            *
29
 *      0010 0000     black won at least 1 game          (0x20)                *
29
 *        0010 0000     black won at least 1 game            (0x20)            *
30
 *      0100 0000     at least one game was drawn        (0x40)                *
30
 *        0100 0000     at least one game was drawn          (0x40)            *
31
 *      1000 0000     white won at least 1 game          (0x80)                *
31
 *        1000 0000     white won at least 1 game            (0x80)            *
32
 *                                                                             *
32
 *                                                                             *
33
 *   24 bits:  number of games this move was played.                           *
33
 *   24 bits:  number of games this move was played.                           *
34
 *                                                                             *
34
 *                                                                             *
35
 *   32 bits:  learned value (floating point).                                 *
35
 *   32 bits:  learned value (floating point).                                 *
36
 *                                                                             *
36
 *                                                                             *
Line 38... Line 38...
38
 *                                                                             *
38
 *                                                                             *
39
 *******************************************************************************
39
 *******************************************************************************
40
 */
40
 */
41
#define BAD_MOVE  0x02
41
#define BAD_MOVE  0x02
42
#define GOOD_MOVE 0x08
42
#define GOOD_MOVE 0x08
43
int Book(TREE * RESTRICT tree, int wtm, int root_list_done) {
43
int Book(TREE * RESTRICT tree, int wtm) {
44
  static int book_moves[200];
44
  static int book_moves[200];
45
  static BOOK_POSITION start_moves[200];
45
  static BOOK_POSITION start_moves[200];
46
  static uint64_t selected_key[200];
46
  static uint64_t selected_key[200];
47
  static int selected[200];
47
  static int selected[200];
48
  static int selected_order_played[200];
48
  static int selected_order_played[200], selected_value[200];
49
  static float selected_value[200]; // Pierre-Marie Baty -- fixed type
-
 
50
  static int selected_status[200], selected_percent[200],
49
  static int selected_status[200], selected_percent[200],
51
      book_development[200];
50
      book_development[200];
52
  static int bs_played[200], bs_percent[200];
51
  static int bs_played[200], bs_percent[200];
53
  static int book_status[200], evaluations[200], bs_learn[200];
52
  static int book_status[200], evaluations[200], bs_learn[200];
54
  static float bs_value[200], total_value;
53
  static float bs_value[200], total_value;
Line 56... Line 55...
56
  int m1_status, forced = 0, total_percent, play_percentage = 0;
55
  int m1_status, forced = 0, total_percent, play_percentage = 0;
57
  float tempr;
56
  float tempr;
58
  int done, i, j, last_move, temp, which, minlv = 999999, maxlv = -999999;
57
  int done, i, j, last_move, temp, which, minlv = 999999, maxlv = -999999;
59
  int maxp = -999999, minev = 999999, maxev = -999999;
58
  int maxp = -999999, minev = 999999, maxev = -999999;
60
  int nflagged, im, value, np, book_ponder_move;
59
  int nflagged, im, value, np, book_ponder_move;
61
  int cluster, scluster, test;
60
  int cluster, scluster, test, v;
62
  unsigned char buf32[4];
61
  unsigned char buf32[4];
63
  uint64_t temp_hash_key, common, tempk;
62
  uint64_t temp_hash_key, common, tempk;
64
  int key, nmoves, num_selected, st;
63
  int key, nmoves, num_selected, st;
65
  int percent_played, total_played, total_moves, smoves;
64
  int percent_played, total_played, total_moves, smoves;
66
  int distribution;
65
  int distribution;
Line 84... Line 83...
84
 *  each move found.  These will be used later to augment   *
83
 *  each move found.  These will be used later to augment   *
85
 *  the flags in the normal book to offer better control.   *
84
 *  the flags in the normal book to offer better control.   *
86
 *                                                          *
85
 *                                                          *
87
 ************************************************************
86
 ************************************************************
88
 */
87
 */
89
  if (!root_list_done)
-
 
90
    RootMoveList(wtm);
-
 
91
  test = HashKey >> 49;
88
  test = HashKey >> 49;
92
  smoves = 0;
89
  smoves = 0;
93
  if (books_file) {
90
  if (books_file) {
94
    fseek(books_file, test * sizeof(int), SEEK_SET);
91
    fseek(books_file, test * sizeof(int), SEEK_SET);
95
    fread(buf32, 4, 1, books_file);
92
    v = fread(buf32, 4, 1, books_file);
-
 
93
    if (v <= 0)
-
 
94
      perror("Book() fread error: ");
96
    key = BookIn32(buf32);
95
    key = BookIn32(buf32);
97
    if (key > 0) {
96
    if (key > 0) {
98
      fseek(books_file, key, SEEK_SET);
97
      fseek(books_file, key, SEEK_SET);
99
      fread(buf32, 4, 1, books_file);
98
      v = fread(buf32, 4, 1, books_file);
-
 
99
      if (v <= 0)
-
 
100
        perror("Book() fread error: ");
100
      scluster = BookIn32(buf32);
101
      scluster = BookIn32(buf32);
-
 
102
      if (scluster)
101
      BookClusterIn(books_file, scluster, book_buffer);
103
        BookClusterIn(books_file, scluster, book_buffer);
102
      for (im = 0; im < n_root_moves; im++) {
104
      for (im = 0; im < n_root_moves; im++) {
103
        common = HashKey & ((uint64_t) 65535 << 48);
105
        common = HashKey & ((uint64_t) 65535 << 48);
104
        MakeMove(tree, 1, root_moves[im].move, wtm);
106
        MakeMove(tree, 1, wtm, root_moves[im].move);
105
        if (Repeat(tree, 2)) {
107
        if (Repeat(tree, 2)) {
106
          UnmakeMove(tree, 1, root_moves[im].move, wtm);
108
          UnmakeMove(tree, 1, wtm, root_moves[im].move);
107
          return 0;
109
          return 0;
108
        }
110
        }
109
        temp_hash_key = (wtm) ? HashKey : ~HashKey;
111
        temp_hash_key = (wtm) ? HashKey : ~HashKey;
110
        temp_hash_key = (temp_hash_key & ~((uint64_t) 65535 << 48)) | common;
112
        temp_hash_key = (temp_hash_key & ~((uint64_t) 65535 << 48)) | common;
111
        for (i = 0; i < scluster; i++)
113
        for (i = 0; i < scluster; i++)
112
          if (!(temp_hash_key ^ book_buffer[i].position)) {
114
          if (!(temp_hash_key ^ book_buffer[i].position)) {
113
            start_moves[smoves++] = book_buffer[i];
115
            start_moves[smoves++] = book_buffer[i];
114
            break;
116
            break;
115
          }
117
          }
116
        UnmakeMove(tree, 1, root_moves[im].move, wtm);
118
        UnmakeMove(tree, 1, wtm, root_moves[im].move);
117
      }
119
      }
118
    }
120
    }
119
  }
121
  }
120
/*
122
/*
121
 ************************************************************
123
 ************************************************************
Line 128... Line 130...
128
 ************************************************************
130
 ************************************************************
129
 */
131
 */
130
  test = HashKey >> 49;
132
  test = HashKey >> 49;
131
  if (book_file) {
133
  if (book_file) {
132
    fseek(book_file, test * sizeof(int), SEEK_SET);
134
    fseek(book_file, test * sizeof(int), SEEK_SET);
133
    fread(buf32, 4, 1, book_file);
135
    v = fread(buf32, 4, 1, book_file);
-
 
136
    if (v <= 0)
-
 
137
      perror("Book() fread error: ");
134
    key = BookIn32(buf32);
138
    key = BookIn32(buf32);
135
    if (key > 0) {
139
    if (key > 0) {
136
      book_learn_seekto = key;
140
      book_learn_seekto = key;
137
      fseek(book_file, key, SEEK_SET);
141
      fseek(book_file, key, SEEK_SET);
138
      fread(buf32, 4, 1, book_file);
142
      v = fread(buf32, 4, 1, book_file);
-
 
143
      if (v <= 0)
-
 
144
        perror("Book() fread error: ");
139
      cluster = BookIn32(buf32);
145
      cluster = BookIn32(buf32);
-
 
146
      if (cluster)
140
      BookClusterIn(book_file, cluster, book_buffer);
147
        BookClusterIn(book_file, cluster, book_buffer);
141
    } else
148
    } else
142
      cluster = 0;
149
      cluster = 0;
143
    if (!cluster && !smoves)
150
    if (!cluster && !smoves)
144
      return 0;
151
      return 0;
145
/*
152
/*
Line 170... Line 177...
170
 *  database.                                               *
177
 *  database.                                               *
171
 *                                                          *
178
 *                                                          *
172
 ************************************************************
179
 ************************************************************
173
 */
180
 */
174
    initial_development = tree->score_mg;
181
    initial_development = tree->score_mg;
175
    EvaluateDevelopment(tree, 1, wtm);
182
    EvaluateCastling(tree, 1, wtm);
176
    initial_development = tree->score_mg - initial_development;
183
    initial_development = tree->score_mg - initial_development;
177
    total_moves = 0;
184
    total_moves = 0;
178
    nmoves = 0;
185
    nmoves = 0;
179
    for (im = 0; im < n_root_moves; im++) {
186
    for (im = 0; im < n_root_moves; im++) {
180
      common = HashKey & ((uint64_t) 65535 << 48);
187
      common = HashKey & ((uint64_t) 65535 << 48);
181
      MakeMove(tree, 1, root_moves[im].move, wtm);
188
      MakeMove(tree, 1, wtm, root_moves[im].move);
182
      if (Repeat(tree, 2)) {
189
      if (Repeat(tree, 2)) {
183
        UnmakeMove(tree, 1, root_moves[im].move, wtm);
190
        UnmakeMove(tree, 1, wtm, root_moves[im].move);
184
        return 0;
191
        return 0;
185
      }
192
      }
186
      temp_hash_key = (wtm) ? HashKey : ~HashKey;
193
      temp_hash_key = (wtm) ? HashKey : ~HashKey;
187
      temp_hash_key = (temp_hash_key & ~((uint64_t) 65535 << 48)) | common;
194
      temp_hash_key = (temp_hash_key & ~((uint64_t) 65535 << 48)) | common;
188
      for (i = 0; i < cluster; i++) {
195
      for (i = 0; i < cluster; i++) {
Line 193... Line 200...
193
          if (puzzling)
200
          if (puzzling)
194
            bs_played[nmoves] += 1;
201
            bs_played[nmoves] += 1;
195
          tree->curmv[1] = root_moves[im].move;
202
          tree->curmv[1] = root_moves[im].move;
196
          if (!Captured(root_moves[im].move)) {
203
          if (!Captured(root_moves[im].move)) {
197
            book_development[nmoves] = tree->score_mg;
204
            book_development[nmoves] = tree->score_mg;
198
            EvaluateDevelopment(tree, 2, wtm);
205
            EvaluateCastling(tree, 2, wtm);
199
            book_development[nmoves] =
206
            book_development[nmoves] =
200
                tree->score_mg - book_development[nmoves];
207
                tree->score_mg - book_development[nmoves];
201
          } else
208
          } else
202
            book_development[nmoves] = 0;
209
            book_development[nmoves] = 0;
203
          total_moves += bs_played[nmoves];
210
          total_moves += bs_played[nmoves];
Line 215... Line 222...
215
          book_key[nmoves] = temp_hash_key;
222
          book_key[nmoves] = temp_hash_key;
216
          nmoves++;
223
          nmoves++;
217
          break;
224
          break;
218
        }
225
        }
219
      }
226
      }
220
      UnmakeMove(tree, 1, root_moves[im].move, wtm);
227
      UnmakeMove(tree, 1, wtm, root_moves[im].move);
221
    }
228
    }
222
    if (!nmoves)
229
    if (!nmoves)
223
      return 0;
230
      return 0;
224
    book_learn_nmoves = nmoves;
231
    book_learn_nmoves = nmoves;
225
/*
232
/*
Line 271... Line 278...
271
      }
278
      }
272
    }
279
    }
273
    maxp++;
280
    maxp++;
274
    for (i = 0; i < nmoves; i++) {
281
    for (i = 0; i < nmoves; i++) {
275
      bs_value[i] = 1;
282
      bs_value[i] = 1;
276
      bs_value[i] += bs_played[i] / (float) maxp * 1000.0f * book_weight_freq; // Pierre-Marie Baty -- added float suffix
283
      bs_value[i] += bs_played[i] / (float) maxp *1000.0f * book_weight_freq; // Pierre-Marie Baty -- added type cast
277
 
284
 
278
      if (minlv < maxlv)
285
      if (minlv < maxlv)
279
        bs_value[i] +=
286
        bs_value[i] +=
280
            (bs_learn[i] - minlv) / (float) (maxlv -
287
            (bs_learn[i] - minlv) / (float) (maxlv -
281
            minlv) * 1000.0f * book_weight_learn; // Pierre-Marie Baty -- added float suffix
288
            minlv) * 1000.0f * book_weight_learn; // Pierre-Marie Baty -- added type cast
282
      if (minev < maxev)
289
      if (minev < maxev)
283
        bs_value[i] +=
290
        bs_value[i] +=
284
            (evaluations[i] - minev) / (float) (Max(maxev - minev,
291
            (evaluations[i] - minev) / (float) (Max(maxev - minev,
285
                50)) * 1000.0f * book_weight_eval; // Pierre-Marie Baty -- added float suffix
292
                50)) * 1000.0f * book_weight_eval; // Pierre-Marie Baty -- added type cast
286
    }
293
    }
287
    total_played = total_moves;
294
    total_played = total_moves;
288
/*
295
/*
289
 ************************************************************
296
 ************************************************************
290
 *                                                          *
297
 *                                                          *
Line 316... Line 323...
316
        done = 1;
323
        done = 1;
317
        for (i = 0; i < nmoves - 1; i++) {
324
        for (i = 0; i < nmoves - 1; i++) {
318
          if (bs_percent[i] < bs_percent[i + 1]
325
          if (bs_percent[i] < bs_percent[i + 1]
319
              || (bs_percent[i] == bs_percent[i + 1]
326
              || (bs_percent[i] == bs_percent[i + 1]
320
                  && bs_value[i] < bs_value[i + 1])) {
327
                  && bs_value[i] < bs_value[i + 1])) {
321
            temp = bs_played[i]; // Pierre-Marie Baty -- the wrong variable type was used
328
            tempr = (float) bs_played[i]; // Pierre-Marie Baty -- added type cast (FIXME: ugly!)
322
            bs_played[i] = bs_played[i + 1];
329
            bs_played[i] = bs_played[i + 1];
323
            bs_played[i + 1] = temp;
330
            bs_played[i + 1] = (int) tempr; // Pierre-Marie Baty -- added type cast (FIXME: ugly!)
324
            tempr = bs_value[i];
331
            tempr = bs_value[i];
325
            bs_value[i] = bs_value[i + 1];
332
            bs_value[i] = bs_value[i + 1];
326
            bs_value[i + 1] = tempr;
333
            bs_value[i + 1] = tempr;
327
            temp = evaluations[i];
334
            temp = evaluations[i];
328
            evaluations[i] = evaluations[i + 1];
335
            evaluations[i] = evaluations[i + 1];
Line 356... Line 363...
356
 *  operator has requested it.                              *
363
 *  operator has requested it.                              *
357
 *                                                          *
364
 *                                                          *
358
 ************************************************************
365
 ************************************************************
359
 */
366
 */
360
    if (show_book) {
367
    if (show_book) {
361
      Print(128, "  after screening, the following moves can be played\n");
368
      Print(32, "  after screening, the following moves can be played\n");
362
      Print(128,
369
      Print(32,
363
          "  move     played    %%  score    learn    " "sortv   P%%  P\n");
370
          "  move     played    %%  score    learn    " "sortv   P%%  P\n");
364
      for (i = 0; i < nmoves; i++) {
371
      for (i = 0; i < nmoves; i++) {
365
        Print(128, "%6s", OutputMove(tree, book_moves[i], 1, wtm));
372
        Print(32, "%6s", OutputMove(tree, 1, wtm, book_moves[i]));
366
        st = book_status[i];
373
        st = book_status[i];
367
        if (st & 0x1f) {
374
        if (st & 0x1f) {
368
          if (st & 0x01)
375
          if (st & 0x01)
369
            Print(128, "??");
376
            Print(32, "??");
370
          else if (st & 0x02)
377
          else if (st & 0x02)
371
            Print(128, "? ");
378
            Print(32, "? ");
372
          else if (st & 0x04)
379
          else if (st & 0x04)
373
            Print(128, "= ");
380
            Print(32, "= ");
374
          else if (st & 0x08)
381
          else if (st & 0x08)
375
            Print(128, "! ");
382
            Print(32, "! ");
376
          else if (st & 0x10)
383
          else if (st & 0x10)
377
            Print(128, "!!");
384
            Print(32, "!!");
378
        } else
385
        } else
379
          Print(128, "  ");
386
          Print(32, "  ");
380
        Print(128, "   %6d", bs_played[i]);
387
        Print(32, "   %6d", bs_played[i]);
381
        Print(128, "  %3d", 100 * bs_played[i] / Max(total_moves, 1));
388
        Print(32, "  %3d", 100 * bs_played[i] / Max(total_moves, 1));
382
        Print(128, "%s", DisplayEvaluation(evaluations[i], wtm));
389
        Print(32, "%s", DisplayEvaluation(evaluations[i], wtm));
383
        Print(128, "%9.2f", (float) bs_learn[i] / 100.0);
390
        Print(32, "%9.2f", (float) bs_learn[i] / 100.0);
384
        Print(128, " %9.1f", bs_value[i]);
391
        Print(32, " %9.1f", bs_value[i]);
385
        Print(128, " %3d", bs_percent[i]);
392
        Print(32, " %3d", bs_percent[i]);
386
        if ((book_status[i] & book_accept_mask &&
393
        if ((book_status[i] & book_accept_mask &&
387
                !(book_status[i] & book_reject_mask))
394
                !(book_status[i] & book_reject_mask))
388
            || (!(book_status[i] & book_reject_mask) && (bs_percent[i]
395
            || (!(book_status[i] & book_reject_mask) && (bs_percent[i]
389
                    || book_status[i] & 0x18 || (wtm && book_status[i] & 0x80)
396
                    || book_status[i] & 0x18 || (wtm && book_status[i] & 0x80)
390
                    || (!wtm && book_status[i] & 0x20))))
397
                    || (!wtm && book_status[i] & 0x20))))
391
          Print(128, "  Y");
398
          Print(32, "  Y");
392
        else
399
        else
393
          Print(128, "  N");
400
          Print(32, "  N");
394
        Print(128, "\n");
401
        Print(32, "\n");
395
      }
402
      }
396
    }
403
    }
397
/*
404
/*
398
 ************************************************************
405
 ************************************************************
399
 *                                                          *
406
 *                                                          *
Line 420... Line 427...
420
    if (!play_percentage) {
427
    if (!play_percentage) {
421
      for (i = 0; i < nmoves; i++)
428
      for (i = 0; i < nmoves; i++)
422
        if (!(book_status[i] & 0x03) || bs_percent[i]) {
429
        if (!(book_status[i] & 0x03) || bs_percent[i]) {
423
          selected_status[num_selected] = book_status[i];
430
          selected_status[num_selected] = book_status[i];
424
          selected_order_played[num_selected] = bs_played[i];
431
          selected_order_played[num_selected] = bs_played[i];
425
          selected_value[num_selected] = bs_value[i];
432
          selected_value[num_selected] = (int) bs_value[i]; // Pierre-Marie Baty -- added type cast
426
          selected_percent[num_selected] = bs_percent[i];
433
          selected_percent[num_selected] = bs_percent[i];
427
          selected_key[num_selected] = book_key[i];
434
          selected_key[num_selected] = book_key[i];
428
          selected[num_selected++] = book_moves[i];
435
          selected[num_selected++] = book_moves[i];
429
        }
436
        }
430
    } else {
437
    } else {
431
      for (i = 0; i < nmoves; i++)
438
      for (i = 0; i < nmoves; i++)
432
        if (bs_percent[i]) {
439
        if (bs_percent[i]) {
433
          selected_status[num_selected] = book_status[i];
440
          selected_status[num_selected] = book_status[i];
434
          selected_order_played[num_selected] = bs_played[i];
441
          selected_order_played[num_selected] = bs_played[i];
435
          selected_value[num_selected] = bs_value[i];
442
          selected_value[num_selected] = (int) bs_value[i]; // Pierre-Marie Baty -- added type cast
436
          selected_percent[num_selected] = bs_percent[i];
443
          selected_percent[num_selected] = bs_percent[i];
437
          selected_key[num_selected] = book_key[i];
444
          selected_key[num_selected] = book_key[i];
438
          selected[num_selected++] = book_moves[i];
445
          selected[num_selected++] = book_moves[i];
439
        }
446
        }
440
    }
447
    }
441
    for (i = 0; i < num_selected; i++) {
448
    for (i = 0; i < num_selected; i++) {
442
      book_status[i] = selected_status[i];
449
      book_status[i] = selected_status[i];
443
      bs_played[i] = selected_order_played[i];
450
      bs_played[i] = selected_order_played[i];
444
      bs_value[i] = selected_value[i];
451
      bs_value[i] = (float) selected_value[i]; // Pierre-Marie Baty -- added type cast
445
      bs_percent[i] = selected_percent[i];
452
      bs_percent[i] = selected_percent[i];
446
      book_moves[i] = selected[i];
453
      book_moves[i] = selected[i];
447
    }
454
    }
448
    nmoves = num_selected;
455
    nmoves = num_selected;
449
/*
456
/*
Line 461... Line 468...
461
        if (!nmoves)
468
        if (!nmoves)
462
          break;
469
          break;
463
        sprintf(kibitz_text, "book moves (");
470
        sprintf(kibitz_text, "book moves (");
464
        kibitz_p = kibitz_text + strlen(kibitz_text);
471
        kibitz_p = kibitz_text + strlen(kibitz_text);
465
        for (i = 0; i < nmoves; i++) {
472
        for (i = 0; i < nmoves; i++) {
466
          sprintf(kibitz_p, "%s %d%%", OutputMove(tree, book_moves[i], 1,
473
          sprintf(kibitz_p, "%s %d%%", OutputMove(tree, 1, wtm,
467
                  wtm), 100 * bs_played[i] / Max(total_played, 1));
474
                  book_moves[i]), 100 * bs_played[i] / Max(total_played, 1));
468
          kibitz_p = kibitz_text + strlen(kibitz_text);
475
          kibitz_p = kibitz_text + strlen(kibitz_text);
469
          if (i < nmoves - 1) {
476
          if (i < nmoves - 1) {
470
            sprintf(kibitz_p, ", ");
477
            sprintf(kibitz_p, ", ");
471
            kibitz_p = kibitz_text + strlen(kibitz_text);
478
            kibitz_p = kibitz_text + strlen(kibitz_text);
472
          }
479
          }
Line 493... Line 500...
493
        for (i = 0; i < nmoves; i++)
500
        for (i = 0; i < nmoves; i++)
494
          if (book_status[i] & 16) {
501
          if (book_status[i] & 16) {
495
            forced = 1;
502
            forced = 1;
496
            selected_status[num_selected] = book_status[i];
503
            selected_status[num_selected] = book_status[i];
497
            selected_order_played[num_selected] = bs_played[i];
504
            selected_order_played[num_selected] = bs_played[i];
498
            selected_value[num_selected] = bs_value[i];
505
            selected_value[num_selected] = (int) bs_value[i]; // Pierre-Marie Baty -- added type cast
499
            selected_key[num_selected] = book_key[i];
506
            selected_key[num_selected] = book_key[i];
500
            selected[num_selected++] = book_moves[i];
507
            selected[num_selected++] = book_moves[i];
501
          }
508
          }
502
    if (!num_selected && !puzzling)
509
    if (!num_selected && !puzzling)
503
      if (book_accept_mask & 8)
510
      if (book_accept_mask & 8)
504
        for (i = 0; i < nmoves; i++)
511
        for (i = 0; i < nmoves; i++)
505
          if (book_status[i] & 8) {
512
          if (book_status[i] & 8) {
506
            forced = 1;
513
            forced = 1;
507
            selected_status[num_selected] = book_status[i];
514
            selected_status[num_selected] = book_status[i];
508
            selected_order_played[num_selected] = bs_played[i];
515
            selected_order_played[num_selected] = bs_played[i];
509
            selected_value[num_selected] = bs_value[i];
516
            selected_value[num_selected] = (int) bs_value[i]; // Pierre-Marie Baty -- added type cast
510
            selected_key[num_selected] = book_key[i];
517
            selected_key[num_selected] = book_key[i];
511
            selected[num_selected++] = book_moves[i];
518
            selected[num_selected++] = book_moves[i];
512
          }
519
          }
513
    if (!num_selected && !puzzling)
520
    if (!num_selected && !puzzling)
514
      if (book_accept_mask & 4)
521
      if (book_accept_mask & 4)
515
        for (i = 0; i < nmoves; i++)
522
        for (i = 0; i < nmoves; i++)
516
          if (book_status[i] & 4) {
523
          if (book_status[i] & 4) {
517
            selected_status[num_selected] = book_status[i];
524
            selected_status[num_selected] = book_status[i];
518
            selected_order_played[num_selected] = bs_played[i];
525
            selected_order_played[num_selected] = bs_played[i];
519
            selected_value[num_selected] = bs_value[i];
526
            selected_value[num_selected] = (int) bs_value[i]; // Pierre-Marie Baty -- added type cast
520
            selected_key[num_selected] = book_key[i];
527
            selected_key[num_selected] = book_key[i];
521
            selected[num_selected++] = book_moves[i];
528
            selected[num_selected++] = book_moves[i];
522
          }
529
          }
523
    if (!num_selected && !puzzling)
530
    if (!num_selected && !puzzling)
524
      for (i = 0; i < nmoves; i++)
531
      for (i = 0; i < nmoves; i++)
525
        if (book_status[i] & book_accept_mask) {
532
        if (book_status[i] & book_accept_mask) {
526
          selected_status[num_selected] = book_status[i];
533
          selected_status[num_selected] = book_status[i];
527
          selected_order_played[num_selected] = bs_played[i];
534
          selected_order_played[num_selected] = bs_played[i];
528
          selected_value[num_selected] = bs_value[i];
535
          selected_value[num_selected] = (int) bs_value[i]; // Pierre-Marie Baty -- added type cast
529
          selected_key[num_selected] = book_key[i];
536
          selected_key[num_selected] = book_key[i];
530
          selected[num_selected++] = book_moves[i];
537
          selected[num_selected++] = book_moves[i];
531
        }
538
        }
532
    if (!num_selected)
539
    if (!num_selected)
533
      for (i = 0; i < nmoves; i++) {
540
      for (i = 0; i < nmoves; i++) {
534
        selected_status[num_selected] = book_status[i];
541
        selected_status[num_selected] = book_status[i];
535
        selected_order_played[num_selected] = bs_played[i];
542
        selected_order_played[num_selected] = bs_played[i];
536
        selected_value[num_selected] = bs_value[i];
543
        selected_value[num_selected] = (int) bs_value[i]; // Pierre-Marie Baty -- added type cast
537
        selected_key[num_selected] = book_key[i];
544
        selected_key[num_selected] = book_key[i];
538
        selected[num_selected++] = book_moves[i];
545
        selected[num_selected++] = book_moves[i];
539
      }
546
      }
540
    if (!num_selected)
547
    if (!num_selected)
541
      return 0;
548
      return 0;
542
    for (i = 0; i < num_selected; i++) {
549
    for (i = 0; i < num_selected; i++) {
543
      book_status[i] = selected_status[i];
550
      book_status[i] = selected_status[i];
544
      book_moves[i] = selected[i];
551
      book_moves[i] = selected[i];
545
      bs_played[i] = selected_order_played[i];
552
      bs_played[i] = selected_order_played[i];
546
      bs_value[i] = selected_value[i];
553
      bs_value[i] = (float) selected_value[i]; // Pierre-Marie Baty -- added type cast
547
      bs_key[i] = selected_key[i];
554
      bs_key[i] = selected_key[i];
548
    }
555
    }
549
    nmoves = num_selected;
556
    nmoves = num_selected;
550
    if (nmoves == 0)
557
    if (nmoves == 0)
551
      return 0;
558
      return 0;
552
    Print(128, "               book moves {");
559
    Print(32, "               book moves {");
553
    for (i = 0; i < nmoves; i++) {
560
    for (i = 0; i < nmoves; i++) {
554
      Print(128, "%s", OutputMove(tree, book_moves[i], 1, wtm));
561
      Print(32, "%s", OutputMove(tree, 1, wtm, book_moves[i]));
555
      if (i < nmoves - 1)
562
      if (i < nmoves - 1)
556
        Print(128, ", ");
563
        Print(32, ", ");
557
    }
564
    }
558
    Print(128, "}\n");
565
    Print(32, "}\n");
559
    nflagged = 0;
566
    nflagged = 0;
560
    for (i = 0; i < nmoves; i++)
567
    for (i = 0; i < nmoves; i++)
561
      if (book_status[i] & 8)
568
      if (book_status[i] & 8)
562
        nflagged++;
569
        nflagged++;
563
    nmoves = Max(Min(nmoves, book_selection_width), nflagged);
570
    nmoves = Max(Min(nmoves, book_selection_width), nflagged);
564
    if (show_book) {
571
    if (show_book) {
565
      Print(128, "               moves considered {");
572
      Print(32, "               moves considered {");
566
      for (i = 0; i < nmoves; i++) {
573
      for (i = 0; i < nmoves; i++) {
567
        Print(128, "%s", OutputMove(tree, book_moves[i], 1, wtm));
574
        Print(32, "%s", OutputMove(tree, 1, wtm, book_moves[i]));
568
        if (i < nmoves - 1)
575
        if (i < nmoves - 1)
569
          Print(128, ", ");
576
          Print(32, ", ");
570
      }
577
      }
571
      Print(128, "}\n");
578
      Print(32, "}\n");
572
    }
579
    }
573
/*
580
/*
574
 ************************************************************
581
 ************************************************************
575
 *                                                          *
582
 *                                                          *
576
 *  We have the book moves, if any have specified percents  *
583
 *  We have the book moves, if any have specified percents  *
Line 590... Line 597...
590
      total_value = 1000.0;
597
      total_value = 1000.0;
591
    total_percent = (total_percent > 99) ? 99 : total_percent;
598
    total_percent = (total_percent > 99) ? 99 : total_percent;
592
    for (i = 0; i < nmoves; i++)
599
    for (i = 0; i < nmoves; i++)
593
      if (bs_percent[i])
600
      if (bs_percent[i])
594
        bs_value[i] =
601
        bs_value[i] =
595
            total_value / (1.0f -
602
            total_value / (1.0f - // Pierre-Marie Baty -- added type cast
596
            (float) total_percent / 100.0f) * (float) bs_percent[i] / 100.0f; // Pierre-Marie Baty -- added float suffixes
603
            (float) total_percent / 100.0f) * (float) bs_percent[i] / 100.0f; // Pierre-Marie Baty -- added type casts
597
/*
604
/*
598
 ************************************************************
605
 ************************************************************
599
 *                                                          *
606
 *                                                          *
600
 *  Display the book moves, and total counts, etc. if the   *
607
 *  Display the book moves, and total counts, etc. if the   *
601
 *  operator has requested it.                              *
608
 *  operator has requested it.                              *
602
 *                                                          *
609
 *                                                          *
603
 ************************************************************
610
 ************************************************************
604
 */
611
 */
605
    if (show_book) {
612
    if (show_book) {
606
      Print(128, "  move     played    %%  score     sortv  P%%  P\n");
613
      Print(32, "  move     played    %%  score     sortv  P%%  P\n");
607
      for (i = 0; i < nmoves; i++) {
614
      for (i = 0; i < nmoves; i++) {
608
        Print(128, "%6s", OutputMove(tree, book_moves[i], 1, wtm));
615
        Print(32, "%6s", OutputMove(tree, 1, wtm, book_moves[i]));
609
        st = book_status[i];
616
        st = book_status[i];
610
        if (st & 0x1f) {
617
        if (st & 0x1f) {
611
          if (st & 0x01)
618
          if (st & 0x01)
612
            Print(128, "??");
619
            Print(32, "??");
613
          else if (st & 0x02)
620
          else if (st & 0x02)
614
            Print(128, "? ");
621
            Print(32, "? ");
615
          else if (st & 0x04)
622
          else if (st & 0x04)
616
            Print(128, "= ");
623
            Print(32, "= ");
617
          else if (st & 0x08)
624
          else if (st & 0x08)
618
            Print(128, "! ");
625
            Print(32, "! ");
619
          else if (st & 0x10)
626
          else if (st & 0x10)
620
            Print(128, "!!");
627
            Print(32, "!!");
621
        } else
628
        } else
622
          Print(128, "  ");
629
          Print(32, "  ");
623
        Print(128, "   %6d", bs_played[i]);
630
        Print(32, "   %6d", bs_played[i]);
624
        Print(128, "  %3d", 100 * bs_played[i] / Max(total_moves, 1));
631
        Print(32, "  %3d", 100 * bs_played[i] / Max(total_moves, 1));
625
        Print(128, "%s", DisplayEvaluation(evaluations[i], wtm));
632
        Print(32, "%s", DisplayEvaluation(evaluations[i], wtm));
626
        Print(128, " %9.1f", bs_value[i]);
633
        Print(32, " %9.1f", bs_value[i]);
627
        Print(128, " %3d", bs_percent[i]);
634
        Print(32, " %3d", bs_percent[i]);
628
        if ((book_status[i] & book_accept_mask &&
635
        if ((book_status[i] & book_accept_mask &&
629
                !(book_status[i] & book_reject_mask))
636
                !(book_status[i] & book_reject_mask))
630
            || (!(book_status[i] & book_reject_mask) && ((wtm &&
637
            || (!(book_status[i] & book_reject_mask) && ((wtm &&
631
                        book_status[i] & 0x80) || (!wtm &&
638
                        book_status[i] & 0x80) || (!wtm &&
632
                        book_status[i] & 0x20))))
639
                        book_status[i] & 0x20))))
633
          Print(128, "  Y");
640
          Print(32, "  Y");
634
        else
641
        else
635
          Print(128, "  N");
642
          Print(32, "  N");
636
        Print(128, "\n");
643
        Print(32, "\n");
637
      }
644
      }
638
    }
645
    }
639
/*
646
/*
640
 ************************************************************
647
 ************************************************************
641
 *                                                          *
648
 *                                                          *
Line 662... Line 669...
662
          if (value < -50) {
669
          if (value < -50) {
663
            last_pv.pathd = 0;
670
            last_pv.pathd = 0;
664
            return 0;
671
            return 0;
665
          }
672
          }
666
        } else {
673
        } else {
667
          tree->pv[1].path[1] = book_moves[0];
674
          tree->pv[0].path[1] = book_moves[0];
668
          tree->pv[1].pathl = 2;
675
          tree->pv[0].pathl = 2;
669
          tree->pv[1].pathd = 0;
676
          tree->pv[0].pathd = 0;
670
        }
677
        }
671
        return 1;
678
        return 1;
672
      }
679
      }
673
    }
680
    }
674
/*
681
/*
Line 690... Line 697...
690
            root_moves[i].move = 0;
697
            root_moves[i].move = 0;
691
      for (i = 0, j = 0; i < n_root_moves; i++)
698
      for (i = 0, j = 0; i < n_root_moves; i++)
692
        if (root_moves[i].move != 0)
699
        if (root_moves[i].move != 0)
693
          root_moves[j++] = root_moves[i];
700
          root_moves[j++] = root_moves[i];
694
      n_root_moves = j;
701
      n_root_moves = j;
695
      Print(128, "               moves considered {only non-book moves}\n");
702
      Print(32, "               moves considered {only non-book moves}\n");
696
      nmoves = j;
703
      nmoves = j;
697
      if (nmoves > 1) {
704
      if (nmoves > 1) {
698
        last_pv.pathd = 0;
705
        last_pv.pathd = 0;
699
        booking = 1;
706
        booking = 1;
700
        (void) Iterate(wtm, booking, 1);
707
        Iterate(wtm, booking, 1);
701
        booking = 0;
708
        booking = 0;
702
      } else {
709
      } else {
703
        tree->pv[1].path[1] = book_moves[0];
710
        tree->pv[0].path[1] = book_moves[0];
704
        tree->pv[1].pathl = 2;
711
        tree->pv[0].pathl = 2;
705
        tree->pv[1].pathd = 0;
712
        tree->pv[0].pathd = 0;
706
      }
713
      }
707
      return 1;
714
      return 1;
708
    }
715
    }
709
    last_move = nmoves;
716
    last_move = nmoves;
710
/*
717
/*
Line 735... Line 742...
735
        distribution -= (int) (bs_value[which] * bs_value[which]); // Pierre-Marie Baty -- added type cast
742
        distribution -= (int) (bs_value[which] * bs_value[which]); // Pierre-Marie Baty -- added type cast
736
      if (distribution < 0)
743
      if (distribution < 0)
737
        break;
744
        break;
738
    }
745
    }
739
    which = Min(which, last_move - 1);
746
    which = Min(which, last_move - 1);
740
    tree->pv[1].path[1] = book_moves[which];
747
    tree->pv[0].path[1] = book_moves[which];
741
    percent_played = 100 * bs_played[which] / Max(total_played, 1);
748
    percent_played = 100 * bs_played[which] / Max(total_played, 1);
742
    total_played = bs_played[which];
749
    total_played = bs_played[which];
743
    m1_status = book_status[which];
750
    m1_status = book_status[which];
744
    tree->pv[1].pathl = 2;
751
    tree->pv[0].pathl = 2;
745
    tree->pv[1].pathd = 0;
752
    tree->pv[0].pathd = 0;
746
    if (mode != tournament_mode) {
753
    if (mode != tournament_mode) {
747
      MakeMove(tree, 1, book_moves[which], wtm);
754
      MakeMove(tree, 1, wtm, book_moves[which]);
748
      if ((book_ponder_move = BookPonderMove(tree, Flip(wtm)))) {
755
      if ((book_ponder_move = BookPonderMove(tree, Flip(wtm)))) {
749
        tree->pv[1].path[2] = book_ponder_move;
756
        tree->pv[0].path[2] = book_ponder_move;
750
        tree->pv[1].pathl = 3;
757
        tree->pv[0].pathl = 3;
751
      }
758
      }
752
      UnmakeMove(tree, 1, book_moves[which], wtm);
759
      UnmakeMove(tree, 1, wtm, book_moves[which]);
753
    }
760
    }
754
    book_learn_key = bs_key[which];
761
    book_learn_key = bs_key[which];
755
    Print(128, "               book   0.0s    %3d%%   ", percent_played);
762
    Print(32, "               book   0.0s    %3d%%   ", percent_played);
756
    Print(128, " %s", OutputMove(tree, tree->pv[1].path[1], 1, wtm));
763
    Print(32, " %s", OutputMove(tree, 1, wtm, tree->pv[0].path[1]));
757
    st = m1_status & book_accept_mask & (~224);
764
    st = m1_status & book_accept_mask & (~224);
758
    if (st) {
765
    if (st) {
759
      if (st & 1)
766
      if (st & 1)
760
        Print(128, "??");
767
        Print(32, "??");
761
      else if (st & 2)
768
      else if (st & 2)
762
        Print(128, "?");
769
        Print(32, "?");
763
      else if (st & 4)
770
      else if (st & 4)
764
        Print(128, "=");
771
        Print(32, "=");
765
      else if (st & 8)
772
      else if (st & 8)
766
        Print(128, "!");
773
        Print(32, "!");
767
      else if (st & 16)
774
      else if (st & 16)
768
        Print(128, "!!");
775
        Print(32, "!!");
769
    }
776
    }
770
    MakeMove(tree, 1, tree->pv[1].path[1], wtm);
777
    MakeMove(tree, 1, wtm, tree->pv[0].path[1]);
771
    if (tree->pv[1].pathl > 2)
778
    if (tree->pv[0].pathl > 2)
772
      Print(128, " %s", OutputMove(tree, tree->pv[1].path[2], 2, Flip(wtm)));
779
      Print(32, " %s", OutputMove(tree, 2, Flip(wtm), tree->pv[0].path[2]));
773
    UnmakeMove(tree, 1, tree->pv[1].path[1], wtm);
780
    UnmakeMove(tree, 1, wtm, tree->pv[0].path[1]);
774
    Print(128, "\n");
781
    Print(32, "\n");
775
    return 1;
782
    return 1;
776
  }
783
  }
777
  return 0;
784
  return 0;
778
}
785
}
779
 
786
 
Line 789... Line 796...
789
 *                                                                             *
796
 *                                                                             *
790
 *******************************************************************************
797
 *******************************************************************************
791
 */
798
 */
792
int BookPonderMove(TREE * RESTRICT tree, int wtm) {
799
int BookPonderMove(TREE * RESTRICT tree, int wtm) {
793
  uint64_t temp_hash_key, common;
800
  uint64_t temp_hash_key, common;
794
  static int book_moves[200];
801
  static unsigned book_moves[200];
795
  int i, key, *lastm, cluster, n_moves, im, played, tplayed;
802
  int i, v, key, cluster, n_moves, im, played, tplayed;
-
 
803
  unsigned *lastm;
796
  int book_ponder_move = 0, test;
804
  int book_ponder_move = 0, test;
797
  unsigned char buf32[4];
805
  unsigned char buf32[4];
798
 
806
 
799
/*
807
/*
800
 ************************************************************
808
 ************************************************************
Line 807... Line 815...
807
 ************************************************************
815
 ************************************************************
808
 */
816
 */
809
  if (book_file) {
817
  if (book_file) {
810
    test = HashKey >> 49;
818
    test = HashKey >> 49;
811
    fseek(book_file, test * sizeof(int), SEEK_SET);
819
    fseek(book_file, test * sizeof(int), SEEK_SET);
812
    fread(buf32, 4, 1, book_file);
820
    v = fread(buf32, 4, 1, book_file);
-
 
821
    if (v <= 0)
-
 
822
      perror("Book() fread error: ");
813
    key = BookIn32(buf32);
823
    key = BookIn32(buf32);
814
    if (key > 0) {
824
    if (key > 0) {
815
      fseek(book_file, key, SEEK_SET);
825
      fseek(book_file, key, SEEK_SET);
816
      fread(buf32, 4, 1, book_file);
826
      v = fread(buf32, 4, 1, book_file);
-
 
827
      if (v <= 0)
-
 
828
        perror("Book() fread error: ");
817
      cluster = BookIn32(buf32);
829
      cluster = BookIn32(buf32);
-
 
830
      if (cluster)
818
      BookClusterIn(book_file, cluster, book_buffer);
831
        BookClusterIn(book_file, cluster, book_buffer);
819
    } else
832
    } else
820
      cluster = 0;
833
      cluster = 0;
821
    if (!cluster)
834
    if (!cluster)
822
      return 0;
835
      return 0;
823
    lastm = GenerateCaptures(tree, 2, wtm, book_moves);
836
    lastm = GenerateCaptures(tree, 2, wtm, book_moves);
Line 833... Line 846...
833
 ************************************************************
846
 ************************************************************
834
 */
847
 */
835
    played = -1;
848
    played = -1;
836
    for (im = 0; im < n_moves; im++) {
849
    for (im = 0; im < n_moves; im++) {
837
      common = HashKey & ((uint64_t) 65535 << 48);
850
      common = HashKey & ((uint64_t) 65535 << 48);
838
      MakeMove(tree, 2, book_moves[im], wtm);
851
      MakeMove(tree, 2, wtm, book_moves[im]);
839
      temp_hash_key = (wtm) ? HashKey : ~HashKey;
852
      temp_hash_key = (wtm) ? HashKey : ~HashKey;
840
      temp_hash_key = (temp_hash_key & ~((uint64_t) 65535 << 48)) | common;
853
      temp_hash_key = (temp_hash_key & ~((uint64_t) 65535 << 48)) | common;
841
      for (i = 0; i < cluster; i++) {
854
      for (i = 0; i < cluster; i++) {
842
        if (!(temp_hash_key ^ book_buffer[i].position)) {
855
        if (!(temp_hash_key ^ book_buffer[i].position)) {
843
          tplayed = book_buffer[i].status_played & 077777777;
856
          tplayed = book_buffer[i].status_played & 077777777;
Line 846... Line 859...
846
            book_ponder_move = book_moves[im];
859
            book_ponder_move = book_moves[im];
847
          }
860
          }
848
          break;
861
          break;
849
        }
862
        }
850
      }
863
      }
851
      UnmakeMove(tree, 2, book_moves[im], wtm);
864
      UnmakeMove(tree, 2, wtm, book_moves[im]);
852
    }
865
    }
853
  }
866
  }
854
  return book_ponder_move;
867
  return book_ponder_move;
855
}
868
}
856
 
869
 
857
/* last modified 05/08/14 */
870
/* last modified 05/08/14 */
858
/*
871
/*
859
 *******************************************************************************
872
 *******************************************************************************
860
 *                                                                             *
873
 *                                                                             *
861
 *   BookUp() is used to create/add to the opening book file.  typing "<file>  *
874
 *   Bookup() is used to create/add to the opening book file.  typing "<file>  *
862
 *   create" will erase the old book file and start from scratch,              *
875
 *   create" will erase the old book file and start from scratch,              *
863
 *                                                                             *
876
 *                                                                             *
864
 *   The format of the input data is a left bracket ("[") followed by any title*
877
 *   The format of the input data is a left bracket ("[") followed by any      *
865
 *   information desired, followed by a right bracket ("]") followed by a      *
878
 *   title information desired, followed by a right bracket ("]") followed by  *
866
 *   sequence of moves.  The sequence of moves is assumed to start at ply=1,   *
879
 *   a sequence of moves.  The sequence of moves is assumed to start at ply=1, *
867
 *   with white-to-move (normal opening position) and can contain as many moves*
880
 *   with white-to-move (normal opening position) and can contain as many      *
868
 *   as desired (no limit on the depth of each variation.)  The file *must* be *
881
 *   moves as desired (no limit on the depth of each variation.)  The file     *
869
 *   terminated with a line that begins with "end", since handling the EOF     *
882
 *   *must* be terminated with a line that begins with "end", since handling   *
870
 *   condition makes portable code difficult.                                  *
883
 *   the EOF condition makes portable code difficult.                          *
871
 *                                                                             *
884
 *                                                                             *
872
 *   Book moves can either be typed in by hand, directly into book_add(), by   *
885
 *   Book moves can either be typed in by hand, directly into book_add(), by   *
873
 *   using the "book create/add" command.  Using the command "book add/create  *
886
 *   using the "book create/add" command.  Using the command "book add/create  *
874
 *   filename" will cause book_add() to read its opening text moves from       *
887
 *   filename" will cause book_add() to read its opening text moves from       *
875
 *   filename rather than from the keyboard                                    *
888
 *   filename rather than from the keyboard                                    *
876
 *                                                                             *
889
 *                                                                             *
877
 *   In addition to the normal text for a move (reduced or full algebraic is   *
890
 *   In addition to the normal text for a move (reduced or full algebraic is   *
878
 *   accepted, ie, e4, ed, exd4, e3d4, etc. are all acceptable) some special   *
891
 *   accepted, ie, e4, ed, exd4, e3d4, etc. are all acceptable) some special   *
879
 *   characters can be appended to a move.                                     *
892
 *   characters can be appended to a move.                                     *
880
 *                                                                             *
893
 *                                                                             *
881
 *      ?? ->  Never play this move.  since the same book is used for both     *
894
 *        ?? ->  Never play this move.  since the same book is used for both   *
882
 *             black and white, you can enter moves in that white might play,  *
895
 *               black and white, you can enter moves in that white might      *
883
 *             but prevent the program from choosing them on its own.          *
896
 *               play, but prevent the program from choosing them on its own.  *
884
 *      ?  ->  Avoid this move except for non-important games.  These openings *
897
 *        ?  ->  Avoid this move except for non-important games.  These        *
885
 *             are historically those that the program doesn't play very well, *
898
 *               openings are historically those that the program doesn't play *
886
 *             but which aren't outright losing.                               *
899
 *               very well, but which aren't outright losing.                  *
887
 *      =  ->  Drawish move, only play this move if drawish moves are allowed  *
900
 *        =  ->  Drawish move, only play this move if drawish moves are        *
888
 *             by the operator.  This is used to encourage the program to play *
901
 *               allowed by the operator.  This is used to encourage the       *
889
 *             drawish openings (Petrov's comes to mind) when the program needs*
902
 *               program to play drawish openings (Petrov's comes to mind)     *
890
 *             to draw or is facing a formidable opponent (deep thought comes  *
903
 *               when the program needs to draw or is facing a formidable      *
891
 *             to mind.)                                                       *
904
 *               opponent (deep thought comes to mind.)                        *
892
 *      !  ->  Always play this move, if there isn't a move with the !! flag   *
905
 *        !  ->  Always play this move, if there isn't a move with the !! flag *
893
 *             set also.  This is a strong move, but not as strong as a !!     *
906
 *               set also.  This is a strong move, but not as strong as a !!   *
894
 *             move.                                                           *
907
 *               move.                                                         *
895
 *      !! ->  Always play this move.  This can be used to make the program    *
908
 *        !! ->  Always play this move.  This can be used to make the program  *
896
 *             favor particular lines, or to mark a strong move for certain    *
909
 *               favor particular lines, or to mark a strong move for certain  *
897
 *             opening traps.                                                  *
910
 *               opening traps.                                                *
898
 *                                                                             *
911
 *                                                                             *
899
 *  {Play nn%} is used to force this specific book move to be played a specific*
912
 *  {Play nn%} is used to force this specific book move to be played a         *
900
 *             percentage of the time, and override the frequency of play that *
913
 *  specific percentage of the time, and override the frequency of play that   *
901
 *             comes from the large pgn database.                              *
914
 *               comes from the large pgn database.                            *
902
 *                                                                             *
915
 *                                                                             *
903
 *******************************************************************************
916
 *******************************************************************************
904
 */
917
 */
905
void BookUp(TREE * RESTRICT tree, int nargs, char **args) {
918
void Bookup(TREE * RESTRICT tree, int nargs, char **args) {
906
  BB_POSITION *bbuffer;
919
  BB_POSITION *bbuffer;
907
  uint64_t temp_hash_key, common;
920
  uint64_t temp_hash_key, common;
908
  FILE *book_input;
921
  FILE *book_input;
909
  char fname[128], start, *ch, output_filename[128];
922
  char fname[128], start, *ch, output_filename[128];
910
  static char schar[2] = { "." };
923
  static char schar[2] = { "." };
Line 1123... Line 1136...
1123
              if (move) {
1136
              if (move) {
1124
                ply++;
1137
                ply++;
1125
                max_search_depth = Max(max_search_depth, ply);
1138
                max_search_depth = Max(max_search_depth, ply);
1126
                total_moves++;
1139
                total_moves++;
1127
                common = HashKey & ((uint64_t) 65535 << 48);
1140
                common = HashKey & ((uint64_t) 65535 << 48);
1128
                MakeMove(tree, 2, move, wtm);
1141
                MakeMove(tree, 2, wtm, move);
1129
                tree->status[2] = tree->status[3];
1142
                tree->status[2] = tree->status[3];
1130
                if (ply <= max_ply) {
1143
                if (ply <= max_ply) {
1131
                  temp_hash_key = (wtm) ? HashKey : ~HashKey;
1144
                  temp_hash_key = (wtm) ? HashKey : ~HashKey;
1132
                  temp_hash_key =
1145
                  temp_hash_key =
1133
                      (temp_hash_key & ~((uint64_t) 65535 << 48)) | common;
1146
                      (temp_hash_key & ~((uint64_t) 65535 << 48)) | common;
Line 1172... Line 1185...
1172
                  if (Castle(0, black) < 0)
1185
                  if (Castle(0, black) < 0)
1173
                    Castle(0, black) = 0;
1186
                    Castle(0, black) = 0;
1174
                  strcpy(buffer, "savepos *");
1187
                  strcpy(buffer, "savepos *");
1175
                  twtm = game_wtm;
1188
                  twtm = game_wtm;
1176
                  game_wtm = wtm;
1189
                  game_wtm = wtm;
1177
                  (void) Option(tree);
1190
                  Option(tree);
1178
                  game_wtm = twtm;
1191
                  game_wtm = twtm;
1179
                  fprintf(pout, "%s\n", initial_position);
1192
                  fprintf(pout, "%s\n", initial_position);
1180
                  strcpy(initial_position, t_initial_position);
1193
                  strcpy(initial_position, t_initial_position);
1181
                  tree->status[0] = temp_pos;
1194
                  tree->status[0] = temp_pos;
1182
                }
1195
                }
Line 1226... Line 1239...
1226
      Print(4095, "Unable to malloc() index block, aborting\n");
1239
      Print(4095, "Unable to malloc() index block, aborting\n");
1227
      CraftyExit(1);
1240
      CraftyExit(1);
1228
    }
1241
    }
1229
    for (i = 0; i < 32768; i++)
1242
    for (i = 0; i < 32768; i++)
1230
      index[i] = -1;
1243
      index[i] = -1;
1231
    temp = BookUpNextPosition(files, 1);
1244
    temp = BookupNextPosition(files, 1);
1232
    memcpy((char *) &current.position, temp.position, 8);
1245
    memcpy((char *) &current.position, temp.position, 8);
1233
    current.status_played = temp.status << 24;
1246
    current.status_played = temp.status << 24;
1234
    if (start)
1247
    if (start)
1235
      current.status_played += temp.percent_play & 127;
1248
      current.status_played += temp.percent_play & 127;
1236
    current.learn = 0.0;
1249
    current.learn = 0.0;
Line 1254... Line 1267...
1254
    if (temp.status & 32 && !(temp.percent_play & 128))
1267
    if (temp.status & 32 && !(temp.percent_play & 128))
1255
      wins++;
1268
      wins++;
1256
    if (temp.status & 32 && temp.percent_play & 128)
1269
    if (temp.status & 32 && temp.percent_play & 128)
1257
      losses++;
1270
      losses++;
1258
    while (1) {
1271
    while (1) {
1259
      temp = BookUpNextPosition(files, 0);
1272
      temp = BookupNextPosition(files, 0);
1260
      memcpy((char *) &next.position, temp.position, 8);
1273
      memcpy((char *) &next.position, temp.position, 8);
1261
      next.status_played = temp.status << 24;
1274
      next.status_played = temp.status << 24;
1262
      if (start)
1275
      if (start)
1263
        next.status_played += temp.percent_play & 127;
1276
        next.status_played += temp.percent_play & 127;
1264
      next.learn = 0.0;
1277
      next.learn = 0.0;
Line 1292... Line 1305...
1292
              (void *) BookOut64(current.position), 8);
1305
              (void *) BookOut64(current.position), 8);
1293
          memcpy((void *) &book_buffer_char[0].status_played,
1306
          memcpy((void *) &book_buffer_char[0].status_played,
1294
              (void *) BookOut32(current.status_played), 4);
1307
              (void *) BookOut32(current.status_played), 4);
1295
          memcpy((void *) &book_buffer_char[0].learn,
1308
          memcpy((void *) &book_buffer_char[0].learn,
1296
              (void *) BookOut32((int) current.learn), 4); // Pierre-Marie Baty -- added type cast
1309
              (void *) BookOut32((int) current.learn), 4); // Pierre-Marie Baty -- added type cast
-
 
1310
          stat =
1297
          stat = fwrite(book_buffer_char, BOOK_POSITION_SIZE, 1, book_file);
1311
              fwrite(book_buffer_char, sizeof(BOOK_POSITION), 1, book_file);
1298
          if (stat != 1)
1312
          if (stat != 1)
1299
            Print(4095, "ERROR!  write failed, disk probably full.\n");
1313
            Print(4095, "ERROR!  write failed, disk probably full.\n");
1300
        } else if (played < min_played)
1314
        } else if (played < min_played)
1301
          discarded_mp++;
1315
          discarded_mp++;
1302
        else
1316
        else
Line 1417... Line 1431...
1417
void BookSort(BB_POSITION * buffer, int number, int fileno) {
1431
void BookSort(BB_POSITION * buffer, int number, int fileno) {
1418
  char fname[16];
1432
  char fname[16];
1419
  FILE *output_file;
1433
  FILE *output_file;
1420
  int stat;
1434
  int stat;
1421
 
1435
 
1422
  qsort((char *) buffer, number, sizeof(BB_POSITION), BookUpCompare);
1436
  qsort((char *) buffer, number, sizeof(BB_POSITION), BookupCompare);
1423
  sprintf(fname, "sort.%d", fileno);
1437
  sprintf(fname, "sort.%d", fileno);
1424
  if (!(output_file = fopen(fname, "wb+")))
1438
  if (!(output_file = fopen(fname, "wb+")))
1425
    printf("ERROR.  unable to open sort output file\n");
1439
    printf("ERROR.  unable to open sort output file\n");
1426
  stat = fwrite(buffer, sizeof(BB_POSITION), number, output_file);
1440
  stat = fwrite(buffer, sizeof(BB_POSITION), number, output_file);
1427
  if (stat != number)
1441
  if (stat != number)
Line 1431... Line 1445...
1431
 
1445
 
1432
/* last modified 02/23/14 */
1446
/* last modified 02/23/14 */
1433
/*
1447
/*
1434
 *******************************************************************************
1448
 *******************************************************************************
1435
 *                                                                             *
1449
 *                                                                             *
1436
 *   BookUpNextPosition() is the heart of the "merge" operation that is done   *
1450
 *   BookupNextPosition() is the heart of the "merge" operation that is done   *
1437
 *   after the chunks of the parsed/hashed move file are sorted.  This code    *
1451
 *   after the chunks of the parsed/hashed move file are sorted.  This code    *
1438
 *   opens the sort.n files, and returns the least (lexically) position key to *
1452
 *   opens the sort.n files, and returns the least (lexically) position key to *
1439
 *   counted/merged into the main book database.                               *
1453
 *   counted/merged into the main book database.                               *
1440
 *                                                                             *
1454
 *                                                                             *
1441
 *******************************************************************************
1455
 *******************************************************************************
1442
 */
1456
 */
1443
BB_POSITION BookUpNextPosition(int files, int init) {
1457
BB_POSITION BookupNextPosition(int files, int init) {
1444
  char fname[20];
1458
  char fname[20];
1445
  static FILE *input_file[100];
1459
  static FILE *input_file[100];
1446
  static BB_POSITION *buffer[100];
1460
  static BB_POSITION *buffer[100];
1447
  static int data_read[100], next[100];
1461
  static int data_read[100], next[100];
1448
  int i, used;
1462
  int i, used;
Line 1503... Line 1517...
1503
  } else
1517
  } else
1504
    next[used]++;
1518
    next[used]++;
1505
  return least;
1519
  return least;
1506
}
1520
}
1507
 
1521
 
1508
int BookUpCompare(const void *pos1, const void *pos2) {
1522
int BookupCompare(const void *pos1, const void *pos2) {
1509
  static uint64_t p1, p2;
1523
  static uint64_t p1, p2;
1510
 
1524
 
1511
  memcpy((char *) &p1, ((BB_POSITION *) pos1)->position, 8);
1525
  memcpy((char *) &p1, ((BB_POSITION *) pos1)->position, 8);
1512
  memcpy((char *) &p2, ((BB_POSITION *) pos2)->position, 8);
1526
  memcpy((char *) &p2, ((BB_POSITION *) pos2)->position, 8);
1513
  if (p1 < p2)
1527
  if (p1 < p2)