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 2... Line 2...
2
#include "data.h"
2
#include "data.h"
3
#include "epdglue.h"
3
#include "epdglue.h"
4
/* last modified 04/24/14 */
4
/* last modified 05/12/15 */
5
/*
5
/*
6
 *******************************************************************************
6
 *******************************************************************************
7
 *                                                                             *
7
 *                                                                             *
8
 *   Iterate() is the routine used to drive the iterated search.  It           *
8
 *   Iterate() is the routine used to drive the iterated search.  It           *
9
 *   repeatedly calls search, incrementing the search depth after each call,   *
9
 *   repeatedly calls search, incrementing the search depth after each call,   *
Line 40... Line 40...
40
 *                                                                             *
40
 *                                                                             *
41
 *******************************************************************************
41
 *******************************************************************************
42
 */
42
 */
43
int Iterate(int wtm, int search_type, int root_list_done) {
43
int Iterate(int wtm, int search_type, int root_list_done) {
44
  TREE *const tree = block[0];
44
  TREE *const tree = block[0];
-
 
45
  ROOT_MOVE temp_rm;
45
  int i, root_alpha, old_root_alpha, old_root_beta;
46
  int i, alpha, beta, current_rm = 0, force_print = 0;
46
  int value = 0, twtm, correct, correct_count;
47
  int value = 0, twtm, correct, correct_count, npc, cpl, max;
47
  char *fl_indicator, *fh_indicator;
48
  unsigned int idle_time;
-
 
49
  char buff[32];
48
#if (CPUS > 1)
50
#if (CPUS > 1)
49
#ifdef UNIX // Pierre-Marie Baty -- this variable is only used on UNIX
51
# if defined(UNIX) // Pierre-Marie Baty -- missing conditional macro
50
  pthread_t pt;
52
  pthread_t pt;
51
#endif // UNIX
53
# endif
52
#endif
54
#endif
53
 
55
 
54
/*
56
/*
55
 ************************************************************
57
 ************************************************************
56
 *                                                          *
58
 *                                                          *
Line 58... Line 60...
58
 *  we don't know whether we are searching for black or     *
60
 *  we don't know whether we are searching for black or     *
59
 *  white until we get to this point.                       *
61
 *  white until we get to this point.                       *
60
 *                                                          *
62
 *                                                          *
61
 ************************************************************
63
 ************************************************************
62
 */
64
 */
63
  if (wtm) {
-
 
64
    draw_score[0] = -abs_draw_score;
65
  draw_score[black] = (wtm) ? -abs_draw_score : abs_draw_score;
65
    draw_score[1] = abs_draw_score;
-
 
66
  } else {
-
 
67
    draw_score[0] = abs_draw_score;
-
 
68
    draw_score[1] = -abs_draw_score;
66
  draw_score[white] = (wtm) ? abs_draw_score : -abs_draw_score;
69
  }
-
 
70
#if defined(NODES)
67
#if defined(NODES)
71
  temp_search_nodes = search_nodes;
68
  temp_search_nodes = search_nodes;
72
#endif
69
#endif
73
/*
70
/*
74
 ************************************************************
71
 ************************************************************
75
 *                                                          *
72
 *                                                          *
76
 *  Initialize statistical counters and such.               *
73
 *  Initialize statistical counters and such.               *
77
 *                                                          *
74
 *                                                          *
78
 ************************************************************
75
 ************************************************************
79
 */
76
 */
80
  idle_time = 0;
-
 
81
  tree->curmv[0] = 0;
-
 
82
  abort_search = 0;
77
  abort_search = 0;
83
  book_move = 0;
78
  book_move = 0;
84
  program_start_time = ReadClock();
79
  program_start_time = ReadClock();
85
  start_time = ReadClock();
80
  start_time = ReadClock();
86
  root_wtm = wtm;
81
  root_wtm = wtm;
87
  kibitz_depth = 0;
82
  kibitz_depth = 0;
88
  tree->nodes_searched = 0;
83
  tree->nodes_searched = 0;
89
  tree->fail_highs = 0;
84
  tree->fail_highs = 0;
90
  tree->fail_high_first_move = 0;
85
  tree->fail_high_first_move = 0;
91
  parallel_splits = 0;
86
  parallel_splits = 0;
-
 
87
  parallel_splits_wasted = 0;
92
  parallel_aborts = 0;
88
  parallel_aborts = 0;
-
 
89
  parallel_joins = 0;
-
 
90
  for (i = 0; i < (int) smp_max_threads; i++) { // Pierre-Marie Baty -- added type cast
-
 
91
    thread[i].max_blocks = 0;
-
 
92
    thread[i].tree = 0;
-
 
93
    thread[i].idle = 0;
-
 
94
    thread[i].terminate = 0;
-
 
95
  }
-
 
96
  thread[0].tree = block[0];
93
  correct_count = 0;
97
  correct_count = 0;
94
  burp = 15 * 100;
98
  burp = 15 * 100;
95
  transposition_age = (transposition_age + 1) & 0x1ff;
99
  transposition_age = (transposition_age + 1) & 0x1ff;
96
  next_time_check = nodes_between_time_checks;
100
  next_time_check = nodes_between_time_checks;
97
  tree->evaluations = 0;
101
  tree->evaluations = 0;
98
  tree->egtb_probes = 0;
102
  tree->egtb_probes = 0;
99
  tree->egtb_probes_successful = 0;
103
  tree->egtb_hits = 0;
100
  tree->extensions_done = 0;
104
  tree->extensions_done = 0;
101
  tree->qchecks_done = 0;
105
  tree->qchecks_done = 0;
102
  tree->reductions_done = 0;
-
 
103
  tree->moves_fpruned = 0;
106
  tree->moves_fpruned = 0;
-
 
107
  tree->moves_mpruned = 0;
-
 
108
  for (i = 0; i < 16; i++) {
-
 
109
    tree->LMR_done[i] = 0;
-
 
110
    tree->null_done[i] = 0;
-
 
111
  }
104
  root_wtm = wtm;
112
  root_wtm = wtm;
105
/*
113
/*
106
 ************************************************************
114
 ************************************************************
107
 *                                                          *
115
 *                                                          *
108
 *  We do a quick check to see if this position has a known *
116
 *  We do a quick check to see if this position has a known *
Line 118... Line 126...
118
 *  (based on a normal search / evaluation but with a lower *
126
 *  (based on a normal search / evaluation but with a lower *
119
 *  time limit) from the book moves given.                  *
127
 *  time limit) from the book moves given.                  *
120
 *                                                          *
128
 *                                                          *
121
 ************************************************************
129
 ************************************************************
122
 */
130
 */
-
 
131
  if (!root_list_done)
-
 
132
    RootMoveList(wtm);
123
  if (booking || !Book(tree, wtm, root_list_done))
133
  if (booking || !Book(tree, wtm))
124
    do {
134
    do {
125
      if (abort_search)
135
      if (abort_search)
126
        break;
136
        break;
127
#if !defined(NOEGTB)
137
#if !defined(NOEGTB)
128
      if (EGTB_draw && !puzzling && swindle_mode)
138
      if (EGTB_draw && !puzzling && swindle_mode)
129
        EGTB_use = 0;
139
        EGTB_use = 0;
130
      else
140
      else
131
        EGTB_use = EGTBlimit;
141
        EGTB_use = EGTBlimit;
132
      if (EGTBlimit && !EGTB_use)
142
      if (EGTBlimit && !EGTB_use)
133
        Print(128, "Drawn at root, trying for swindle.\n");
143
        Print(32, "Drawn at root, trying for swindle.\n");
134
#endif
144
#endif
135
/*
145
/*
136
 ************************************************************
146
 ************************************************************
137
 *                                                          *
147
 *                                                          *
138
 *  The first action for a real search is to generate the   *
148
 *  The first action for a real search is to generate the   *
Line 149... Line 159...
149
 *  book random 0) which would have already inserted just   *
159
 *  book random 0) which would have already inserted just   *
150
 *  the moves that should be searched.                      *
160
 *  the moves that should be searched.                      *
151
 *                                                          *
161
 *                                                          *
152
 ************************************************************
162
 ************************************************************
153
 */
163
 */
154
      if (!root_list_done)
-
 
155
        RootMoveList(wtm);
-
 
156
      if (n_root_moves == 0) {
164
      if (n_root_moves == 0) {
157
        program_end_time = ReadClock();
165
        program_end_time = ReadClock();
158
        tree->pv[0].pathl = 0;
166
        tree->pv[0].pathl = 0;
159
        tree->pv[0].pathd = 0;
167
        tree->pv[0].pathd = 0;
160
        if (Check(wtm))
168
        if (Check(wtm))
161
          value = -(MATE - 1);
169
          value = -(MATE - 1);
162
        else
170
        else
163
          value = DrawScore(wtm);
171
          value = DrawScore(wtm);
164
        Print(6, "        depth     time       score   variation\n");
172
        Print(2, "        depth     time       score   variation\n");
165
        Print(6, "                                     (no moves)\n");
173
        Print(2, "                                     (no moves)\n");
166
        tree->nodes_searched = 1;
174
        tree->nodes_searched = 1;
167
        if (!puzzling)
175
        if (!puzzling)
168
          last_root_value = value;
176
          last_root_value = value;
169
        return value;
177
        return value;
170
      }
178
      }
Line 178... Line 186...
178
 *  by search.                                              *
186
 *  by search.                                              *
179
 *                                                          *
187
 *                                                          *
180
 ************************************************************
188
 ************************************************************
181
 */
189
 */
182
      TimeSet(search_type);
190
      TimeSet(search_type);
183
      iteration_depth = 1;
191
      iteration = 1;
184
      noise_block = 0;
192
      noise_block = 0;
-
 
193
      force_print = 0;
185
      if (last_pv.pathd > 1) {
194
      if (last_pv.pathd > 1) {
186
        iteration_depth = last_pv.pathd + 1;
195
        iteration = last_pv.pathd + 1;
187
        value = last_root_value;
196
        value = last_root_value;
188
        tree->pv[0] = last_pv;
197
        tree->pv[0] = last_pv;
-
 
198
        root_moves[0].path = tree->pv[0];
189
        noise_block = 1;
199
        noise_block = 1;
-
 
200
        force_print = 1;
190
      } else
201
      } else
191
        difficulty = 100;
202
        difficulty = 100;
192
      Print(6, "        depth     time       score   variation (%d)\n",
203
      Print(2, "        depth     time       score   variation (%d)\n",
193
          iteration_depth);
204
          iteration);
194
      abort_search = 0;
205
      abort_search = 0;
195
/*
206
/*
196
 ************************************************************
207
 ************************************************************
197
 *                                                          *
208
 *                                                          *
198
 *  Set the initial search bounds based on the last search  *
209
 *  Set the initial search bounds based on the last search  *
199
 *  or default values.                                      *
210
 *  or default values.                                      *
200
 *                                                          *
211
 *                                                          *
201
 ************************************************************
212
 ************************************************************
202
 */
213
 */
203
      tree->pv[0] = last_pv;
214
      tree->pv[0] = last_pv;
204
      if (iteration_depth > 1) {
215
      if (iteration > 1) {
205
        root_alpha = Max(-MATE, last_value - 16);
216
        alpha = Max(-MATE, last_value - 16);
206
        root_beta = Min(MATE, last_value + 16);
217
        beta = Min(MATE, last_value + 16);
207
      } else {
218
      } else {
208
        root_alpha = -MATE;
219
        alpha = -MATE;
209
        root_beta = MATE;
220
        beta = MATE;
210
      }
221
      }
211
/*
222
/*
212
 ************************************************************
223
 ************************************************************
213
 *                                                          *
224
 *                                                          *
214
 *  If we are using multiple threads, and they have not     *
225
 *  If we are using multiple threads, and they have not     *
215
 *  been started yet, then start them now as the search is  *
226
 *  been started yet, then start them now as the search is  *
216
 *  ready to begin.                                         *
227
 *  ready to begin.                                         *
-
 
228
 *                                                          *
-
 
229
 *  If we are using CPU affinity, we need to set this up    *
-
 
230
 *  for thread 0 since it could have changed since we       *
-
 
231
 *  initialized everything.                                 *
217
 *                                                          *
232
 *                                                          *
218
 ************************************************************
233
 ************************************************************
219
 */
234
 */
220
#if (CPUS > 1)
235
#if (CPUS > 1)
221
      if (smp_max_threads > smp_idle + 1) {
236
      if ((int) smp_max_threads > smp_threads + 1) { // Pierre-Marie Baty -- added type cast
222
        long proc;
237
        long proc;
223
 
238
 
224
        initialized_threads = 1;
239
        initialized_threads = 1;
225
        Print(128, "starting thread");
240
        Print(32, "starting thread");
226
        for (proc = smp_threads + 1; proc < smp_max_threads; proc++) {
241
        for (proc = smp_threads + 1; proc < (int) smp_max_threads; proc++) { // Pierre-Marie Baty -- added type cast
227
          Print(128, " %d", proc);
242
          Print(32, " %d", proc);
228
          thread[proc].tree = 0;
-
 
229
#  if defined(UNIX)
243
#  if defined(UNIX)
230
          pthread_create(&pt, &attributes, ThreadInit, (void *) proc);
244
          pthread_create(&pt, &attributes, ThreadInit, (void *) proc);
231
#  else
245
#  else
232
          NumaStartThread(ThreadInit, (void *) proc);
246
          NumaStartThread(ThreadInit, (void *) proc);
233
#  endif
247
#  endif
234
          smp_threads++;
248
          smp_threads++;
235
        }
249
        }
236
        Print(128, " <done>\n");
250
        Print(32, " <done>\n");
237
      }
251
      }
238
      WaitForAllThreadsInitialized();
252
      WaitForAllThreadsInitialized();
-
 
253
      ThreadAffinity(smp_affinity);
239
#endif
254
#endif
240
      if (search_nodes)
255
      if (search_nodes)
241
        nodes_between_time_checks = search_nodes;
256
        nodes_between_time_checks = (unsigned int) search_nodes; // Pierre-Marie Baty -- added type cast
242
      for (; iteration_depth <= MAXPLY - 5; iteration_depth++) {
-
 
243
/*
257
/*
244
 ************************************************************
258
 ************************************************************
245
 *                                                          *
259
 *                                                          *
-
 
260
 *  Main iterative-deepening loop starts here.  We either   *
-
 
261
 *  start at depth = 1, or if we are pondering and have a   *
-
 
262
 *  PV from the previous search, we use that to set the     *
-
 
263
 *  starting depth.                                         *
-
 
264
 *                                                          *
246
 *  Now install the old PV into the hash table so that      *
265
 *  First install the old PV into the hash table so that    *
247
 *  these moves will be followed first.  We do this since   *
266
 *  these moves will be searched first.  We do this since   *
248
 *  the last iteration done could have overwritten the PV   *
267
 *  the last iteration done could have overwritten the PV   *
249
 *  as the last few root moves were searched.               *
268
 *  as the last few root moves were searched.               *
250
 *                                                          *
269
 *                                                          *
251
 ************************************************************
270
 ************************************************************
252
 */
271
 */
-
 
272
      for (; iteration <= MAXPLY - 5; iteration++) {
253
        twtm = wtm;
273
        twtm = wtm;
254
        for (i = 1; i < (int) tree->pv[0].pathl; i++) {
274
        for (i = 1; i < (int) tree->pv[0].pathl; i++) {
255
          if (!VerifyMove(tree, i, twtm, tree->pv[0].path[i])) {
275
          if (!VerifyMove(tree, i, twtm, tree->pv[0].path[i])) {
256
            Print(4095, "ERROR, not installing bogus pv info at ply=%d\n", i);
276
            Print(2048, "ERROR, not installing bogus pv info at ply=%d\n", i);
257
            Print(4095, "not installing from=%d  to=%d  piece=%d\n",
277
            Print(2048, "not installing from=%d  to=%d  piece=%d\n",
258
                From(tree->pv[0].path[i]), To(tree->pv[0].path[i]),
278
                From(tree->pv[0].path[i]), To(tree->pv[0].path[i]),
259
                Piece(tree->pv[0].path[i]));
279
                Piece(tree->pv[0].path[i]));
260
            Print(4095, "pathlen=%d\n", tree->pv[0].pathl);
280
            Print(2048, "pathlen=%d\n", tree->pv[0].pathl);
261
            break;
281
            break;
262
          }
282
          }
263
          HashStorePV(tree, twtm, i);
283
          HashStorePV(tree, twtm, i);
264
          MakeMove(tree, i, tree->pv[0].path[i], twtm);
284
          MakeMove(tree, i, twtm, tree->pv[0].path[i]);
265
          twtm = Flip(twtm);
285
          twtm = Flip(twtm);
266
        }
286
        }
267
        for (i--; i > 0; i--) {
287
        for (i--; i > 0; i--) {
268
          twtm = Flip(twtm);
288
          twtm = Flip(twtm);
269
          UnmakeMove(tree, i, tree->pv[0].path[i], twtm);
289
          UnmakeMove(tree, i, twtm, tree->pv[0].path[i]);
270
        }
290
        }
271
/*
291
/*
272
 ************************************************************
292
 ************************************************************
273
 *                                                          *
293
 *                                                          *
274
 *  Now we call Search() and start the next search          *
294
 *  Now we call Search() and start the next search          *
Line 285... Line 305...
285
 *  of the clock unnecessarily.                             *
305
 *  of the clock unnecessarily.                             *
286
 *                                                          *
306
 *                                                          *
287
 ************************************************************
307
 ************************************************************
288
 */
308
 */
289
        if (trace_level) {
309
        if (trace_level) {
290
          printf("==================================\n");
310
          Print(32, "==================================\n");
291
          printf("=      search iteration %2d       =\n", iteration_depth);
311
          Print(32, "=      search iteration %2d       =\n", iteration);
292
          printf("==================================\n");
312
          Print(32, "==================================\n");
293
        }
313
        }
294
        if (tree->nodes_searched) {
314
        if (tree->nodes_searched) {
295
          nodes_between_time_checks = nodes_per_second / 10;
315
          nodes_between_time_checks =
-
 
316
              nodes_per_second / (10 * Max(smp_max_threads, 1));
296
          if (!analyze_mode) {
317
          if (!analyze_mode) {
297
            if (time_limit > 300);
318
            if (time_limit < 1000)
-
 
319
              nodes_between_time_checks /= 10;
298
            else if (time_limit > 50)
320
            if (time_limit < 100)
299
              nodes_between_time_checks /= 10;
321
              nodes_between_time_checks /= 10;
300
            else
-
 
301
              nodes_between_time_checks /= 100;
-
 
302
          } else
322
          } else
303
            nodes_between_time_checks = Min(nodes_per_second, 1000000);
323
            nodes_between_time_checks = Min(nodes_per_second, 1000000);
304
#if defined(SKILL)
-
 
305
          if (skill > 50)
-
 
306
            nodes_between_time_checks = Max(nodes_between_time_checks, 10000);
-
 
307
#endif
-
 
308
        }
324
        }
309
        if (search_nodes)
325
        if (search_nodes)
310
          nodes_between_time_checks = search_nodes - (unsigned int) tree->nodes_searched; // Pierre-Marie Baty -- added type cast (FIXME: either stay on 32 bits, or port correctly!)
326
          nodes_between_time_checks = (unsigned int) (search_nodes - tree->nodes_searched); // Pierre-Marie Baty -- added type cast
311
        nodes_between_time_checks =
327
        nodes_between_time_checks =
312
            Min(nodes_between_time_checks, MAX_TC_NODES);
328
            Min(nodes_between_time_checks, MAX_TC_NODES);
313
        next_time_check = nodes_between_time_checks;
329
        next_time_check = nodes_between_time_checks;
314
/*
330
/*
315
 ************************************************************
331
 ************************************************************
Line 323... Line 339...
323
 *                                                          *
339
 *                                                          *
324
 ************************************************************
340
 ************************************************************
325
 */
341
 */
326
        failhi_delta = 16;
342
        failhi_delta = 16;
327
        faillo_delta = 16;
343
        faillo_delta = 16;
-
 
344
        for (i = 0; i < n_root_moves; i++) {
-
 
345
          if (i || iteration == 1)
-
 
346
            root_moves[i].path.pathv = -99999999;
-
 
347
          root_moves[i].status &= 4;
-
 
348
        }
328
        while (1) {
349
        while (1) {
329
          thread[0].tree = block[0];
-
 
330
          tree->inchk[1] = Check(wtm);
-
 
331
          if (smp_max_threads > 1)
350
          if (smp_max_threads > 1)
332
            smp_split = 1;
351
            smp_split = 1;
333
          tree->rep_index--;
352
          rep_index--;
334
          value =
-
 
335
              Search(tree, root_alpha, root_beta, wtm, iteration_depth, 1, 0);
353
          value = Search(tree, 1, iteration, wtm, alpha, beta, Check(wtm), 0);
336
          tree->rep_index++;
354
          rep_index++;
337
          end_time = ReadClock();
355
          end_time = ReadClock();
338
          if (abort_search)
356
          if (abort_search)
339
            break;
357
            break;
-
 
358
          for (current_rm = 0; current_rm < n_root_moves; current_rm++)
340
          old_root_alpha = root_alpha;
359
            if (tree->pv[0].path[1] == root_moves[current_rm].move)
341
          old_root_beta = root_beta;
360
              break;
342
/*
361
/*
343
 ************************************************************
362
 ************************************************************
344
 *                                                          *
363
 *                                                          *
345
 *  Check for the case where we get a score back that is    *
364
 *  Check for the case where we get a score back that is    *
346
 *  greater than or equal to beta.  This is called a fail   *
365
 *  greater than or equal to beta.  This is called a fail   *
Line 365... Line 384...
365
 *  mind at the root.  (If we are failing high on the first *
384
 *  mind at the root.  (If we are failing high on the first *
366
 *  root move we skip this update.)                         *
385
 *  root move we skip this update.)                         *
367
 *                                                          *
386
 *                                                          *
368
 ************************************************************
387
 ************************************************************
369
 */
388
 */
370
          if (value >= root_beta) {
389
          if (value >= beta) {
371
            root_beta = Min(old_root_beta + failhi_delta, MATE);
390
            beta = Min(beta + failhi_delta, MATE);
372
            failhi_delta *= 2;
391
            failhi_delta *= 2;
373
            if (failhi_delta > 10 * PAWN_VALUE)
392
            if (failhi_delta > 10 * PAWN_VALUE)
374
              failhi_delta = 99999;
393
              failhi_delta = 99999;
375
            root_moves[0].status &= 0xf7;
394
            root_moves[current_rm].status &= 7;
-
 
395
            root_moves[current_rm].bm_age = 4;
376
            if ((root_moves[0].status & 2) == 0)
396
            if ((root_moves[current_rm].status & 2) == 0)
377
              difficulty = ComputeDifficulty(difficulty, +1);
397
              difficulty = ComputeDifficulty(difficulty, +1);
378
            root_moves[0].status |= 2;
398
            root_moves[current_rm].status |= 2;
379
            if (tree->nodes_searched > noise_level) {
-
 
380
              fh_indicator = (wtm) ? "++" : "--";
-
 
381
              Print(2, "         %2i   %s     %2s   ", iteration_depth,
399
            DisplayFail(tree, 1, 5, wtm, end_time - start_time,
382
                  Display2Times(end_time - start_time), fh_indicator);
400
                root_moves[current_rm].move, value, force_print);
383
              if (display_options & 64)
-
 
384
                Print(2, "%d. ", move_number);
401
            temp_rm = root_moves[current_rm];
385
              if ((display_options & 64) && !wtm)
-
 
386
                Print(2, "... ");
-
 
387
              Print(2, "%s! ", OutputMove(tree, tree->pv[1].path[1], 1, wtm));
-
 
388
              Print(2, "(%c%s)                  \n", (wtm) ? '>' : '<',
-
 
389
                  DisplayEvaluationKibitz(old_root_beta, wtm));
-
 
390
              kibitz_text[0] = 0;
402
            for (i = current_rm; i > 0; i--)
391
              if (display_options & 64)
403
              root_moves[i] = root_moves[i - 1];
392
                sprintf_s(kibitz_text, sizeof (kibitz_text), " %d.", move_number); // Pierre-Marie Baty -- use safe version
-
 
393
              if ((display_options & 64) && !wtm)
-
 
394
                strcat_s(kibitz_text, sizeof (kibitz_text), " ..."); // Pierre-Marie Baty -- use safe version
-
 
395
              sprintf(kibitz_text + strlen(kibitz_text), " %s!",
-
 
396
                  OutputMove(tree, tree->pv[1].path[1], 1, wtm));
-
 
397
              idle_percent =
-
 
398
                  100 - Min(100,
404
            root_moves[0] = temp_rm;
399
                  100 * idle_time / (smp_max_threads * (end_time -
-
 
400
                          start_time) + 1));
-
 
401
              Kibitz(6, wtm, iteration_depth, end_time - start_time, value,
-
 
402
                  tree->nodes_searched, idle_percent,
-
 
403
                  tree->egtb_probes_successful, kibitz_text);
-
 
404
            }
405
          }
405
/*
406
/*
406
 ************************************************************
407
 ************************************************************
407
 *                                                          *
408
 *                                                          *
408
 *  Check for the case where we get a score back that is    *
409
 *  Check for the case where we get a score back that is    *
409
 *  less than or equal to alpha.  This is called a fail     *
410
 *  less than or equal to alpha.  This is called a fail     *
Line 428... Line 429...
428
 *  the first move at the root, and we don't want to stop   *
429
 *  the first move at the root, and we don't want to stop   *
429
 *  before we have a chance to find a better one.           *
430
 *  before we have a chance to find a better one.           *
430
 *                                                          *
431
 *                                                          *
431
 ************************************************************
432
 ************************************************************
432
 */
433
 */
433
          } else if (value <= root_alpha) {
434
          else if (value <= alpha) {
434
            root_alpha = Max(old_root_alpha - faillo_delta, -MATE);
435
            alpha = Max(alpha - faillo_delta, -MATE);
435
            faillo_delta *= 2;
436
            faillo_delta *= 2;
436
            if (faillo_delta > 10 * PAWN_VALUE)
437
            if (faillo_delta > 10 * PAWN_VALUE)
437
              faillo_delta = 99999;
438
              faillo_delta = 99999;
438
            root_moves[0].status &= 0xf7;
439
            root_moves[current_rm].status &= 7;
439
            if ((root_moves[0].status & 1) == 0)
440
            if ((root_moves[current_rm].status & 1) == 0)
440
              difficulty = ComputeDifficulty(Max(100, difficulty), -1);
441
              difficulty = ComputeDifficulty(Max(100, difficulty), -1);
441
            root_moves[0].status |= 1;
442
            root_moves[current_rm].status |= 1;
442
            if (tree->nodes_searched > noise_level && !abort_search) {
-
 
443
              fl_indicator = (wtm) ? "--" : "++";
-
 
444
              Print(4, "         %2i   %s     %2s   ", iteration_depth,
-
 
445
                  Display2Times(ReadClock() - start_time), fl_indicator);
443
            DisplayFail(tree, 2, 5, wtm, end_time - start_time,
446
              if (display_options & 64)
-
 
447
                Print(4, "%d. ", move_number);
444
                root_moves[current_rm].move, value, force_print);
448
              if ((display_options & 64) && !wtm)
-
 
449
                Print(4, "... ");
-
 
450
              Print(4, "%s? ", OutputMove(tree, root_moves[0].move, 1, wtm));
-
 
451
              Print(4, "(%c%s)                  \n", (Flip(wtm)) ? '>' : '<',
-
 
452
                  DisplayEvaluationKibitz(old_root_alpha, wtm));
-
 
453
            }
-
 
454
          } else
445
          } else
455
            break;
446
            break;
456
        }
447
        }
457
        if (value > root_alpha && value < root_beta)
448
        if (value > alpha && value < beta)
458
          last_root_value = value;
449
          last_root_value = value;
459
/*
450
/*
460
 ************************************************************
451
 ************************************************************
461
 *                                                          *
452
 *                                                          *
462
 *  If we are running a test suite, check to see if we can  *
453
 *  If we are running a test suite, check to see if we can  *
Line 469... Line 460...
469
        correct = solution_type;
460
        correct = solution_type;
470
        for (i = 0; i < number_of_solutions; i++) {
461
        for (i = 0; i < number_of_solutions; i++) {
471
          if (!solution_type) {
462
          if (!solution_type) {
472
            if (solutions[i] == tree->pv[0].path[1])
463
            if (solutions[i] == tree->pv[0].path[1])
473
              correct = 1;
464
              correct = 1;
474
          } else if (solutions[i] == tree->pv[0].path[1])
465
          } else if (solutions[i] == root_moves[current_rm].move)
475
            correct = 0;
466
            correct = 0;
476
        }
467
        }
477
        if (correct)
468
        if (correct)
478
          correct_count++;
469
          correct_count++;
479
        else
470
        else
Line 486... Line 477...
486
 *  those since they are potential best moves again.        *
477
 *  those since they are potential best moves again.        *
487
 *                                                          *
478
 *                                                          *
488
 ************************************************************
479
 ************************************************************
489
 */
480
 */
490
        for (i = 0; i < n_root_moves; i++) {
481
        for (i = 0; i < n_root_moves; i++) {
-
 
482
          root_moves[i].status &= 3;
491
          if (root_moves[i].bm_age)
483
          if (root_moves[i].bm_age)
492
            root_moves[i].bm_age--;
484
            root_moves[i].bm_age--;
493
          if (root_moves[i].bm_age)
485
          if (root_moves[i].bm_age)
494
            root_moves[i].status &= 0xfb;
-
 
495
          else
-
 
496
            root_moves[i].status |= 4;
486
            root_moves[i].status |= 4;
497
        }
487
        }
-
 
488
        SortRootMoves();
498
        difficulty = ComputeDifficulty(difficulty, 0);
489
        difficulty = ComputeDifficulty(difficulty, 0);
499
/*
490
/*
500
 ************************************************************
491
 ************************************************************
501
 *                                                          *
492
 *                                                          *
502
 *  If requested, print the ply=1 move list along with the  *
493
 *  If requested, print the ply=1 move list along with the  *
503
 *  flags for each move.  Once we print this (if requested) *
494
 *  flags for each move.  Once we print this (if requested) *
504
 *  we can then clear all of the status flags (except the   *
495
 *  we can then clear all of the status flags (except the   *
505
 *  "ok to search in parallel or reduce" flag) to prepare   *
496
 *  "do not search in parallel or reduce" flag) to prepare  *
506
 *  for the start of the next iteration, since that is the  *
497
 *  for the start of the next iteration, since that is the  *
507
 *  only flag that needs to be carried forward to the next  *
498
 *  only flag that needs to be carried forward to the next  *
508
 *  iteration.                                              *
499
 *  iteration.                                              *
509
 *                                                          *
500
 *                                                          *
510
 ************************************************************
501
 ************************************************************
511
 */
502
 */
512
        if (display_options & 256) {
503
        if (display_options & 64) {
513
          Print(128, "       move  age  R ! ?\n");
504
          Print(64, "      rmove   score    age  S ! ?\n");
514
          for (i = 0; i < n_root_moves; i++) {
505
          for (i = 0; i < n_root_moves; i++) {
515
            Print(128, " %10s   %d   %d %d %d\n", OutputMove(tree,
506
            Print(64, " %10s ", OutputMove(tree, 1, wtm, root_moves[i].move));
-
 
507
            if (root_moves[i].path.pathv > -MATE)
-
 
508
              Print(64, "%s", DisplayEvaluation(root_moves[i].path.pathv,
-
 
509
                      wtm));
-
 
510
            else
-
 
511
              Print(64, "  -----");
516
                    root_moves[i].move, 1, wtm), root_moves[i].bm_age,
512
            Print(64, "     %d   %d %d %d\n", root_moves[i].bm_age,
517
                (root_moves[i].status & 4) != 0,
513
                (root_moves[i].status & 4) != 0,
518
                (root_moves[i].status & 2) != 0,
514
                (root_moves[i].status & 2) != 0,
519
                (root_moves[i].status & 1) != 0);
515
                (root_moves[i].status & 1) != 0);
520
          }
516
          }
521
        }
517
        }
522
        for (i = 0; i < n_root_moves; i++)
-
 
523
          root_moves[i].status &= 4;
-
 
524
/*
518
/*
525
 ************************************************************
519
 ************************************************************
526
 *                                                          *
520
 *                                                          *
527
 *  Here we simply display the PV from the current search   *
521
 *  Here we simply display the PV from the current search   *
528
 *  iteration, and then set the aspiration for the next     *
522
 *  iteration, and then set the aspiration for the next     *
529
 *  iteration to the current score +/- 16.                  *
523
 *  iteration to the current score +/- 16.                  *
530
 *                                                          *
524
 *                                                          *
531
 ************************************************************
525
 ************************************************************
532
 */
526
 */
533
        if (end_time - start_time > 10)
527
        if (end_time - start_time > 10)
534
          nodes_per_second =
528
          nodes_per_second = (unsigned int) // Pierre-Marie Baty -- added type cast
535
              (unsigned int) (tree->nodes_searched * 100 / (end_time - start_time)); // Pierre-Marie Baty -- added type cast (FIXME: either stay on 32 bits, or port correctly!)
529
              (tree->nodes_searched * 100 / (uint64_t) (end_time - start_time));
536
        else
530
        else
537
          nodes_per_second = 1000000;
531
          nodes_per_second = 1000000;
-
 
532
        tree->pv[0] = root_moves[0].path;
538
        if (!abort_search && value != -(MATE - 1)) {
533
        if (!abort_search && value != -(MATE - 1)) {
539
          if (tree->nodes_searched > noise_level) {
534
          if (end_time - start_time >= noise_level) {
540
            DisplayPV(tree, 5, wtm, end_time - start_time, &tree->pv[0]);
535
            DisplayPV(tree, 5, wtm, end_time - start_time, &tree->pv[0],
-
 
536
                force_print);
541
            noise_block = 0;
537
            noise_block = 0;
542
          }
538
          } else
-
 
539
            noise_block = 1;
543
        }
540
        }
544
        root_alpha = Max(-MATE, value - 16);
541
        alpha = Max(-MATE, value - 16);
545
        root_beta = Min(MATE, value + 16);
542
        beta = Min(MATE, value + 16);
546
/*
543
/*
547
 ************************************************************
544
 ************************************************************
548
 *                                                          *
545
 *                                                          *
549
 *  There are multiple termination criteria that are used.  *
546
 *  There are multiple termination criteria that are used.  *
550
 *  The first and most obvious is that we have exceeded the *
547
 *  The first and most obvious is that we have exceeded the *
Line 559... Line 556...
559
 *                                                          *
556
 *                                                          *
560
 ************************************************************
557
 ************************************************************
561
 */
558
 */
562
        if (TimeCheck(tree, 0))
559
        if (TimeCheck(tree, 0))
563
          break;
560
          break;
564
        if (iteration_depth > 3 && value > 32000 &&
561
        if (iteration > 3 && value > 32000 && value >= (MATE - iteration + 3)
565
            value >= (MATE - iteration_depth + 3)
-
 
566
            && value > last_mate_score)
562
            && value > last_mate_score)
567
          break;
563
          break;
568
        if ((iteration_depth >= search_depth) && search_depth)
564
        if ((iteration >= search_depth) && search_depth)
569
          break;
565
          break;
570
        if (abort_search)
566
        if (abort_search)
571
          break;
567
          break;
572
        end_time = ReadClock() - start_time;
568
        end_time = ReadClock() - start_time;
573
        if (correct_count >= early_exit)
569
        if (correct_count >= early_exit)
574
          break;
570
          break;
575
#if !defined(NOEGTB)
571
#if !defined(NOEGTB)
576
        if (iteration_depth > 10 && TotalAllPieces <= EGTBlimit && EGTB_use &&
572
        if (iteration > EGTB_depth + 10 && TotalAllPieces <= EGTBlimit &&
577
            !EGTB_search && EGTBProbe(tree, 1, wtm, &i))
573
            EGTB_use && EGTBProbe(tree, 1, wtm, &i))
578
          break;
574
          break;
579
#endif
575
#endif
580
        if (search_nodes && tree->nodes_searched >= search_nodes)
576
        if (search_nodes && tree->nodes_searched >= search_nodes)
581
          break;
577
          break;
582
      }
578
      }
Line 602... Line 598...
602
 *                                                          *
598
 *                                                          *
603
 ************************************************************
599
 ************************************************************
604
 */
600
 */
605
      end_time = ReadClock();
601
      end_time = ReadClock();
606
      if (end_time > 10)
602
      if (end_time > 10)
607
        nodes_per_second =
603
        nodes_per_second = (unsigned int) // Pierre-Marie Baty -- added type cast
608
            (unsigned int) (tree->nodes_searched * 100 / (end_time -
604
            ((uint64_t) tree->nodes_searched * 100 / Max((uint64_t) end_time -
609
            start_time + 1)); // Pierre-Marie Baty -- added type cast (FIXME: either stay on 32 bits, or port correctly!)
605
            start_time, 1));
610
      if (abort_search != 2 && !puzzling) {
606
      if (abort_search != 2 && !puzzling) {
611
        if (noise_block)
607
        if (noise_block)
612
          DisplayPV(tree, 5, wtm, end_time - start_time, &tree->pv[0]);
608
          DisplayPV(tree, 5, wtm, end_time - start_time, &tree->pv[0], 1);
613
        tree->evaluations = (tree->evaluations) ? tree->evaluations : 1;
609
        tree->evaluations = (tree->evaluations) ? tree->evaluations : 1;
614
        tree->fail_highs++;
610
        tree->fail_highs++;
615
        tree->fail_high_first_move++;
611
        tree->fail_high_first_move++;
-
 
612
        idle_time = 0;
-
 
613
        for (i = 0; i < (int) smp_max_threads; i++) // Pierre-Marie Baty -- added type cast
-
 
614
          idle_time += thread[i].idle;
616
        idle_percent =
615
        busy_percent =
617
            100 - Min(100,
616
            100 - Min(100,
618
            100 * idle_time / (smp_max_threads * (end_time - start_time) +
617
            100 * idle_time / (smp_max_threads * (end_time - start_time) +
619
                1));
618
                1));
620
        Print(8, "        time=%s(%d%%)",
619
        Print(8, "        time=%s(%d%%)",
621
            DisplayTimeKibitz(end_time - start_time), idle_percent);
620
            DisplayTimeKibitz(end_time - start_time), busy_percent);
622
        Print(8, "  n=%" PRIu64, tree->nodes_searched);
621
        Print(8, "  nodes=%" PRIu64 "(%s)", tree->nodes_searched,
-
 
622
            DisplayKMB(tree->nodes_searched, 0));
623
        Print(8, "  fh1=%d%%",
623
        Print(8, "  fh1=%d%%",
624
            tree->fail_high_first_move * 100 / tree->fail_highs);
624
            tree->fail_high_first_move * 100 / tree->fail_highs);
-
 
625
        Print(8, "  pred=%d", predicted);
-
 
626
        Print(8, "  nps=%s\n", DisplayKMB(nodes_per_second, 0));
-
 
627
        Print(8, "        chk=%s", DisplayKMB(tree->extensions_done, 0));
-
 
628
        Print(8, "  qchk=%s", DisplayKMB(tree->qchecks_done, 0));
-
 
629
        Print(8, "  fp=%s", DisplayKMB(tree->moves_fpruned, 0));
-
 
630
        Print(8, "  mcp=%s", DisplayKMB(tree->moves_mpruned, 0));
625
        Print(8, "  50move=%d", Reversible(0));
631
        Print(8, "  50move=%d", Reversible(0));
-
 
632
        if (tree->egtb_hits)
626
        Print(8, "  nps=%s\n", DisplayKMB(nodes_per_second));
633
          Print(8, "  egtb=%s", DisplayKMB(tree->egtb_hits, 0));
-
 
634
        Print(8, "\n");
627
        Print(16, "        ext=%s", DisplayKMB(tree->extensions_done));
635
        Print(8, "        LMReductions:");
-
 
636
        npc = 21;
-
 
637
        cpl = 75;
-
 
638
        for (i = 1; i < 16; i++)
-
 
639
          if (tree->LMR_done[i]) {
628
        Print(16, "  red=%s", DisplayKMB(tree->reductions_done));
640
            sprintf(buff, "%d/%s", i, DisplayKMB(tree->LMR_done[i], 0));
-
 
641
            if (npc + (int)strlen(buff) > cpl) { // Pierre-Marie Baty -- added type cast
-
 
642
              Print(8, "\n            ");
-
 
643
              npc = 12;
-
 
644
            }
-
 
645
            Print(8, "  %s", buff);
-
 
646
            npc += strlen(buff) + 2;
-
 
647
          }
-
 
648
        if (npc)
-
 
649
          Print(8, "\n");
-
 
650
        npc = 24;
-
 
651
        cpl = 75;
-
 
652
        if (tree->null_done[null_depth])
629
        Print(16, "  pruned=%s", DisplayKMB(tree->moves_fpruned));
653
          Print(8, "        null-move (R):");
-
 
654
        for (i = null_depth; i < 16; i++)
-
 
655
          if (tree->null_done[i]) {
630
        Print(16, "  qchks=%s", DisplayKMB(tree->qchecks_done));
656
            sprintf(buff, "%d/%s", i, DisplayKMB(tree->null_done[i], 0));
-
 
657
            if (npc + (int)strlen(buff) > cpl) { // Pierre-Marie Baty -- added type cast
-
 
658
              Print(8, "\n            ");
-
 
659
              npc = 12;
-
 
660
            }
631
        Print(16, "  pred=%d\n", predicted);
661
            Print(8, "  %s", buff);
-
 
662
            npc += strlen(buff) + 2;
-
 
663
          }
-
 
664
        if (npc)
-
 
665
          Print(8, "\n");
-
 
666
        if (parallel_splits) {
-
 
667
          max = 0;
-
 
668
          for (i = 0; i < (int) smp_max_threads; i++) { // Pierre-Marie Baty -- added type cast
-
 
669
            max = Max(max, PopCnt(thread[i].max_blocks));
-
 
670
            game_max_blocks |= thread[i].max_blocks;
-
 
671
          }
632
        Print(16, "        splits=%s", DisplayKMB(parallel_splits));
672
          Print(8, "        splits=%s", DisplayKMB(parallel_splits, 0));
633
        Print(16, "  aborts=%s", DisplayKMB(parallel_aborts));
673
          Print(8, "(%s)", DisplayKMB(parallel_splits_wasted, 0));
634
        Print(16, "  data=%d%%", 100 * max_split_blocks / Max(MAX_BLOCKS, 1));
674
          Print(8, "  aborts=%s", DisplayKMB(parallel_aborts, 0));
635
        Print(16, "  probes=%s", DisplayKMB(tree->egtb_probes));
675
          Print(8, "  joins=%s", DisplayKMB(parallel_joins, 0));
636
        Print(16, "  hits=%s\n", DisplayKMB(tree->egtb_probes_successful));
676
          Print(8, "  data=%d%%(%d%%)\n", 100 * max / 64,
-
 
677
              100 * PopCnt(game_max_blocks) / 64);
-
 
678
        }
637
      }
679
      }
638
    } while (0);
680
    } while (0);
639
/*
681
/*
640
 ************************************************************
682
 ************************************************************
641
 *                                                          *
683
 *                                                          *
Line 647... Line 689...
647
 */
689
 */
648
  else {
690
  else {
649
    last_root_value = 0;
691
    last_root_value = 0;
650
    value = 0;
692
    value = 0;
651
    book_move = 1;
693
    book_move = 1;
652
    tree->pv[0] = tree->pv[1];
-
 
653
    if (analyze_mode)
694
    if (analyze_mode)
654
      Kibitz(4, wtm, 0, 0, 0, 0, 0, 0, kibitz_text);
695
      Kibitz(4, wtm, 0, 0, 0, 0, 0, 0, kibitz_text);
655
  }
696
  }
656
/*
697
/*
657
 ************************************************************
698
 ************************************************************
Line 666... Line 707...
666
 *                                                          *
707
 *                                                          *
667
 ************************************************************
708
 ************************************************************
668
 */
709
 */
669
  if (smp_nice && ponder == 0 && smp_threads) {
710
  if (smp_nice && ponder == 0 && smp_threads) {
670
    int proc;
711
    int proc;
-
 
712
 
671
    Print(128, "terminating SMP processes.\n");
713
    Print(64, "terminating SMP processes.\n");
672
    for (proc = 1; proc < CPUS; proc++)
714
    for (proc = 1; proc < CPUS; proc++)
673
      thread[proc].tree = (TREE *) - 1;
715
      thread[proc].terminate = 1;
674
    while (smp_threads);
716
    while (smp_threads);
675
    smp_idle = 0;
-
 
676
    smp_split = 0;
717
    smp_split = 0;
677
  }
718
  }
678
  program_end_time = ReadClock();
719
  program_end_time = ReadClock();
679
  search_move = 0;
720
  search_move = 0;
680
  if (quit)
721
  if (quit)