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 5... Line 5...
5
#if defined(UNIX)
5
#if defined(UNIX)
6
#  include <unistd.h>
6
#  include <unistd.h>
7
#  include <signal.h>
7
#  include <signal.h>
8
#endif
8
#endif
9
#include "epdglue.h"
9
#include "epdglue.h"
10
/* last modified 02/26/14 */
10
/* last modified 01/16/15 */
11
/*
11
/*
12
 *******************************************************************************
12
 *******************************************************************************
13
 *                                                                             *
13
 *                                                                             *
14
 *   Option() is used to handle user input necessary to control/customize the  *
14
 *   Option() is used to handle user input necessary to control/customize the  *
15
 *   program.  It performs all functions excepting chess move input which is   *
15
 *   program.  It performs all functions excepting chess move input which is   *
16
 *   handled by main().                                                        *
16
 *   handled by main().                                                        *
17
 *                                                                             *
17
 *                                                                             *
18
 *******************************************************************************
18
 *******************************************************************************
19
 */
19
 */
20
int Option(TREE * RESTRICT tree) {
20
int Option(TREE * RESTRICT tree) {
-
 
21
  int v;
-
 
22
 
21
/*
23
/*
22
 ************************************************************
24
 ************************************************************
23
 *                                                          *
25
 *                                                          *
24
 *  parse the input.  If it looks like a FEN string, don't  *
26
 *  parse the input.  If it looks like a FEN string, don't  *
25
 *  parse using "/" as a separator, otherwise do.           *
27
 *  parse using "/" as a separator, otherwise do.           *
Line 48... Line 50...
48
  if (initialized) {
50
  if (initialized) {
49
    if (EGCommandCheck(buffer)) {
51
    if (EGCommandCheck(buffer)) {
50
      if (thinking || pondering)
52
      if (thinking || pondering)
51
        return 2;
53
        return 2;
52
      else {
54
      else {
53
        (void) EGCommand(buffer);
55
        EGCommand(buffer);
54
        return 1;
56
        return 1;
55
      }
57
      }
56
    }
58
    }
57
  }
59
  }
58
#endif
60
#endif
Line 66... Line 68...
66
 *  machine, probably something that is not wanted.         *
68
 *  machine, probably something that is not wanted.         *
67
 *                                                          *
69
 *                                                          *
68
 ************************************************************
70
 ************************************************************
69
 */
71
 */
70
  if (buffer[0] == '!') {
72
  if (buffer[0] == '!') {
71
    if (!xboard)
73
    if (!xboard) {
72
      system(strchr(buffer, '!') + 1);
74
      v = system(strchr(buffer, '!') + 1);
-
 
75
      if (v != 0)
-
 
76
        perror("Option() system() error: ");
-
 
77
    }
73
  }
78
  }
74
/*
79
/*
75
 ************************************************************
80
 ************************************************************
76
 *                                                          *
81
 *                                                          *
77
 *  "." ignores "." if it happens to get to this point, if  *
82
 *  "." ignores "." if it happens to get to this point, if  *
Line 118... Line 123...
118
    if (nargs != 6) {
123
    if (nargs != 6) {
119
      printf("usage:  adaptive NPS hmin hmax pmin pmax\n");
124
      printf("usage:  adaptive NPS hmin hmax pmin pmax\n");
120
      return 1;
125
      return 1;
121
    }
126
    }
122
    if (nargs > 1) {
127
    if (nargs > 1) {
123
      adaptive_hash = (int) atoiKM(args[1]); // Pierre-Marie Baty -- added type cast
128
      adaptive_hash = (int) atoiKMB(args[1]); // Pierre-Marie Baty -- added type cast
124
      adaptive_hash_min = (size_t) atoiKM(args[2]); // Pierre-Marie Baty -- added type cast
129
      adaptive_hash_min = (size_t) atoiKMB(args[2]); // Pierre-Marie Baty -- added type cast
125
      adaptive_hash_max = (size_t) atoiKM(args[3]); // Pierre-Marie Baty -- added type cast
130
      adaptive_hash_max = (size_t) atoiKMB(args[3]); // Pierre-Marie Baty -- added type cast
126
      adaptive_hashp_min = (size_t) atoiKM(args[4]); // Pierre-Marie Baty -- added type cast
131
      adaptive_hashp_min = (size_t) atoiKMB(args[4]); // Pierre-Marie Baty -- added type cast
127
      adaptive_hashp_max = (size_t) atoiKM(args[5]); // Pierre-Marie Baty -- added type cast
132
      adaptive_hashp_max = (size_t) atoiKMB(args[5]); // Pierre-Marie Baty -- added type cast
128
    }
133
    }
129
    Print(128, "adaptive estimated NPS =  %s\n", PrintKM(adaptive_hash, 1));
134
    Print(32, "adaptive estimated NPS =  %s\n", DisplayKMB(adaptive_hash, 1));
130
    Print(128, "adaptive minimum hsize =  %s\n", PrintKM(adaptive_hash_min,
135
    Print(32, "adaptive minimum hsize =  %s\n", DisplayKMB(adaptive_hash_min,
131
            1));
136
            1));
132
    Print(128, "adaptive maximum hsize =  %s\n", PrintKM(adaptive_hash_max,
137
    Print(32, "adaptive maximum hsize =  %s\n", DisplayKMB(adaptive_hash_max,
133
            1));
138
            1));
134
    Print(128, "adaptive minimum psize =  %s\n", PrintKM(adaptive_hashp_min,
139
    Print(32, "adaptive minimum psize =  %s\n", DisplayKMB(adaptive_hashp_min,
135
            1));
140
            1));
136
    Print(128, "adaptive maximum psize =  %s\n", PrintKM(adaptive_hashp_max,
141
    Print(32, "adaptive maximum psize =  %s\n", DisplayKMB(adaptive_hashp_max,
137
            1));
142
            1));
138
  }
143
  }
139
/*
144
/*
140
 ************************************************************
145
 ************************************************************
141
 *                                                          *
146
 *                                                          *
Line 182... Line 187...
182
  else if (OptionMatch("annotate", *args) || OptionMatch("annotateh", *args)
187
  else if (OptionMatch("annotate", *args) || OptionMatch("annotateh", *args)
183
      || OptionMatch("annotatet", *args)) {
188
      || OptionMatch("annotatet", *args)) {
184
    if (thinking || pondering)
189
    if (thinking || pondering)
185
      return 2;
190
      return 2;
186
    Annotate();
191
    Annotate();
-
 
192
  }
-
 
193
/*
-
 
194
 ************************************************************
-
 
195
 *                                                          *
-
 
196
 *  "autotune" command is used to automatically tune the    *
-
 
197
 *  SMP search parameters that affect search efficiency.    *
-
 
198
 *                                                          *
-
 
199
 ************************************************************
-
 
200
 */
-
 
201
  else if (OptionMatch("autotune", *args)) {
-
 
202
    if (thinking || pondering)
-
 
203
      return 2;
-
 
204
    AutoTune(nargs, args);
187
  }
205
  }
188
/*
206
/*
189
 ************************************************************
207
 ************************************************************
190
 *                                                          *
208
 *                                                          *
191
 *  "batch" command disables asynchronous I/O so that a     *
209
 *  "batch" command disables asynchronous I/O so that a     *
Line 213... Line 231...
213
    return xboard;
231
    return xboard;
214
  }
232
  }
215
/*
233
/*
216
 ************************************************************
234
 ************************************************************
217
 *                                                          *
235
 *                                                          *
218
 *  "bench" runs internal performance benchmark             *
236
 *  "bench" runs internal performance benchmark.  An        *
-
 
237
 *  optional second argument can increase or decrease the   *
-
 
238
 *  time it takes.  "bench 1" increases the default depth   *
-
 
239
 *  by one ply, and "bench -1" reduces the depth to speed   *
-
 
240
 *  it up.                                                  *
219
 *                                                          *
241
 *                                                          *
220
 ************************************************************
242
 ************************************************************
221
 */
243
 */
222
  else if (OptionMatch("bench", *args)) {
244
  else if (OptionMatch("bench", *args)) {
-
 
245
    int mod = 0, time;
-
 
246
 
223
    Bench(0);
247
    if (nargs > 1)
224
  } else if (OptionMatch("bench1", *args) || OptionMatch("bench-1", *args)) {
248
      mod = atoi(args[1]);
225
    Bench(-1);
249
    time = Bench(mod, 0);
226
  } else if (OptionMatch("bench2", *args) || OptionMatch("bench-2", *args)) {
250
    Print(32, "time used = %s\n", DisplayTime(time));
227
    Bench(-2);
251
  }
-
 
252
/*
-
 
253
 ***************************************************************
-
 
254
 *                                                             *
-
 
255
 *  "pgo" runs an internal performance benchmark used for PGO. *
228
  } else if (OptionMatch("bench3", *args) || OptionMatch("bench-3", *args)) {
256
 *  An optional second argument can increase or decrease       *
229
    Bench(-3);
257
 *  the time it takes.  "pgo 1" increases the default          *
230
  } else if (OptionMatch("bench+1", *args)) {
258
 *  by one ply, and "pgo -1" reduces the depth to speed        *
-
 
259
 *  it up.                                                     *
-
 
260
 *                                                             *
-
 
261
 ************************************************************
231
    Bench(1);
262
         */
232
  } else if (OptionMatch("bench+2", *args)) {
263
  else if (OptionMatch("pgo", *args)) {
-
 
264
    int mod = 0, time;
-
 
265
 
233
    Bench(2);
266
    if (nargs > 1)
234
  } else if (OptionMatch("bench+3", *args)) {
267
      mod = atoi(args[1]);
235
    Bench(3);
268
    time = Bench_PGO(mod, 0);
-
 
269
    Print(32, "time used = %s\n", DisplayTime(time));
236
  }
270
  }
237
/*
271
/*
238
 ************************************************************
272
 ************************************************************
239
 *                                                          *
273
 *                                                          *
240
 *  "bk"  book command from xboard sends the suggested book *
274
 *  "bk"  book command from xboard sends the suggested book *
Line 252... Line 286...
252
 *                                                          *
286
 *                                                          *
253
 *  "black" command sets black to move (Flip(wtm)).         *
287
 *  "black" command sets black to move (Flip(wtm)).         *
254
 *                                                          *
288
 *                                                          *
255
 ************************************************************
289
 ************************************************************
256
 */
290
 */
257
  else if (!strcmp("white", *args)) {
291
  else if (OptionMatch("white", *args)) {
258
    if (thinking || pondering)
292
    if (thinking || pondering)
259
      return 2;
293
      return 2;
-
 
294
    game_wtm = 1;
260
    ponder_move = 0;
295
    ponder_move = 0;
261
    last_pv.pathd = 0;
296
    last_pv.pathd = 0;
262
    last_pv.pathl = 0;
297
    last_pv.pathl = 0;
263
    if (!game_wtm)
298
    if (!game_wtm)
264
      Pass();
299
      Pass();
265
    force = 0;
300
    force = 0;
266
  } else if (!strcmp("black", *args)) {
301
  } else if (OptionMatch("black", *args)) {
267
    if (thinking || pondering)
302
    if (thinking || pondering)
268
      return 2;
303
      return 2;
-
 
304
    game_wtm = 0;
269
    ponder_move = 0;
305
    ponder_move = 0;
270
    last_pv.pathd = 0;
306
    last_pv.pathd = 0;
271
    last_pv.pathl = 0;
307
    last_pv.pathl = 0;
272
    if (game_wtm)
308
    if (game_wtm)
273
      Pass();
309
      Pass();
Line 280... Line 316...
280
 *                                                          *
316
 *                                                          *
281
 ************************************************************
317
 ************************************************************
282
 */
318
 */
283
  else if (OptionMatch("bogus", *args)) {
319
  else if (OptionMatch("bogus", *args)) {
284
    return xboard;
320
    return xboard;
-
 
321
  }
-
 
322
/*
-
 
323
 ************************************************************
-
 
324
 *                                                          *
-
 
325
 *  "book" command updates/creates the opening book file.   *
-
 
326
 *                                                          *
-
 
327
 ************************************************************
-
 
328
 */
-
 
329
  else if (OptionMatch("book", *args)) {
-
 
330
    nargs = ReadParse(buffer, args, " \t;");
-
 
331
    Bookup(tree, nargs, args);
-
 
332
  } else if (!strcmp("create", *(args + 1))) {
-
 
333
    nargs = ReadParse(buffer, args, " \t;");
-
 
334
    Bookup(tree, nargs, args);
285
  }
335
  }
286
/*
336
/*
287
 ************************************************************
337
 ************************************************************
288
 *                                                          *
338
 *                                                          *
289
 *  "bookw" command updates the book selection weights.     *
339
 *  "bookw" command updates the book selection weights.     *
290
 *                                                          *
340
 *                                                          *
291
 ************************************************************
341
 ************************************************************
292
 */
342
 */
293
  else if (!strcmp("bookw", *args)) {
343
  else if (OptionMatch("bookw", *args)) {
294
    if (nargs > 1) {
344
    if (nargs > 1) {
295
      if (!strcmp("freq", args[1]))
345
      if (OptionMatch("frequency", args[1]))
296
        book_weight_freq = (float) atof(args[2]); // Pierre-Marie Baty -- added type cast
346
        book_weight_freq = (float) atof(args[2]); // Pierre-Marie Baty -- added type cast
297
      else if (!strcmp("eval", args[1]))
347
      else if (OptionMatch("evaluation", args[1]))
298
        book_weight_eval = (float) atof(args[2]); // Pierre-Marie Baty -- added type cast
348
        book_weight_eval = (float) atof(args[2]); // Pierre-Marie Baty -- added type cast
299
      else if (!strcmp("learn", args[1]))
349
      else if (OptionMatch("learning", args[1]))
300
        book_weight_learn = (float) atof(args[2]); // Pierre-Marie Baty -- added type cast
350
        book_weight_learn = (float) atof(args[2]); // Pierre-Marie Baty -- added type cast
301
    } else {
351
    } else {
302
      Print(128, "frequency (freq)..............%4.2f\n", book_weight_freq);
352
      Print(32, "frequency (freq)..............%4.2f\n", book_weight_freq);
303
      Print(128, "static evaluation (eval)......%4.2f\n", book_weight_eval);
353
      Print(32, "static evaluation (eval)......%4.2f\n", book_weight_eval);
304
      Print(128, "learning (learn)..............%4.2f\n", book_weight_learn);
354
      Print(32, "learning (learn)..............%4.2f\n", book_weight_learn);
305
    }
355
    }
306
  }
-
 
307
/*
-
 
308
 ************************************************************
-
 
309
 *                                                          *
-
 
310
 *  "book" command updates/creates the opening book file.   *
-
 
311
 *                                                          *
-
 
312
 ************************************************************
-
 
313
 */
-
 
314
  else if (!strcmp("book", *args)) {
-
 
315
    nargs = ReadParse(buffer, args, " \t;");
-
 
316
    BookUp(tree, nargs, args);
-
 
317
  } else if (!strcmp("create", *(args + 1))) {
-
 
318
    nargs = ReadParse(buffer, args, " \t;");
-
 
319
    BookUp(tree, nargs, args);
-
 
320
  }
356
  }
321
/*
357
/*
322
 ************************************************************
358
 ************************************************************
323
 *                                                          *
359
 *                                                          *
324
 *  "cache" is used to set the EGTB cache size.  As always  *
360
 *  "cache" is used to set the EGTB cache size.  As always  *
Line 328... Line 364...
328
 *                                                          *
364
 *                                                          *
329
 ************************************************************
365
 ************************************************************
330
 */
366
 */
331
#if !defined(NOEGTB)
367
#if !defined(NOEGTB)
332
  else if (OptionMatch("cache", *args)) {
368
  else if (OptionMatch("cache", *args)) {
333
    EGTB_cache_size = (size_t) atoiKM(args[1]); // Pierre-Marie Baty -- added type cast
369
    EGTB_cache_size = (size_t) atoiKMB(args[1]); // Pierre-Marie Baty -- added type cast
334
    if (EGTB_cache)
370
    if (EGTB_cache)
335
      free(EGTB_cache);
371
      free(EGTB_cache);
336
    EGTB_cache = malloc(EGTB_cache_size);
372
    EGTB_cache = malloc(EGTB_cache_size);
337
    if (!EGTB_cache) {
373
    if (!EGTB_cache) {
338
      Print(2095,
374
      Print(2095,
339
          "ERROR:  unable to malloc specified cache size, using default\n");
375
          "ERROR:  unable to malloc specified cache size, using default\n");
340
      EGTB_cache = malloc(4096 * 4096);
376
      EGTB_cache = malloc(4096 * 4096);
341
    }
377
    }
342
    Print(128, "EGTB cache memory = %s bytes.\n", PrintKM(EGTB_cache_size,
378
    Print(32, "EGTB cache memory = %s bytes.\n", DisplayKMB(EGTB_cache_size,
343
            1));
379
            1));
344
    FTbSetCacheSize(EGTB_cache, EGTB_cache_size);
380
    FTbSetCacheSize(EGTB_cache, EGTB_cache_size);
345
  }
381
  }
346
#endif
382
#endif
347
/*
383
/*
Line 353... Line 389...
353
 */
389
 */
354
  else if (OptionMatch("clock", *args)) {
390
  else if (OptionMatch("clock", *args)) {
355
    int side;
391
    int side;
356
 
392
 
357
    for (side = white; side >= black; side--) {
393
    for (side = white; side >= black; side--) {
358
      Print(128, "time remaining (%s): %s", (side) ? "white" : "black",
394
      Print(32, "time remaining (%s): %s", (side) ? "white" : "black",
359
          DisplayHHMMSS(tc_time_remaining[side]));
395
          DisplayHHMMSS(tc_time_remaining[side]));
360
      if (tc_sudden_death != 1)
396
      if (tc_sudden_death != 1)
361
        Print(128, "  (%d more moves)", tc_moves_remaining[side]);
397
        Print(32, "  (%d more moves)", tc_moves_remaining[side]);
362
      printf("\n");
398
      Print(32, "\n");
363
    }
399
    }
364
    Print(128, "\n");
400
    Print(32, "\n");
365
    if (tc_sudden_death == 1)
401
    if (tc_sudden_death == 1)
366
      Print(128, "Sudden-death time control in effect\n");
402
      Print(32, "Sudden-death time control in effect\n");
367
  }
403
  }
368
/*
404
/*
369
 ************************************************************
405
 ************************************************************
370
 *                                                          *
406
 *                                                          *
371
 *  "computer" lets Crafty know it is playing a computer.   *
407
 *  "computer" lets Crafty know it is playing a computer.   *
372
 *                                                          *
408
 *                                                          *
373
 ************************************************************
409
 ************************************************************
374
 */
410
 */
375
  else if (OptionMatch("computer", *args)) {
411
  else if (OptionMatch("computer", *args)) {
376
    Print(128, "playing a computer!\n");
412
    Print(32, "playing a computer!\n");
377
    accept_draws = 1;
413
    accept_draws = 1;
-
 
414
    if (resign)
378
    resign = 10;
415
      resign = 10;
379
    resign_counter = 4;
416
    resign_count = 4;
380
    usage_level = 0;
417
    usage_level = 0;
381
    books_file = (computer_bs_file) ? computer_bs_file : normal_bs_file;
418
    books_file = (computer_bs_file) ? computer_bs_file : normal_bs_file;
382
  }
419
  }
383
/*
420
/*
384
 ************************************************************
421
 ************************************************************
Line 388... Line 425...
388
 *  "display" command sets specific display options which   *
425
 *  "display" command sets specific display options which   *
389
 *  control how "chatty" the program is.  In the variable   *
426
 *  control how "chatty" the program is.  In the variable   *
390
 *  display_options, the following bits are set/cleared     *
427
 *  display_options, the following bits are set/cleared     *
391
 *  based on the option chosen.                             *
428
 *  based on the option chosen.                             *
392
 *                                                          *
429
 *                                                          *
393
 *    1 -> display time for moves.                          *
430
 *    1 -> display move/time/results/etc.                   *
394
 *    2 -> display variation when it changes.               *
431
 *    2 -> display PV.                                      *
395
 *    4 -> display variation at end of iteration.           *
432
 *    4 -> display fail high / fail low moves               *
396
 *    8 -> display basic search statistics.                 *
433
 *    8 -> display search statistics.                       *
397
 *   16 -> display extended search statistics.              *
-
 
398
 *   32 -> display root moves as they are searched.         *
434
 *   16 -> display root moves as they are searched.         *
399
 *   64 -> display move numbers in the PV output.           *
-
 
400
 *  128 -> display general informational messages.          *
435
 *   32 -> display general informational messages.          *
401
 *  256 -> display ply-1 move list / flags after each       *
436
 *   64 -> display ply-1 move list / flags after each       *
402
 *         iteration.                                       *
437
 *         iteration.                                       *
403
 *  512 -> display ply-1 moves and positional evaluations   *
438
 *  128 -> display root moves and scores before search      *
-
 
439
 *         begins.                                          *
-
 
440
 * 2048 -> error messages (can not be disabled).            *
404
 *                                                          *
441
 *                                                          *
405
 ************************************************************
442
 ************************************************************
406
 */
443
 */
407
  else if (OptionMatch("display", *args)) {
444
  else if (OptionMatch("display", *args)) {
408
    if (nargs > 1)
-
 
409
      do {
-
 
410
        if (OptionMatch("time", args[1])) {
-
 
411
          display_options |= 1;
-
 
412
          Print(128, "display time for moves played in game.\n");
-
 
413
        } else if (OptionMatch("notime", args[1])) {
-
 
414
          display_options &= 4095 - 1;
445
    int i, set, old_display_options = display_options;
415
          Print(128, "don't display time for moves played in game.\n");
-
 
416
        } else if (OptionMatch("changes", args[1])) {
-
 
417
          display_options |= 2;
-
 
418
          Print(128, "display PV each time it changes.\n");
-
 
419
        } else if (OptionMatch("nochanges", args[1])) {
-
 
420
          display_options &= 4095 - 2;
-
 
421
          Print(128, "don't display PV each time it changes.\n");
-
 
422
        } else if (OptionMatch("variation", args[1])) {
-
 
423
          display_options |= 4;
-
 
424
          Print(128, "display PV at end of each iteration.\n");
-
 
425
        } else if (OptionMatch("novariation", args[1])) {
-
 
426
          display_options &= 4095 - 4;
-
 
427
          Print(128, "don't display PV at end of each iteration.\n");
-
 
428
        } else if (OptionMatch("stats", args[1])) {
-
 
429
          display_options |= 8;
-
 
430
          Print(128, "display statistics at end of each search.\n");
-
 
431
        } else if (OptionMatch("nostats", args[1])) {
-
 
432
          display_options &= 4095 - 8;
-
 
433
          Print(128, "don't display statistics at end of each search.\n");
446
    char *doptions[8] = { "moveinfo", "pv", "fail", "stats", "moves", "info",
434
        } else if (OptionMatch("extstats", args[1])) {
-
 
435
          display_options |= 16;
447
      "ply1", "movelist"
436
          Print(128, "display extended statistics at end of each search.\n");
-
 
437
        } else if (OptionMatch("noextstats", args[1])) {
-
 
438
          display_options &= 4095 - 16;
-
 
439
          Print(128,
448
    };
440
              "don't display extended statistics at end of each search.\n");
-
 
441
        } else if (OptionMatch("movenum", args[1])) {
-
 
442
          display_options |= 64;
-
 
443
          Print(128, "display move numbers in variations.\n");
449
    char *descriptions[8] = { "display move time/results/etc",
444
        } else if (OptionMatch("nomovenum", args[1])) {
-
 
445
          display_options &= 4095 - 64;
-
 
446
          Print(128, "don't display move numbers in variations.\n");
-
 
447
        } else if (OptionMatch("moves", args[1])) {
-
 
448
          display_options |= 32;
-
 
449
          Print(128, "display ply-1 moves as they are searched.\n");
-
 
450
        } else if (OptionMatch("nomoves", args[1])) {
-
 
451
          display_options &= 4095 - 32;
-
 
452
          Print(128, "don't display ply-1 moves as they are searched.\n");
450
      "principal variation", "fail highs/lows", "search statistics",
453
        } else if (OptionMatch("general", args[1])) {
-
 
454
          display_options |= 128;
-
 
455
          Print(128, "display informational messages.\n");
-
 
456
        } else if (OptionMatch("nogeneral", args[1])) {
451
      "root moves as they are searched", "general information",
457
          display_options &= 4095 - 128;
-
 
458
          Print(128, "don't display informational messages.\n");
-
 
459
        } else if (OptionMatch("movelist", args[1])) {
-
 
460
          display_options |= 256;
-
 
461
          Print(128, "display ply-1 move list after each iteration.\n");
452
      "ply1 move list after each iteration",
462
        } else if (OptionMatch("nomovelist", args[1])) {
-
 
463
          display_options &= 4095 - 256;
453
      "root move list and scores prior to search"
464
          Print(128, "don't display ply-1 move list after each iteration.\n");
-
 
465
        } else if (OptionMatch("ply1", args[1])) {
-
 
466
          display_options |= 512;
454
    };
467
          Print(128, "display ply-1 moves/evaluations.\n");
-
 
468
        } else if (OptionMatch("noply1", args[1])) {
-
 
469
          display_options &= 4095 - 512;
-
 
470
          Print(128, "don't display ply-1 moves/evaluations.\n");
-
 
471
        } else if (OptionMatch("everything", args[1])) {
-
 
-
 
455
 
472
          display_options = 4095;
456
    if (nargs > 1) {
473
          Print(128, "display everything (lots of output).\n");
-
 
474
        } else if (OptionMatch("nothing", args[1])) {
457
      if (!strcmp(args[1], "all"))
475
          display_options = 4095 - 1023;
458
        old_display_options = ~display_options;
476
          Print(128, "display nothing.\n");
-
 
477
        } else if (OptionMatch("*", args[1])) {
-
 
478
          if (display_options & 1)
459
      for (i = 0; i < 8; i++) {
479
            printf("display time for moves\n");
-
 
480
          if (display_options & 2)
460
        if (strstr(args[1], doptions[i])) {
481
            printf("display variation when it changes.\n");
-
 
482
          if (display_options & 4)
461
          if (strstr(args[1], "no"))
483
            printf("display variation at end of iteration.\n");
-
 
484
          if (display_options & 8)
462
            set = 0;
485
            printf("display basic search stats.\n");
-
 
486
          if (display_options & 16)
-
 
487
            printf("display extended search stats.\n");
-
 
488
          if (display_options & 32)
463
          else
489
            printf("display ply-1 moves as they are searched.\n");
-
 
490
          if (display_options & 64)
464
            set = 1;
491
            printf("display move numbers in variations.\n");
-
 
492
          if (display_options & 128)
465
          display_options &= ~(1 << i);
493
            printf("display general messages.\n");
-
 
494
          if (display_options & 256)
-
 
495
            printf("display ply-1 node counts every iteration.\n");
-
 
496
          if (display_options & 512)
466
          display_options |= set << i;
497
            printf("display ply-1 moves and evaluations.\n");
-
 
498
        } else
-
 
499
          break;
467
          break;
500
        return 1;
468
        }
-
 
469
      }
-
 
470
      for (i = 0; i < 8; i++) {
-
 
471
        if ((old_display_options & (1 << i)) != (display_options & (1 << i))) {
-
 
472
          Print(32, "display ");
-
 
473
          if (!(display_options & (1 << i)))
-
 
474
            Print(32, "no");
-
 
475
          Print(32, "%s (%s)\n", doptions[i], descriptions[i]);
501
      } while (0);
476
        }
-
 
477
      }
502
    else
478
    } else
503
      DisplayChessBoard(stdout, display);
479
      DisplayChessBoard(stdout, display);
504
  }
480
  }
505
/*
481
/*
506
 ************************************************************
482
 ************************************************************
507
 *                                                          *
483
 *                                                          *
Line 509... Line 485...
509
 *  modified to test some modified code function.           *
485
 *  modified to test some modified code function.           *
510
 *                                                          *
486
 *                                                          *
511
 ************************************************************
487
 ************************************************************
512
 */
488
 */
513
  else if (OptionMatch("debug", *args)) {
489
  else if (OptionMatch("debug", *args)) {
514
    Print(4095, "No debug code added to Option()\n");
490
    Print(32, "ERROR:  no debug code included\n");
515
  }
491
  }
516
/*
492
/*
517
 ************************************************************
493
 ************************************************************
518
 *                                                          *
494
 *                                                          *
519
 *  "depth" command sets a specific search depth to         *
495
 *  "depth" command sets a specific search depth to         *
520
 *  control the tree search depth. [xboard compatibility].  *
496
 *  control the tree search depth. [xboard compatibility].  *
521
 *                                                          *
497
 *                                                          *
522
 ************************************************************
498
 ************************************************************
523
 */
499
 */
524
  else if (!strcmp("depth", *args)) {
500
  else if (OptionMatch("depth", *args)) {
525
    if (nargs < 2) {
501
    if (nargs < 2) {
526
      printf("usage:  depth <n>\n");
502
      printf("usage:  depth <n>\n");
527
      return 1;
503
      return 1;
528
    }
504
    }
529
    search_depth = atoi(args[1]);
505
    search_depth = atoi(args[1]);
530
    Print(128, "search depth set to %d.\n", search_depth);
506
    Print(32, "search depth set to %d.\n", search_depth);
531
  }
507
  }
532
/*
508
/*
533
 ************************************************************
509
 ************************************************************
534
 *                                                          *
510
 *                                                          *
535
 *  "draw" is used to offer Crafty a draw, or to control    *
511
 *  "draw" is used to offer Crafty a draw, or to control    *
Line 540... Line 516...
540
  else if (OptionMatch("draw", *args)) {
516
  else if (OptionMatch("draw", *args)) {
541
    if (nargs == 1) {
517
    if (nargs == 1) {
542
      draw_offer_pending = 1;
518
      draw_offer_pending = 1;
543
      if (draw_offered) {
519
      if (draw_offered) {
544
        Print(4095, "1/2-1/2 {Draw agreed}\n");
520
        Print(4095, "1/2-1/2 {Draw agreed}\n");
545
        strcpy_s(pgn_result, sizeof (pgn_result), "1/2-1/2"); // Pierre-Marie Baty -- use safe version
521
        strcpy(pgn_result, "1/2-1/2");
546
      }
522
      }
547
    } else {
523
    } else {
548
      if (!strcmp(args[1], "accept")) {
524
      if (!strcmp(args[1], "accept")) {
549
        accept_draws = 1;
525
        accept_draws = 1;
550
        Print(128, "accept draw offers\n");
526
        Print(32, "accept draw offers\n");
551
      } else if (!strcmp(args[1], "decline")) {
527
      } else if (!strcmp(args[1], "decline")) {
552
        accept_draws = 0;
528
        accept_draws = 0;
553
        Print(128, "decline draw offers\n");
529
        Print(32, "decline draw offers\n");
-
 
530
      } else if (!strcmp(args[1], "dynamic")) {
-
 
531
        if (nargs > 2)
-
 
532
          dynamic_draw_score = atoi(args[2]);
-
 
533
        Print(32, "dynamic draw scores %s\n",
-
 
534
            (dynamic_draw_score) ? "enabled" : "disabled");
554
      } else if (!strcmp(args[1], "offer")) {
535
      } else if (!strcmp(args[1], "offer")) {
555
        offer_draws = 1;
536
        offer_draws = 1;
556
        Print(128, "offer draws\n");
537
        Print(32, "offer draws\n");
557
      } else if (!strcmp(args[1], "nooffer")) {
538
      } else if (!strcmp(args[1], "nooffer")) {
558
        offer_draws = 0;
539
        offer_draws = 0;
559
        Print(128, "do not offer draws\n");
540
        Print(32, "do not offer draws\n");
560
      } else
541
      } else
561
        Print(128, "usage: draw accept|decline|offer|nooffer\n");
542
        Print(32, "usage: draw accept|decline|offer|nooffer\n");
562
    }
543
    }
563
  }
544
  }
564
/*
545
/*
565
 ************************************************************
546
 ************************************************************
566
 *                                                          *
547
 *                                                          *
Line 570... Line 551...
570
 */
551
 */
571
  else if (OptionMatch("easy", *args)) {
552
  else if (OptionMatch("easy", *args)) {
572
    if (thinking || pondering)
553
    if (thinking || pondering)
573
      return 2;
554
      return 2;
574
    ponder = 0;
555
    ponder = 0;
575
    Print(128, "pondering disabled.\n");
556
    Print(32, "pondering disabled.\n");
576
  }
557
  }
577
/*
558
/*
578
 ************************************************************
559
 ************************************************************
579
 *                                                          *
560
 *                                                          *
580
 *  "echo" command displays messages from command file.     *
561
 *  "echo" command displays messages from command file.     *
Line 588... Line 569...
588
 *                                                          *
569
 *                                                          *
589
 *  "edit" command modifies the board position.             *
570
 *  "edit" command modifies the board position.             *
590
 *                                                          *
571
 *                                                          *
591
 ************************************************************
572
 ************************************************************
592
 */
573
 */
593
  else if (OptionMatch("edit", *args) && strcmp(*args, "ed")) {
574
  else if (OptionMatch("edit", *args)) {
594
    if (thinking || pondering)
575
    if (thinking || pondering)
595
      return 2;
576
      return 2;
596
    Edit();
577
    Edit();
597
    move_number = 1;    /* discard history */
578
    move_number = 1; /* discard history */
598
    if (!game_wtm) {
579
    if (!game_wtm) {
599
      game_wtm = 1;
580
      game_wtm = 1;
600
      Pass();
581
      Pass();
601
    }
582
    }
602
    ponder_move = 0;
583
    ponder_move = 0;
603
    last_pv.pathd = 0;
584
    last_pv.pathd = 0;
604
    last_pv.pathl = 0;
585
    last_pv.pathl = 0;
605
    strcpy_s(buffer, sizeof (buffer), "savepos *"); // Pierre-Marie Baty -- use safe version
586
    strcpy(buffer, "savepos *");
606
    (void) Option(tree);
587
    Option(tree);
607
  }
588
  }
608
/*
589
/*
609
 ************************************************************
590
 ************************************************************
610
 *                                                          *
591
 *                                                          *
611
 *  "egtb" command enables/disables tablebases and sets     *
592
 *  "egtb" command enables/disables tablebases and sets     *
Line 614... Line 595...
614
 ************************************************************
595
 ************************************************************
615
 */
596
 */
616
#if !defined(NOEGTB)
597
#if !defined(NOEGTB)
617
  else if (OptionMatch("egtb", *args)) {
598
  else if (OptionMatch("egtb", *args)) {
618
    if (!EGTB_setup) {
599
    if (!EGTB_setup) {
619
      Print(128, "EGTB access enabled\n");
600
      Print(32, "EGTB access enabled\n");
620
      Print(128, "using tbpath=%s\n", tb_path);
601
      Print(32, "using tbpath=%s\n", tb_path);
621
      EGTBlimit = IInitializeTb(tb_path);
602
      EGTBlimit = IInitializeTb(tb_path);
622
      Print(128, "%d piece tablebase files found\n", EGTBlimit);
603
      Print(32, "%d piece tablebase files found\n", EGTBlimit);
623
      if (0 != cbEGTBCompBytes)
604
      if (0 != cbEGTBCompBytes)
624
        Print(128,
605
        Print(32,
625
            "%dkb of RAM used for TB indices and decompression tables\n",
606
            "%dkb of RAM used for TB indices and decompression tables\n",
626
            (cbEGTBCompBytes + 1023) / 1024);
607
            (cbEGTBCompBytes + 1023) / 1024);
627
      if (EGTBlimit) {
608
      if (EGTBlimit) {
628
        if (!EGTB_cache)
609
        if (!EGTB_cache)
629
          EGTB_cache = malloc(EGTB_cache_size);
610
          EGTB_cache = malloc(EGTB_cache_size);
630
        if (!EGTB_cache) {
611
        if (!EGTB_cache) {
631
          Print(128, "ERROR  EGTB cache malloc failed\n");
612
          Print(32, "ERROR  EGTB cache malloc failed\n");
632
          EGTB_cache = malloc(4096 * 4096);
613
          EGTB_cache = malloc(4096 * 4096);
633
        } else
614
        } else
634
          FTbSetCacheSize(EGTB_cache, EGTB_cache_size);
615
          FTbSetCacheSize(EGTB_cache, EGTB_cache_size);
635
        EGTB_setup = 1;
616
        EGTB_setup = 1;
636
      }
617
      }
Line 638... Line 619...
638
      if (nargs == 1)
619
      if (nargs == 1)
639
        EGTBPV(tree, game_wtm);
620
        EGTBPV(tree, game_wtm);
640
      else if (nargs == 2)
621
      else if (nargs == 2)
641
        EGTBlimit = Min(atoi(args[1]), 5);
622
        EGTBlimit = Min(atoi(args[1]), 5);
642
    }
623
    }
-
 
624
  }
-
 
625
/*
-
 
626
 ************************************************************
-
 
627
 *                                                          *
-
 
628
 *  "egtbd" command sets the probe depth limit.  If the     *
-
 
629
 *  remaining depth is < this limit, probes are not done to *
-
 
630
 *  avoid slowing the search unnecessarily.                 *
-
 
631
 *                                                          *
-
 
632
 ************************************************************
-
 
633
 */
-
 
634
  else if (OptionMatch("egtbd", *args)) {
-
 
635
    if (nargs > 1)
-
 
636
      EGTB_depth = atoi(args[1]);
-
 
637
    Print(32, "EGTB probe depth set to %d\n", EGTB_depth);
643
  }
638
  }
644
#endif
639
#endif
645
/*
640
/*
646
 ************************************************************
641
 ************************************************************
647
 *                                                          *
642
 *                                                          *
Line 692... Line 687...
692
      return 0;
687
      return 0;
693
    if (input_stream != stdin)
688
    if (input_stream != stdin)
694
      fclose(input_stream);
689
      fclose(input_stream);
695
    input_stream = stdin;
690
    input_stream = stdin;
696
    ReadClear();
691
    ReadClear();
697
    Print(128, "\n");
692
    Print(32, "\n");
698
  }
693
  }
699
/*
694
/*
700
 ************************************************************
695
 ************************************************************
701
 *                                                          *
696
 *                                                          *
702
 *  "flag" command controls whether Crafty will call the    *
697
 *  "flag" command controls whether Crafty will call the    *
703
 *  flag in xboard/winboard games (to end the game.)        *
698
 *  flag in xboard/winboard games (to end the game.)        *
704
 *                                                          *
699
 *                                                          *
705
 ************************************************************
700
 ************************************************************
706
 */
701
 */
707
  else if (!strcmp("flag", *args)) {
702
  else if (OptionMatch("flag", *args)) {
708
    if (nargs < 2) {
703
    if (nargs < 2) {
709
      printf("usage:  flag on|off\n");
704
      printf("usage:  flag on|off\n");
710
      return 1;
705
      return 1;
711
    }
706
    }
712
    if (!strcmp(args[1], "on"))
707
    if (!strcmp(args[1], "on"))
713
      call_flag = 1;
708
      call_flag = 1;
714
    else if (!strcmp(args[1], "off"))
709
    else if (!strcmp(args[1], "off"))
715
      call_flag = 0;
710
      call_flag = 0;
716
    if (call_flag)
711
    if (call_flag)
717
      Print(128, "end game on time forfeits\n");
712
      Print(32, "end game on time forfeits\n");
718
    else
713
    else
719
      Print(128, "ignore time forfeits\n");
714
      Print(32, "ignore time forfeits\n");
720
  }
715
  }
721
/*
716
/*
722
 ************************************************************
717
 ************************************************************
723
 *                                                          *
718
 *                                                          *
724
 *  "flip" command flips the board, interchanging each      *
719
 *  "flip" command flips the board, interchanging each      *
Line 802... Line 797...
802
    last_pv.pathl = 0;
797
    last_pv.pathl = 0;
803
    save_move_number = move_number;
798
    save_move_number = move_number;
804
    movenum = move_number;
799
    movenum = move_number;
805
    if (game_wtm)
800
    if (game_wtm)
806
      movenum--;
801
      movenum--;
807
    strcpy_s(text, sizeof (text), args[1]); // Pierre-Marie Baty -- use safe version
802
    strcpy(text, args[1]);
808
    sprintf_s(buffer, sizeof (buffer), "reset %d", movenum); // Pierre-Marie Baty -- use safe version
803
    sprintf(buffer, "reset %d", movenum);
809
    game_wtm = Flip(game_wtm);
804
    game_wtm = Flip(game_wtm);
810
    (void) Option(tree);
805
    Option(tree);
811
    move = InputMove(tree, text, 0, game_wtm, 0, 0);
806
    move = InputMove(tree, 0, game_wtm, 0, 0, text);
812
    if (move) {
807
    if (move) {
813
      if (input_stream != stdin)
808
      if (input_stream != stdin)
814
        printf("%s\n", OutputMove(tree, move, 0, game_wtm));
809
        printf("%s\n", OutputMove(tree, 0, game_wtm, move));
815
      if (history_file) {
810
      if (history_file) {
816
        fseek(history_file, ((movenum - 1) * 2 + 1 - game_wtm) * 10,
811
        fseek(history_file, ((movenum - 1) * 2 + 1 - game_wtm) * 10,
817
            SEEK_SET);
812
            SEEK_SET);
818
        fprintf(history_file, "%9s\n", OutputMove(tree, move, 0, game_wtm));
813
        fprintf(history_file, "%9s\n", OutputMove(tree, 0, game_wtm, move));
819
      }
814
      }
820
      MakeMoveRoot(tree, move, game_wtm);
815
      MakeMoveRoot(tree, game_wtm, move);
821
      last_pv.pathd = 0;
816
      last_pv.pathd = 0;
822
      last_pv.pathl = 0;
817
      last_pv.pathl = 0;
823
    } else if (input_stream == stdin)
818
    } else if (input_stream == stdin)
824
      printf("illegal move.\n");
819
      printf("illegal move.\n");
825
    game_wtm = Flip(game_wtm);
820
    game_wtm = Flip(game_wtm);
826
    move_number = save_move_number;
821
    move_number = save_move_number;
827
    strcpy_s(hint, sizeof (hint), "none"); // Pierre-Marie Baty -- use safe version
822
    strcpy(ponder_text, "none");
828
  }
823
  }
829
/*
824
/*
830
 ************************************************************
825
 ************************************************************
831
 *                                                          *
826
 *                                                          *
832
 *  "go" command does nothing, except force main() to start *
827
 *  "go" command does nothing, except force main() to start *
833
 *  a search.  ("move" is an alias for go).                 *
828
 *  a search.  ("move" is an alias for go).                 *
834
 *                                                          *
829
 *                                                          *
835
 ************************************************************
830
 ************************************************************
836
 */
831
 */
837
  else if (OptionMatch("go", *args) || OptionMatch("move", *args)) {
832
  else if (OptionMatch("go", *args) || OptionMatch("move", *args)) {
-
 
833
    int t;
838
    char temp[128];
834
    char temp[128];
839
 
835
 
840
    if (thinking || pondering)
836
    if (thinking || pondering)
841
      return 2;
837
      return 2;
842
    if (game_wtm) {
838
    if (game_wtm) {
843
      if (strncmp(pgn_white, "Crafty", 6)) {
839
      if (strncmp(pgn_white, "Crafty", 6)) {
844
        strcpy_s(temp, sizeof (temp), pgn_white); // Pierre-Marie Baty -- use safe version
840
        strcpy(temp, pgn_white);
845
        strcpy_s(pgn_white, sizeof (pgn_white), pgn_black); // Pierre-Marie Baty -- use safe version
841
        strcpy(pgn_white, pgn_black);
846
        strcpy_s(pgn_black, sizeof (pgn_black), temp); // Pierre-Marie Baty -- use safe version
842
        strcpy(pgn_black, temp);
847
      }
843
      }
848
    } else {
844
    } else {
849
      if (strncmp(pgn_black, "Crafty", 6)) {
845
      if (strncmp(pgn_black, "Crafty", 6)) {
850
        strcpy_s(temp, sizeof (temp), pgn_white); // Pierre-Marie Baty -- use safe version
846
        strcpy(temp, pgn_white);
851
        strcpy_s(pgn_white, sizeof (pgn_white), pgn_black); // Pierre-Marie Baty -- use safe version
847
        strcpy(pgn_white, pgn_black);
852
        strcpy_s(pgn_black, sizeof (pgn_black), temp); // Pierre-Marie Baty -- use safe version
848
        strcpy(pgn_black, temp);
853
      }
849
      }
854
    }
850
    }
-
 
851
    t = tc_time_remaining[white];
-
 
852
    tc_time_remaining[white] = tc_time_remaining[black];
-
 
853
    tc_time_remaining[black] = t;
-
 
854
    t = tc_moves_remaining[white];
-
 
855
    tc_moves_remaining[white] = tc_moves_remaining[black];
-
 
856
    tc_moves_remaining[black] = t;
855
    force = 0;
857
    force = 0;
856
    return -1;
858
    return -1;
857
  }
859
  }
858
/*
860
/*
859
 ************************************************************
861
 ************************************************************
Line 868... Line 870...
868
 
870
 
869
    if (history_file) {
871
    if (history_file) {
870
      printf("    white       black\n");
872
      printf("    white       black\n");
871
      for (i = 0; i < (move_number - 1) * 2 - game_wtm + 1; i++) {
873
      for (i = 0; i < (move_number - 1) * 2 - game_wtm + 1; i++) {
872
        fseek(history_file, i * 10, SEEK_SET);
874
        fseek(history_file, i * 10, SEEK_SET);
873
        fscanf(history_file, "%s", buffer);
875
        v = fscanf(history_file, "%s", buffer);
-
 
876
        if (v <= 0)
-
 
877
          perror("Option() fscanf error: ");
874
        if (!(i % 2))
878
        if (!(i % 2))
875
          printf("%3d", i / 2 + 1);
879
          printf("%3d", i / 2 + 1);
876
        printf("  %-10s", buffer);
880
        printf("  %-10s", buffer);
877
        if (i % 2 == 1)
881
        if (i % 2 == 1)
878
          printf("\n");
882
          printf("\n");
Line 888... Line 892...
888
 *                                                          *
892
 *                                                          *
889
 ************************************************************
893
 ************************************************************
890
 */
894
 */
891
  else if (OptionMatch("hard", *args)) {
895
  else if (OptionMatch("hard", *args)) {
892
    ponder = 1;
896
    ponder = 1;
893
    Print(128, "pondering enabled.\n");
897
    Print(32, "pondering enabled.\n");
894
  }
898
  }
895
/*
899
/*
896
 ************************************************************
900
 ************************************************************
897
 *                                                          *
901
 *                                                          *
898
 *  "hash" command controls the transposition table size.   *
902
 *  "hash" command controls the transposition table size.   *
899
 *  The size can be entered in one of three ways:           *
903
 *  The size can be entered in one of four ways:            *
900
 *                                                          *
904
 *                                                          *
901
 *     hash=nnn  where nnn is in bytes.                     *
905
 *     hash=nnn  where nnn is in bytes.                     *
902
 *     hash=nnnK where nnn is in K bytes.                   *
906
 *     hash=nnnK where nnn is in K bytes.                   *
903
 *     hash=nnnM where nnn is in M bytes.                   *
907
 *     hash=nnnM where nnn is in M bytes.                   *
-
 
908
 *     hash=nnnG where nnn is in G bytes.                   *
904
 *                                                          *
909
 *                                                          *
905
 *  the only restriction is that the hash table is computed *
910
 *  the only restriction is that the hash table is computed *
906
 *  as a perfect power of 2.  Any value that is not a       *
911
 *  as a perfect power of 2.  Any value that is not a       *
907
 *  perfect power of 2 is rounded down so that it is, in    *
912
 *  perfect power of 2 is rounded down so that it is, in    *
908
 *  order to avoid breaking the addressing scheme.          *
913
 *  order to avoid breaking the addressing scheme.          *
909
 *                                                          *
914
 *                                                          *
910
 ************************************************************
915
 ************************************************************
911
 */
916
 */
912
  else if (OptionMatch("hash", *args)) {
917
  else if (OptionMatch("hash", *args)) {
913
    size_t new_hash_size;
918
    size_t old_hash_size = hash_table_size, new_hash_size;
914
 
919
 
915
    if (thinking || pondering)
920
    if (thinking || pondering)
916
      return 2;
921
      return 2;
917
    if (nargs > 1) {
922
    if (nargs > 1) {
918
      allow_memory = 0;
923
      allow_memory = 0;
-
 
924
      if (xboard)
919
      Print(4095, "Warning--  xboard 'memory' option disabled\n");
925
        Print(4095, "Warning--  xboard 'memory' option disabled\n");
920
      new_hash_size = (size_t) atoiKM(args[1]); // Pierre-Marie Baty -- added type cast
926
      new_hash_size = (size_t) atoiKMB(args[1]); // Pierre-Marie Baty -- added type cast
921
      if (new_hash_size < 64 * 1024) {
927
      if (new_hash_size < 64 * 1024) {
922
        printf("ERROR.  Minimum hash table size is 64K bytes.\n");
928
        printf("ERROR.  Minimum hash table size is 64K bytes.\n");
923
        return 1;
929
        return 1;
924
      }
930
      }
925
      hash_table_size = ((1ull) << MSB(new_hash_size)) / sizeof(HASH_ENTRY);
931
      hash_table_size = ((1ull) << MSB(new_hash_size)) / 16;
926
      AlignedRemalloc((void **) &trans_ref, 64,
932
      AlignedRemalloc((void *) ((void *) &hash_table), 64,
927
          sizeof(HASH_ENTRY) * hash_table_size);
933
          hash_table_size * sizeof(HASH_ENTRY));
928
      if (!trans_ref) {
934
      if (!hash_table) {
929
        printf("AlignedRemalloc() failed, not enough memory.\n");
935
        printf("AlignedRemalloc() failed, not enough memory.\n");
930
        exit(1);
936
        exit(1);
931
      }
937
      }
932
      hash_mask = ((1ull << (MSB((uint64_t) hash_table_size) - 2)) - 1) << 2;
938
      hash_mask = (hash_table_size - 1) & ~3;
933
      InitializeHashTables();
-
 
934
    }
939
    }
935
    Print(128, "hash table memory = %s bytes",
940
    Print(32, "hash table memory = %s bytes",
936
        PrintKM(hash_table_size * sizeof(HASH_ENTRY), 1));
941
        DisplayKMB(hash_table_size * sizeof(HASH_ENTRY), 1));
937
    Print(128, " (%s entries).\n", PrintKM(hash_table_size, 1));
942
    Print(32, " (%s entries).\n", DisplayKMB(hash_table_size, 1));
-
 
943
    InitializeHashTables(old_hash_size != hash_table_size);
938
  }
944
  }
939
/*
945
/*
940
 ************************************************************
946
 ************************************************************
941
 *                                                          *
947
 *                                                          *
942
 *  "phash" command controls the path hash table size. The  *
948
 *  "phash" command controls the path hash table size. The  *
943
 *  size can be entered in one of three ways:               *
949
 *  size can be entered in one of four ways:                *
944
 *                                                          *
950
 *                                                          *
945
 *     phash=nnn  where nnn is in bytes.                    *
951
 *     phash=nnn  where nnn is in bytes.                    *
946
 *     phash=nnnK where nnn is in K bytes.                  *
952
 *     phash=nnnK where nnn is in K bytes.                  *
947
 *     phash=nnnM where nnn is in M bytes.                  *
953
 *     phash=nnnM where nnn is in M bytes.                  *
-
 
954
 *     phash=nnnG where nnn is in G bytes.                  *
948
 *                                                          *
955
 *                                                          *
949
 *  the only restriction is that the path hash table must   *
956
 *  the only restriction is that the path hash table must   *
950
 *  have a perfect power of 2 entries.  The value entered   *
957
 *  have a perfect power of 2 entries.  The value entered   *
951
 *  will be rounded down to meet that requirement.          *
958
 *  will be rounded down to meet that requirement.          *
952
 *                                                          *
959
 *                                                          *
953
 ************************************************************
960
 ************************************************************
954
 */
961
 */
955
  else if (OptionMatch("phash", *args)) {
962
  else if (OptionMatch("phash", *args)) {
956
    size_t new_hash_size;
963
    size_t old_hash_size = hash_path_size, new_hash_size;
957
    size_t i; // Pierre-Marie Baty -- fixed type
-
 
958
 
964
 
959
    if (thinking || pondering)
965
    if (thinking || pondering)
960
      return 2;
966
      return 2;
961
    if (nargs > 1) {
967
    if (nargs > 1) {
962
      new_hash_size = (size_t) atoiKM(args[1]); // Pierre-Marie Baty -- added type cast
968
      new_hash_size = (size_t) atoiKMB(args[1]); // Pierre-Marie Baty -- added type cast
963
      if (new_hash_size < 64 * 1024) {
969
      if (new_hash_size < 64 * 1024) {
964
        printf("ERROR.  Minimum phash table size is 64K bytes.\n");
970
        printf("ERROR.  Minimum phash table size is 64K bytes.\n");
965
        return 1;
971
        return 1;
966
      }
972
      }
967
      hash_path_size = ((1ull) << MSB(new_hash_size / sizeof(HPATH_ENTRY)));
973
      hash_path_size = ((1ull) << MSB(new_hash_size / sizeof(HPATH_ENTRY)));
968
      AlignedRemalloc((void **) &hash_path, 64,
974
      AlignedRemalloc((void *) ((void *) &hash_path), 64,
969
          sizeof(HPATH_ENTRY) * hash_path_size);
975
          sizeof(HPATH_ENTRY) * hash_path_size);
970
      if (!hash_path) {
976
      if (!hash_path) {
971
        printf("AlignedRemalloc() failed, not enough memory.\n");
977
        printf("AlignedRemalloc() failed, not enough memory.\n");
972
        hash_path_size = 0;
978
        hash_path_size = 0;
973
        hash_path = 0;
979
        hash_path = 0;
974
      }
980
      }
975
      hash_path_mask = (hash_path_size - 1) & ~15;
981
      hash_path_mask = (hash_path_size - 1) & ~15;
976
      for (i = 0; i < hash_path_size; i++)
-
 
977
        (hash_path + i)->hash_path_age = -99;
-
 
978
    }
982
    }
979
    Print(128, "hash path table memory = %s bytes",
983
    Print(32, "hash path table memory = %s bytes",
980
        PrintKM(hash_path_size * sizeof(HPATH_ENTRY), 1));
984
        DisplayKMB(hash_path_size * sizeof(HPATH_ENTRY), 1));
981
    Print(128, " (%s entries).\n", PrintKM(hash_path_size, 1));
985
    Print(32, " (%s entries).\n", DisplayKMB(hash_path_size, 1));
-
 
986
    InitializeHashTables(old_hash_size != hash_path_size);
982
  }
987
  }
983
/*
988
/*
984
 ************************************************************
989
 ************************************************************
985
 *                                                          *
990
 *                                                          *
986
 *  "hashp" command controls the pawn hash table size.      *
991
 *  "hashp" command controls the pawn hash table size.      *
987
 *                                                          *
992
 *                                                          *
988
 ************************************************************
993
 ************************************************************
989
 */
994
 */
990
  else if (OptionMatch("hashp", *args)) {
995
  else if (OptionMatch("hashp", *args)) {
991
    size_t i; // Pierre-Marie Baty -- fixed type
996
    size_t old_hash_size = pawn_hash_table_size, new_hash_size;
992
    size_t new_hash_size;
-
 
993
 
997
 
994
    if (thinking || pondering)
998
    if (thinking || pondering)
995
      return 2;
999
      return 2;
996
    if (nargs > 1) {
1000
    if (nargs > 1) {
997
      allow_memory = 0;
1001
      allow_memory = 0;
-
 
1002
      if (xboard)
998
      Print(4095, "Warning--  xboard 'memory' option disabled\n");
1003
        Print(4095, "Warning--  xboard 'memory' option disabled\n");
999
      new_hash_size = (size_t) atoiKM(args[1]); // Pierre-Marie Baty -- added type cast
1004
      new_hash_size = (size_t) atoiKMB(args[1]); // Pierre-Marie Baty -- added type cast
1000
      if (new_hash_size < 16 * 1024) {
1005
      if (new_hash_size < 16 * 1024) {
1001
        printf("ERROR.  Minimum pawn hash table size is 16K bytes.\n");
1006
        printf("ERROR.  Minimum pawn hash table size is 16K bytes.\n");
1002
        return 1;
1007
        return 1;
1003
      }
1008
      }
1004
      pawn_hash_table_size =
1009
      pawn_hash_table_size =
1005
          (1ull << MSB(new_hash_size)) / sizeof(PAWN_HASH_ENTRY);
1010
          1ull << MSB(new_hash_size / sizeof(PAWN_HASH_ENTRY));
1006
      AlignedRemalloc((void **) &pawn_hash_table, 32,
1011
      AlignedRemalloc((void *) ((void *) &pawn_hash_table), 64,
1007
          sizeof(PAWN_HASH_ENTRY) * pawn_hash_table_size);
1012
          sizeof(PAWN_HASH_ENTRY) * pawn_hash_table_size);
1008
      if (!pawn_hash_table) {
1013
      if (!pawn_hash_table) {
1009
        printf("AlignedRemalloc() failed, not enough memory.\n");
1014
        printf("AlignedRemalloc() failed, not enough memory.\n");
1010
        exit(1);
1015
        exit(1);
1011
      }
1016
      }
1012
      pawn_hash_mask = (1ull << MSB((uint64_t) pawn_hash_table_size)) - 1;
1017
      pawn_hash_mask = pawn_hash_table_size - 1;
-
 
1018
    }
1013
      for (i = 0; i < pawn_hash_table_size; i++) {
1019
    Print(32, "pawn hash table memory = %s bytes",
1014
        (pawn_hash_table + i)->key = 0;
1020
        DisplayKMB(pawn_hash_table_size * sizeof(PAWN_HASH_ENTRY), 1));
1015
        (pawn_hash_table + i)->score_mg = 0;
1021
    Print(32, " (%s entries).\n", DisplayKMB(pawn_hash_table_size, 1));
1016
        (pawn_hash_table + i)->score_eg = 0;
1022
    InitializeHashTables(old_hash_size != pawn_hash_table_size);
-
 
1023
  }
-
 
1024
/*
-
 
1025
 ************************************************************
1017
        (pawn_hash_table + i)->defects_k[white] = 0;
1026
 *                                                          *
1018
        (pawn_hash_table + i)->defects_q[white] = 0;
1027
 *  "hashe" command controls the eval hash table size.      *
1019
        (pawn_hash_table + i)->defects_d[white] = 0;
1028
 *                                                          *
-
 
1029
 ************************************************************
-
 
1030
 */
-
 
1031
  else if (OptionMatch("hashe", *args)) {
1020
        (pawn_hash_table + i)->defects_e[white] = 0;
1032
    size_t old_hash_size = eval_hash_table_size, new_hash_size;
-
 
1033
 
-
 
1034
    if (thinking || pondering)
-
 
1035
      return 2;
-
 
1036
    if (nargs > 1) {
1021
        (pawn_hash_table + i)->all[white] = 0;
1037
      allow_memory = 0;
-
 
1038
      if (xboard)
-
 
1039
        Print(4095, "Warning--  xboard 'memory' option disabled\n");
-
 
1040
      new_hash_size = (size_t) atoiKMB(args[1]); // Pierre-Marie Baty -- added type cast
1022
        (pawn_hash_table + i)->passed[white] = 0;
1041
      if (new_hash_size < 16 * 1024) {
1023
        (pawn_hash_table + i)->defects_k[black] = 0;
1042
        printf("ERROR.  Minimum eval hash table size is 16K bytes.\n");
-
 
1043
        return 1;
-
 
1044
      }
1024
        (pawn_hash_table + i)->defects_q[black] = 0;
1045
      eval_hash_table_size = 1ull << MSB(new_hash_size / sizeof(uint64_t));
1025
        (pawn_hash_table + i)->defects_d[black] = 0;
1046
      AlignedRemalloc((void *) ((void *) &eval_hash_table), 64,
1026
        (pawn_hash_table + i)->defects_e[black] = 0;
1047
          sizeof(uint64_t) * eval_hash_table_size);
1027
        (pawn_hash_table + i)->all[black] = 0;
1048
      if (!eval_hash_table) {
1028
        (pawn_hash_table + i)->passed[black] = 0;
1049
        printf("AlignedRemalloc() failed, not enough memory.\n");
-
 
1050
        exit(1);
1029
      }
1051
      }
-
 
1052
      eval_hash_mask = eval_hash_table_size - 1;
1030
    }
1053
    }
1031
    Print(128, "pawn hash table memory = %s bytes",
1054
    Print(32, "eval hash table memory = %s bytes",
1032
        PrintKM(pawn_hash_table_size * sizeof(PAWN_HASH_ENTRY), 1));
1055
        DisplayKMB(eval_hash_table_size * sizeof(uint64_t), 1));
1033
    Print(128, " (%s entries).\n", PrintKM(pawn_hash_table_size, 1));
1056
    Print(32, " (%s entries).\n", DisplayKMB(eval_hash_table_size, 1));
-
 
1057
    InitializeHashTables(old_hash_size != eval_hash_table_size);
1034
  }
1058
  }
1035
/*
1059
/*
1036
 ************************************************************
1060
 ************************************************************
1037
 *                                                          *
1061
 *                                                          *
1038
 *  "help" command lists commands/options.                  *
1062
 *  "help" command lists commands/options.                  *
Line 1042... Line 1066...
1042
  else if (OptionMatch("help", *args)) {
1066
  else if (OptionMatch("help", *args)) {
1043
    FILE *helpfile;
1067
    FILE *helpfile;
1044
    char *readstat = (char *) -1;
1068
    char *readstat = (char *) -1;
1045
    int lines = 0;
1069
    int lines = 0;
1046
 
1070
 
1047
    fopen_s (&helpfile, "crafty.hlp", "r"); // Pierre-Marie Baty -- use safe version
1071
    helpfile = fopen("crafty.hlp", "r");
1048
    if (!helpfile) {
1072
    if (!helpfile) {
1049
      printf("ERROR.  Unable to open \"crafty.hlp\" -- help unavailable\n");
1073
      printf("ERROR.  Unable to open \"crafty.hlp\" -- help unavailable\n");
1050
      return 1;
1074
      return 1;
1051
    }
1075
    }
1052
    if (nargs > 1) {
1076
    if (nargs > 1) {
Line 1075... Line 1099...
1075
      lines++;
1099
      lines++;
1076
      if (lines > 22) {
1100
      if (lines > 22) {
1077
        lines = 0;
1101
        lines = 0;
1078
        printf("<return> for more...");
1102
        printf("<return> for more...");
1079
        fflush(stdout);
1103
        fflush(stdout);
1080
        (void) Read(1, buffer, sizeof (buffer));
1104
        Read(1, buffer);
1081
      }
1105
      }
1082
    }
1106
    }
1083
    fclose(helpfile);
1107
    fclose(helpfile);
1084
  }
1108
  }
1085
/*
1109
/*
Line 1088... Line 1112...
1088
 *  "hint" displays the expected move based on the last     *
1112
 *  "hint" displays the expected move based on the last     *
1089
 *  search done. [xboard compatibility]                     *
1113
 *  search done. [xboard compatibility]                     *
1090
 *                                                          *
1114
 *                                                          *
1091
 ************************************************************
1115
 ************************************************************
1092
 */
1116
 */
1093
  else if (!strcmp("hint", *args)) {
1117
  else if (OptionMatch("hint", *args)) {
1094
    if (strlen(hint)) {
1118
    if (strlen(ponder_text)) {
1095
      printf("Hint: %s\n", hint);
1119
      printf("Hint: %s\n", ponder_text);
1096
      fflush(stdout);
1120
      fflush(stdout);
1097
    }
1121
    }
1098
  }
1122
  }
1099
/*
1123
/*
1100
 ************************************************************
1124
 ************************************************************
Line 1111... Line 1135...
1111
    nargs = ReadParse(buffer, args, " \t=");
1135
    nargs = ReadParse(buffer, args, " \t=");
1112
    if (nargs < 2) {
1136
    if (nargs < 2) {
1113
      printf("usage:  input <filename>\n");
1137
      printf("usage:  input <filename>\n");
1114
      return 1;
1138
      return 1;
1115
    }
1139
    }
1116
    fopen_s(&input_stream, args[1], "r"); // Pierre-Marie Baty -- use safe version
-
 
1117
    if (!input_stream) {
1140
    if (!(input_stream = fopen(args[1], "r"))) {
1118
      printf("file does not exist.\n");
1141
      printf("file does not exist.\n");
1119
      input_stream = stdin;
1142
      input_stream = stdin;
1120
    }
1143
    }
1121
  }
1144
  }
1122
/*
1145
/*
Line 1125... Line 1148...
1125
 *  "info" command gives some information about Crafty.     *
1148
 *  "info" command gives some information about Crafty.     *
1126
 *                                                          *
1149
 *                                                          *
1127
 ************************************************************
1150
 ************************************************************
1128
 */
1151
 */
1129
  else if (OptionMatch("info", *args)) {
1152
  else if (OptionMatch("info", *args)) {
1130
    Print(128, "Crafty version %s\n", version);
1153
    Print(32, "Crafty version %s\n", version);
1131
    Print(128, "number of threads =         %2d\n", smp_max_threads);
1154
    Print(32, "number of threads =         %2d\n", smp_max_threads);
1132
    Print(128, "hash table memory =      %5s\n",
1155
    Print(32, "hash table memory = %s bytes", DisplayKMB(hash_table_size * 64,
-
 
1156
            1));
1133
        PrintKM(hash_table_size * sizeof(HASH_ENTRY), 1));
1157
    Print(32, " (%s entries).\n", DisplayKMB(hash_table_size * 5, 0));
1134
    Print(128, "pawn hash table memory = %5s\n",
1158
    Print(32, "pawn hash table memory = %5s\n",
1135
        PrintKM(pawn_hash_table_size * sizeof(PAWN_HASH_ENTRY), 1));
1159
        DisplayKMB(pawn_hash_table_size * sizeof(PAWN_HASH_ENTRY), 1));
1136
#if !defined(NOEGTB)
1160
#if !defined(NOEGTB)
1137
    Print(128, "EGTB cache memory =      %5s\n", PrintKM(EGTB_cache_size, 1));
1161
    Print(32, "EGTB cache memory =      %5s\n", DisplayKMB(EGTB_cache_size,
-
 
1162
            1));
1138
#endif
1163
#endif
1139
    if (!tc_sudden_death) {
1164
    if (!tc_sudden_death) {
1140
      Print(128, "%d moves/%d minutes %d seconds primary time control\n",
1165
      Print(32, "%d moves/%d minutes %d seconds primary time control\n",
1141
          tc_moves, tc_time / 6000, (tc_time / 100) % 60);
1166
          tc_moves, tc_time / 6000, (tc_time / 100) % 60);
1142
      Print(128, "%d moves/%d minutes %d seconds secondary time control\n",
1167
      Print(32, "%d moves/%d minutes %d seconds secondary time control\n",
1143
          tc_secondary_moves, tc_secondary_time / 6000,
1168
          tc_secondary_moves, tc_secondary_time / 6000,
1144
          (tc_secondary_time / 100) % 60);
1169
          (tc_secondary_time / 100) % 60);
1145
      if (tc_increment)
1170
      if (tc_increment)
1146
        Print(128, "increment %d seconds.\n", tc_increment / 100);
1171
        Print(32, "increment %d seconds.\n", tc_increment / 100);
1147
    } else if (tc_sudden_death == 1) {
1172
    } else if (tc_sudden_death == 1) {
1148
      Print(128, " game/%d minutes primary time control\n", tc_time / 6000);
1173
      Print(32, " game/%d minutes primary time control\n", tc_time / 6000);
1149
      if (tc_increment)
1174
      if (tc_increment)
1150
        Print(128, "increment %d seconds.\n", (tc_increment / 100) % 60);
1175
        Print(32, "increment %d seconds.\n", (tc_increment / 100) % 60);
1151
    } else if (tc_sudden_death == 2) {
1176
    } else if (tc_sudden_death == 2) {
1152
      Print(128, "%d moves/%d minutes primary time control\n", tc_moves,
1177
      Print(32, "%d moves/%d minutes primary time control\n", tc_moves,
1153
          tc_time / 6000);
1178
          tc_time / 6000);
1154
      Print(128, "game/%d minutes secondary time control\n",
1179
      Print(32, "game/%d minutes secondary time control\n",
1155
          tc_secondary_time / 6000);
1180
          tc_secondary_time / 6000);
1156
      if (tc_increment)
1181
      if (tc_increment)
1157
        Print(128, "increment %d seconds.\n", tc_increment / 100);
1182
        Print(32, "increment %d seconds.\n", tc_increment / 100);
1158
    }
1183
    }
1159
    Print(128, "book frequency (freq)..............%4.2f\n",
1184
    Print(32, "book frequency (freq)..............%4.2f\n", book_weight_freq);
1160
        book_weight_freq);
-
 
1161
    Print(128, "book static evaluation (eval)......%4.2f\n",
1185
    Print(32, "book static evaluation (eval)......%4.2f\n", book_weight_eval);
1162
        book_weight_eval);
-
 
1163
    Print(128, "book learning (learn)..............%4.2f\n",
1186
    Print(32, "book learning (learn)..............%4.2f\n",
1164
        book_weight_learn);
1187
        book_weight_learn);
1165
  }
1188
  }
1166
/*
1189
/*
1167
 ************************************************************
1190
 ************************************************************
1168
 *                                                          *
1191
 *                                                          *
1169
 *  "kibitz" command sets kibitz mode for ICS.  =1 will     *
1192
 *  "kibitz" command sets kibitz mode for ICS.  =1 will     *
1170
 *  kibitz mate announcements, =2 will kibitz scores and    *
1193
 *  kibitz mate announcements, =2 will kibitz scores and    *
1171
 *  other info, =3 will kibitz scores and PV, =4 adds the   *
1194
 *  other info, =3 will kibitz scores and PV, =4 adds the   *
1172
 *  list of book moves, =5 displays the PV after each       *
1195
 *  list of book moves, =5 displays the PV after each       *
1173
 *  iteration completes, and =6 displays the PV each time   *
-
 
1174
 *  it changes in an iteration.                             *
1196
 *  iteration completes.                                    *
1175
 *                                                          *
1197
 *                                                          *
1176
 ************************************************************
1198
 ************************************************************
1177
 */
1199
 */
1178
  else if (OptionMatch("kibitz", *args)) {
1200
  else if (OptionMatch("kibitz", *args)) {
1179
    if (nargs < 2) {
1201
    if (nargs < 2) {
1180
      printf("usage:  kibitz <level>\n");
1202
      printf("usage:  kibitz <level>\n");
1181
      return 1;
1203
      return 1;
1182
    }
1204
    }
1183
    kibitz = atoi(args[1]);
1205
    kibitz = Min(5, atoi(args[1]));
1184
  }
1206
  }
1185
/*
1207
/*
1186
 ************************************************************
1208
 ************************************************************
1187
 *                                                          *
1209
 *                                                          *
1188
 *  "learn" command enables/disables the learning           *
1210
 *  "learn" command enables/disables the learning           *
Line 1202... Line 1224...
1202
        int index[32768], i, j, cluster;
1224
        int index[32768], i, j, cluster;
1203
        unsigned char buf32[4];
1225
        unsigned char buf32[4];
1204
 
1226
 
1205
        fseek(book_file, 0, SEEK_SET);
1227
        fseek(book_file, 0, SEEK_SET);
1206
        for (i = 0; i < 32768; i++) {
1228
        for (i = 0; i < 32768; i++) {
1207
          fread(buf32, 4, 1, book_file);
1229
          v = fread(buf32, 4, 1, book_file);
-
 
1230
          if (v <= 0)
-
 
1231
            perror("Option() fread error: ");
1208
          index[i] = BookIn32(buf32);
1232
          index[i] = BookIn32(buf32);
1209
        }
1233
        }
1210
        for (i = 0; i < 32768; i++)
1234
        for (i = 0; i < 32768; i++)
1211
          if (index[i] > 0) {
1235
          if (index[i] > 0) {
1212
            fseek(book_file, index[i], SEEK_SET);
1236
            fseek(book_file, index[i], SEEK_SET);
1213
            fread(buf32, 4, 1, book_file);
1237
            v = fread(buf32, 4, 1, book_file);
-
 
1238
            if (v <= 0)
-
 
1239
              perror("Option() fread error: ");
1214
            cluster = BookIn32(buf32);
1240
            cluster = BookIn32(buf32);
-
 
1241
            if (cluster)
1215
            BookClusterIn(book_file, cluster, book_buffer);
1242
              BookClusterIn(book_file, cluster, book_buffer);
1216
            for (j = 0; j < cluster; j++)
1243
            for (j = 0; j < cluster; j++)
1217
              book_buffer[j].learn = 0.0;
1244
              book_buffer[j].learn = 0.0;
1218
            fseek(book_file, index[i] + sizeof(int), SEEK_SET);
1245
            fseek(book_file, index[i] + sizeof(int), SEEK_SET);
-
 
1246
            if (cluster)
1219
            BookClusterOut(book_file, cluster, book_buffer);
1247
              BookClusterOut(book_file, cluster, book_buffer);
1220
          }
1248
          }
1221
      } else {
1249
      } else {
1222
        learning = atoi(args[1]);
1250
        learning = atoi(args[1]);
1223
        learn = (learning > 0) ? 1 : 0;
1251
        learn = (learning > 0) ? 1 : 0;
1224
        if (learning)
1252
        if (learning)
1225
          Print(128, "book learning enabled {-%d,+%d}\n", learning, learning);
1253
          Print(32, "book learning enabled {-%d,+%d}\n", learning, learning);
1226
        else
1254
        else
1227
          Print(128, "book learning disabled\n");
1255
          Print(32, "book learning disabled\n");
1228
      }
1256
      }
1229
    }
1257
    }
1230
  }
1258
  }
1231
/*
1259
/*
1232
 ************************************************************
1260
 ************************************************************
Line 1261... Line 1289...
1261
      tc_secondary_time = tc_time;
1289
      tc_secondary_time = tc_time;
1262
      tc_moves_remaining[white] = tc_moves;
1290
      tc_moves_remaining[white] = tc_moves;
1263
      tc_moves_remaining[black] = tc_moves;
1291
      tc_moves_remaining[black] = tc_moves;
1264
    }
1292
    }
1265
    if (!tc_sudden_death) {
1293
    if (!tc_sudden_death) {
1266
      Print(128, "%d moves/%d seconds primary time control\n", tc_moves,
1294
      Print(32, "%d moves/%d seconds primary time control\n", tc_moves,
1267
          tc_time / 100);
1295
          tc_time / 100);
1268
      Print(128, "%d moves/%d seconds secondary time control\n",
1296
      Print(32, "%d moves/%d seconds secondary time control\n",
1269
          tc_secondary_moves, tc_secondary_time / 100);
1297
          tc_secondary_moves, tc_secondary_time / 100);
1270
      if (tc_increment)
1298
      if (tc_increment)
1271
        Print(128, "increment %d seconds.\n", tc_increment / 100);
1299
        Print(32, "increment %d seconds.\n", tc_increment / 100);
1272
    } else if (tc_sudden_death == 1) {
1300
    } else if (tc_sudden_death == 1) {
1273
      Print(128, " game/%d seconds primary time control\n", tc_time / 100);
1301
      Print(32, " game/%d seconds primary time control\n", tc_time / 100);
1274
      if (tc_increment)
1302
      if (tc_increment)
1275
        Print(128, "increment %d seconds.\n", tc_increment / 100);
1303
        Print(32, "increment %d seconds.\n", tc_increment / 100);
1276
    }
1304
    }
1277
    if (adaptive_hash) {
1305
    if (adaptive_hash) {
-
 
1306
      uint64_t positions_per_move;
1278
      float percent;
1307
      float percent;
1279
      int optimal_hash_size;
1308
      int optimal_hash_size;
1280
      unsigned int positions_per_move; // Pierre-Marie Baty -- fixed type. No sense to make it uint64_t if optimal_hash_size is int.
-
 
1281
 
1309
 
1282
      TimeSet(think);
1310
      TimeSet(think);
1283
      time_limit /= 100;
1311
      time_limit /= 100;
1284
      positions_per_move = time_limit * adaptive_hash / 16;
1312
      positions_per_move = time_limit * adaptive_hash / 16;
1285
      optimal_hash_size = positions_per_move * 16;
1313
      optimal_hash_size = (int) positions_per_move * 16; // Pierre-Marie Baty -- added type cast
1286
      printf("optimal=%d\n", optimal_hash_size);
1314
      printf("optimal=%d\n", optimal_hash_size);
1287
      optimal_hash_size = Max(optimal_hash_size, (int) adaptive_hash_min); // Pierre-Marie Baty -- added type cast
1315
      optimal_hash_size = Max(optimal_hash_size, (int) adaptive_hash_min); // Pierre-Marie Baty -- added type cast
1288
      optimal_hash_size = Min(optimal_hash_size, (int) adaptive_hash_max); // Pierre-Marie Baty -- added type cast
1316
      optimal_hash_size = Min(optimal_hash_size, (int) adaptive_hash_max); // Pierre-Marie Baty -- added type cast
1289
      sprintf_s(buffer, sizeof (buffer), "hash=%d\n", optimal_hash_size); // Pierre-Marie Baty -- use safe version
1317
      sprintf(buffer, "hash=%d\n", optimal_hash_size);
1290
      (void) Option(tree);
1318
      Option(tree);
1291
      percent =
1319
      percent =
1292
          (float) (optimal_hash_size -
1320
          (float) (optimal_hash_size -
1293
          adaptive_hash_min) / (float) (adaptive_hash_max -
1321
          adaptive_hash_min) / (float) (adaptive_hash_max -
1294
          adaptive_hash_min);
1322
          adaptive_hash_min);
1295
      optimal_hash_size =
1323
      optimal_hash_size = (int) // Pierre-Marie Baty -- added type cast
1296
          (int) (adaptive_hashp_min + percent * (adaptive_hashp_max -
1324
          (adaptive_hashp_min + percent * (adaptive_hashp_max -
1297
          adaptive_hashp_min)); // Pierre-Marie Baty -- added type cast
1325
          adaptive_hashp_min));
1298
      optimal_hash_size = Max(optimal_hash_size, (int) adaptive_hashp_min); // Pierre-Marie Baty -- added type cast
1326
      optimal_hash_size = Max(optimal_hash_size, (int) adaptive_hashp_min); // Pierre-Marie Baty -- added type cast
1299
      sprintf_s(buffer, sizeof (buffer), "hashp=%d\n", optimal_hash_size); // Pierre-Marie Baty -- use safe version
1327
      sprintf(buffer, "hashp=%d\n", optimal_hash_size);
1300
      (void) Option(tree);
1328
      Option(tree);
1301
    }
1329
    }
1302
  }
1330
  }
1303
/*
1331
/*
1304
 ************************************************************
1332
 ************************************************************
1305
 *                                                          *
1333
 *                                                          *
Line 1370... Line 1398...
1370
 *  commands direct Crafty to look elsewhere.               *
1398
 *  commands direct Crafty to look elsewhere.               *
1371
 *                                                          *
1399
 *                                                          *
1372
 ************************************************************
1400
 ************************************************************
1373
 */
1401
 */
1374
  else if (OptionMatch("list", *args)) {
1402
  else if (OptionMatch("list", *args)) {
1375
    int i, list, lastent = -1;
-
 
1376
    char **targs;
1403
    char **targs;
1377
    char listname[5][3] = { "AK", "B", "GM", "IM", "SP" };
1404
    char listname[5][3] = { "AK", "B", "GM", "IM", "SP" };
1378
    char **listaddr[] = { AK_list, B_list, GM_list,
1405
    char **listaddr[] = { AK_list, B_list, GM_list,
1379
      IM_list, SP_list
1406
      IM_list, SP_list
1380
    };
1407
    };
-
 
1408
    int i, list, lastent = -1;
-
 
1409
 
1381
    targs = args;
1410
    targs = args;
1382
    for (list = 0; list < 5; list++) {
1411
    for (list = 0; list < 5; list++) {
1383
      if (!strcmp(listname[list], args[1]))
1412
      if (!strcmp(listname[list], args[1]))
1384
        break;
1413
        break;
1385
    }
1414
    }
Line 1395... Line 1424...
1395
          for (i = 0; i < 128; i++)
1424
          for (i = 0; i < 128; i++)
1396
            if (listaddr[list][i]) {
1425
            if (listaddr[list][i]) {
1397
              if (!strcmp(listaddr[list][i], targs[0] + 1)) {
1426
              if (!strcmp(listaddr[list][i], targs[0] + 1)) {
1398
                free(listaddr[list][i]);
1427
                free(listaddr[list][i]);
1399
                listaddr[list][i] = NULL;
1428
                listaddr[list][i] = NULL;
1400
                Print(128, "%s removed from %s list.\n", targs[0] + 1,
1429
                Print(32, "%s removed from %s list.\n", targs[0] + 1,
1401
                    listname[list]);
1430
                    listname[list]);
1402
                break;
1431
                break;
1403
              }
1432
              }
1404
            }
1433
            }
1405
        } else if (targs[0][0] == '+') {
1434
        } else if (targs[0][0] == '+') {
1406
          for (i = 0; i < 128; i++)
1435
          for (i = 0; i < 128; i++)
1407
            if (listaddr[list][i]) {
1436
            if (listaddr[list][i]) {
1408
              if (!strcmp(listaddr[list][i], targs[0] + 1)) {
1437
              if (!strcmp(listaddr[list][i], targs[0] + 1)) {
1409
                Print(128, "Warning: %s is already in %s list.\n",
1438
                Print(32, "Warning: %s is already in %s list.\n",
1410
                    targs[0] + 1, listname[list]);
1439
                    targs[0] + 1, listname[list]);
1411
                break;
1440
                break;
1412
              }
1441
              }
1413
            }
1442
            }
1414
          for (i = 0; i < 128; i++)
1443
          for (i = 0; i < 128; i++)
1415
            if (listaddr[list][i] == NULL)
1444
            if (listaddr[list][i] == NULL)
1416
              break;
1445
              break;
1417
          if (i >= 128)
1446
          if (i >= 128)
1418
            Print(128, "ERROR!  %s list is full at 128 entries\n",
1447
            Print(32, "ERROR!  %s list is full at 128 entries\n",
1419
                listname[list]);
1448
                listname[list]);
1420
          else {
1449
          else {
1421
            listaddr[list][i] = malloc(strlen(targs[0]));
1450
            listaddr[list][i] = malloc(strlen(targs[0]));
1422
            strcpy(listaddr[list][i], targs[0] + 1);
1451
            strcpy(listaddr[list][i], targs[0] + 1);
1423
            Print(128, "%s added to %s list.\n", targs[0] + 1,
1452
            Print(32, "%s added to %s list.\n", targs[0] + 1, listname[list]);
1424
                listname[list]);
-
 
1425
            if (list == 5)
1453
            if (list == 5)
1426
              lastent = i;
1454
              lastent = i;
1427
          }
1455
          }
1428
        } else if (!strcmp(targs[0], "clear")) {
1456
        } else if (!strcmp(targs[0], "clear")) {
1429
          for (i = 0; i < 128; i++) {
1457
          for (i = 0; i < 128; i++) {
Line 1432... Line 1460...
1432
          }
1460
          }
1433
        } else if (!strcmp(targs[0], "book") && lastent != -1) {
1461
        } else if (!strcmp(targs[0], "book") && lastent != -1) {
1434
          char filename[256];
1462
          char filename[256];
1435
          FILE *file;
1463
          FILE *file;
1436
 
1464
 
1437
          strcpy_s(filename, sizeof (filename), book_path); // Pierre-Marie Baty -- use safe version
1465
          strcpy(filename, book_path);
1438
          strcat_s(filename, sizeof (filename), "/"); // Pierre-Marie Baty -- use safe version
1466
          strcat(filename, "/");
1439
          strcat_s(filename, sizeof (filename), targs[1]); // Pierre-Marie Baty -- use safe version
1467
          strcat(filename, targs[1]);
1440
          if (!strstr(args[2], ".bin"))
1468
          if (!strstr(args[2], ".bin"))
1441
            strcat_s(filename, sizeof (filename), ".bin"); // Pierre-Marie Baty -- use safe version
1469
            strcat(filename, ".bin");
1442
          fopen_s (&file, filename, "r"); // Pierre-Marie Baty -- use safe version
1470
          file = fopen(filename, "r");
1443
          if (!file) {
1471
          if (!file) {
1444
            Print(4095, "ERROR  book file %s can not be opened\n", filename);
1472
            Print(4095, "ERROR  book file %s can not be opened\n", filename);
1445
            break;
1473
            break;
1446
          }
1474
          }
1447
          fclose(file);
1475
          fclose(file);
Line 1471... Line 1499...
1471
          printf("error, name must be preceeded by +/- flag.\n");
1499
          printf("error, name must be preceeded by +/- flag.\n");
1472
        nargs--;
1500
        nargs--;
1473
        targs++;
1501
        targs++;
1474
      }
1502
      }
1475
    } else {
1503
    } else {
1476
      Print(128, "%s List:\n", listname[list]);
1504
      Print(32, "%s List:\n", listname[list]);
1477
      for (i = 0; i < 128; i++) {
1505
      for (i = 0; i < 128; i++) {
1478
        if (listaddr[list][i]) {
1506
        if (listaddr[list][i]) {
1479
          Print(128, "%s", listaddr[list][i]);
1507
          Print(32, "%s", listaddr[list][i]);
1480
          if (list == 5) {
1508
          if (list == 5) {
1481
            if (SP_opening_filename[i])
1509
            if (SP_opening_filename[i])
1482
              Print(128, "  book=%s", SP_opening_filename[i]);
1510
              Print(32, "  book=%s", SP_opening_filename[i]);
1483
            if (SP_personality_filename[i])
1511
            if (SP_personality_filename[i])
1484
              Print(128, "  personality=%s", SP_personality_filename[i]);
1512
              Print(32, "  personality=%s", SP_personality_filename[i]);
1485
          }
1513
          }
1486
          Print(128, "\n");
1514
          Print(32, "\n");
1487
        }
1515
        }
1488
      }
1516
      }
-
 
1517
    }
-
 
1518
  }
-
 
1519
/*
-
 
1520
 ************************************************************
-
 
1521
 *                                                          *
-
 
1522
 *  "lmr" command sets the formla parameters that produce   *
-
 
1523
 *  LMR reduction matrix.  The format is:                   *
-
 
1524
 *                                                          *
-
 
1525
 *     lmr <min> <max> <depth bias> <moves bias> <scale>    *
-
 
1526
 *                                                          *
-
 
1527
 *  <min> is the minimum LMR reduction.  This probably      *
-
 
1528
 *  should not be changed from 1, the default.              *
-
 
1529
 *                                                          *
-
 
1530
 *  <max> is the maximum LMR reduction.  If you adjust the  *
-
 
1531
 *  following values, you might need to increase this as it *
-
 
1532
 *  is an absolute clamp and no value can exceed this no    *
-
 
1533
 *  matter what the formula produces.                       *
-
 
1534
 *                                                          *
-
 
1535
 *  <depth_bias> is simply a multiplier that causes depth   *
-
 
1536
 *  to influence the reduction amount more or less (as the  *
-
 
1537
 *  value drops below the value used for <moves bias> below *
-
 
1538
 *  or as it is increased above <moves bias>.  The default  *
-
 
1539
 *  is 2.0.                                                 *
-
 
1540
 *                                                          *
-
 
1541
 *  <moves bias> is simply a multiplier that causes the     *
-
 
1542
 *  number of moves already searched to become more or less *
-
 
1543
 *  important than the remaining depth as above.  The       *
-
 
1544
 *  default is 1.0.                                         *
-
 
1545
 *                                                          *
-
 
1546
 *  <scale> is used to scale the formula back since it uses *
-
 
1547
 *  a logarithmic expression.  The basic idea is to adjust  *
-
 
1548
 *  the above two values to produce the desired "shape" of  *
-
 
1549
 *  the reduction matrix, then adjust this to change the    *
-
 
1550
 *  reduction amounts overall.  The default is 2.9.         *
-
 
1551
 *                                                          *
-
 
1552
 ************************************************************
-
 
1553
 */
-
 
1554
  else if (OptionMatch("lmr", *args)) {
-
 
1555
    int i, j;
-
 
1556
 
-
 
1557
    if ((nargs > 1 && nargs < 6) || nargs > 7) {
-
 
1558
      printf("usage:  lmr <min> <max> <depth bias> <move bias> <scale>\n");
-
 
1559
      return 1;
-
 
1560
    }
-
 
1561
    if (nargs > 1) {
-
 
1562
      LMR_min = atoi(args[1]);
-
 
1563
      LMR_max = Min(atoi(args[2]), 15);
-
 
1564
      LMR_db = atof(args[3]);
-
 
1565
      LMR_mb = atof(args[4]);
-
 
1566
      LMR_s = atof(args[5]);
-
 
1567
      InitializeReductions();
-
 
1568
    }
-
 
1569
    if (nargs > 6) {
-
 
1570
      char *axis = "|||||||||||depth left|||||||||||";
-
 
1571
 
-
 
1572
      Print(32,
-
 
1573
          "LMR values:  %d(min) %d(max) %.2f(depth) %.2f(moves) %.2f(scale).\n",
-
 
1574
          LMR_min, LMR_max, LMR_db, LMR_mb, LMR_s);
-
 
1575
      Print(32, "\n                 LMR reductions[depth][moves]\n");
-
 
1576
      Print(32, "  ----------------------moves searched-----------------\n");
-
 
1577
      Print(32, " |      ");
-
 
1578
      for (i = 0; i < 64; i += 1)
-
 
1579
        Print(32, "%3d", i);
-
 
1580
      Print(32, "\n");
-
 
1581
      for (i = 0; i < 32; i += 1) {
-
 
1582
        Print(32, " %c %3d: ", axis[i], i);
-
 
1583
        for (j = 0; j < 64; j += 1)
-
 
1584
          Print(32, " %2d", LMR[i][j]);
-
 
1585
        Print(32, "\n");
-
 
1586
      }
-
 
1587
    } else {
-
 
1588
 
-
 
1589
      char *axis = "||depth left|||";
-
 
1590
      Print(32,
-
 
1591
          "LMR values:  %d(min) %d(max) %.2f(depth) %.2f(moves) %.2f(scale).\n",
-
 
1592
          LMR_min, LMR_max, LMR_db, LMR_mb, LMR_s);
-
 
1593
      Print(32, "\n                 LMR reductions[depth][moves]\n");
-
 
1594
      Print(32, "  ----------------------moves searched------------------\n");
-
 
1595
      Print(32, " |      ");
-
 
1596
      for (i = 2; i < 64; i += 4)
-
 
1597
        Print(32, "%3d", i);
-
 
1598
      Print(32, "\n");
-
 
1599
      for (i = 3; i < 32; i += 2) {
-
 
1600
        Print(32, " %c %3d: ", axis[(i - 3) / 2], i);
-
 
1601
        for (j = 2; j < 64; j += 4)
-
 
1602
          Print(32, " %2d", LMR[i][j]);
-
 
1603
        Print(32, "\n");
-
 
1604
      }
-
 
1605
      Print(32, "    note:  table is shown compressed, each index is in\n");
-
 
1606
      Print(32, "    units of 1, all rows/columns are not shown above\n");
1489
    }
1607
    }
1490
  }
1608
  }
1491
/*
1609
/*
1492
 ************************************************************
1610
 ************************************************************
1493
 *                                                          *
1611
 *                                                          *
Line 1512... Line 1630...
1512
    }
1630
    }
1513
    if (!(prob_file = fopen(args[1], "r"))) {
1631
    if (!(prob_file = fopen(args[1], "r"))) {
1514
      printf("file does not exist.\n");
1632
      printf("file does not exist.\n");
1515
      return 1;
1633
      return 1;
1516
    }
1634
    }
1517
    strcpy_s(title, sizeof (title), args[2]); // Pierre-Marie Baty -- use safe version
1635
    strcpy(title, args[2]);
1518
    while (!feof(prob_file)) {
1636
    while (!feof(prob_file)) {
1519
      readstat = fgets(buffer, 128, prob_file);
1637
      readstat = fgets(buffer, 128, prob_file);
1520
      if (readstat) {
1638
      if (readstat) {
1521
        char *delim;
1639
        char *delim;
1522
 
1640
 
Line 1547... Line 1665...
1547
      }
1665
      }
1548
      if (readstat == NULL)
1666
      if (readstat == NULL)
1549
        break;
1667
        break;
1550
      nargs = ReadParse(buffer, args, " \t;\n");
1668
      nargs = ReadParse(buffer, args, " \t;\n");
1551
      if (!strcmp(args[0], "setboard")) {
1669
      if (!strcmp(args[0], "setboard")) {
1552
        (void) Option(tree);
1670
        Option(tree);
1553
        break;
1671
        break;
1554
      }
1672
      }
1555
    }
1673
    }
1556
  }
1674
  }
1557
/*
1675
/*
Line 1576... Line 1694...
1576
    }
1694
    }
1577
    if (!strcmp(args[1], "on")) {
1695
    if (!strcmp(args[1], "on")) {
1578
      int id;
1696
      int id;
1579
 
1697
 
1580
      id = InitializeGetLogID();
1698
      id = InitializeGetLogID();
1581
      sprintf_s(log_filename, sizeof (log_filename), "%s/log.%03d", log_path, id); // Pierre-Marie Baty -- use safe version
1699
      sprintf(log_filename, "%s/log.%03d", log_path, id);
1582
      sprintf_s(history_filename, sizeof (history_filename), "%s/game.%03d", log_path, id); // Pierre-Marie Baty -- use safe version
1700
      sprintf(history_filename, "%s/game.%03d", log_path, id);
1583
      fopen_s (&log_file, log_filename, "w"); // Pierre-Marie Baty -- use safe version
1701
      log_file = fopen(log_filename, "w");
1584
      fopen_s (&history_file, history_filename, "w+"); // Pierre-Marie Baty -- use safe version
1702
      history_file = fopen(history_filename, "w+");
1585
    } else if (!strcmp(args[1], "off")) {
1703
    } else if (!strcmp(args[1], "off")) {
1586
      if (log_file)
1704
      if (log_file)
1587
        fclose(log_file);
1705
        fclose(log_file);
1588
      log_file = 0;
1706
      log_file = 0;
1589
      sprintf_s(filename, sizeof (filename), "%s/log.%03d", log_path, log_id - 1); // Pierre-Marie Baty -- use safe version
1707
      sprintf(filename, "%s/log.%03d", log_path, log_id - 1);
1590
      remove(filename);
1708
      remove(filename);
1591
      sprintf_s(filename, sizeof (filename), "%s/game.%03d", log_path, log_id - 1); // Pierre-Marie Baty -- use safe version
1709
      sprintf(filename, "%s/game.%03d", log_path, log_id - 1);
1592
      remove(filename);
1710
      remove(filename);
1593
    } else if (args[1][0] >= '0' && args[1][0] <= '9') {
1711
    } else if (args[1][0] >= '0' && args[1][0] <= '9') {
1594
      if (log_id == 0)
1712
      if (log_id == 0)
1595
        log_id = atoi(args[1]);
1713
        log_id = atoi(args[1]);
1596
    } else {
1714
    } else {
1597
      int nrecs, trecs, lrecs;
-
 
1598
      char *eof;
1715
      char *eof;
1599
      FILE *log;
1716
      FILE *log;
-
 
1717
      int nrecs, trecs, lrecs;
1600
 
1718
 
1601
      nrecs = atoi(args[1]);
1719
      nrecs = atoi(args[1]);
1602
      output_file = stdout;
1720
      output_file = stdout;
1603
      if (nargs > 2)
1721
      if (nargs > 2)
1604
        output_file = fopen(args[2], "w");
1722
        output_file = fopen(args[2], "w");
Line 1665... Line 1783...
1665
    size_t hmemory, pmemory;
1783
    size_t hmemory, pmemory;
1666
    if (nargs < 2) {
1784
    if (nargs < 2) {
1667
      printf("usage:  memory <size>\n");
1785
      printf("usage:  memory <size>\n");
1668
      return 1;
1786
      return 1;
1669
    }
1787
    }
-
 
1788
    if (allow_memory) {
1670
    size = atoi(args[1]) * 1024 * 1024;
1789
      size = (uint64_t) atoi(args[1]);
1671
    if (size == 0) {
1790
      if (size == 0) {
1672
      Print(4095, "ERROR - memory size can not be zero\n");
1791
        Print(4095, "ERROR - memory size can not be zero\n");
1673
      return 1;
1792
        return 1;
1674
    }
1793
      }
1675
    hmemory = (1ull) << MSB(size);
1794
      hmemory = (1ull) << MSB(size);
1676
    size &= ~hmemory;
1795
      size &= ~hmemory;
1677
    pmemory = (1ull) << MSB(size);
1796
      pmemory = (1ull) << MSB(size);
1678
    if (pmemory < 1024 * 1024)
-
 
1679
      pmemory = 0;
-
 
1680
    sprintf_s(buffer, sizeof (buffer), "hash %" PRIu64 "\n", (uint64_t) hmemory); // Pierre-Marie Baty -- use safe version
1797
      sprintf(buffer, "hash %" PRIu64 "M\n", (uint64_t) hmemory);
1681
    (void) Option(tree);
1798
      Option(tree);
1682
    if (pmemory) {
1799
      if (pmemory) {
1683
      sprintf_s(buffer, sizeof (buffer), "hashp %" PRIu64 "\n", (uint64_t) pmemory); // Pierre-Marie Baty -- use safe version
1800
        sprintf(buffer, "hashp %" PRIu64 "M\n", (uint64_t) pmemory);
1684
      (void) Option(tree);
1801
        Option(tree);
1685
    }
1802
      }
-
 
1803
    } else
-
 
1804
      Print(4095, "WARNING - memory command ignored.\n");
1686
  }
1805
  }
1687
/*
1806
/*
1688
 ************************************************************
1807
 ************************************************************
1689
 *                                                          *
1808
 *                                                          *
1690
 *   "mode" command sets tournament mode or normal mode.    *
1809
 *   "mode" command sets tournament mode or normal mode.    *
Line 1705... Line 1824...
1705
        book_weight_learn = 1.0;
1824
        book_weight_learn = 1.0;
1706
        book_weight_freq = 1.0;
1825
        book_weight_freq = 1.0;
1707
        book_weight_eval = 0.5;
1826
        book_weight_eval = 0.5;
1708
      } else if (!strcmp(args[1], "match")) {
1827
      } else if (!strcmp(args[1], "match")) {
1709
        mode = normal_mode;
1828
        mode = normal_mode;
1710
        book_weight_learn = 1.0f; // Pierre-Marie Baty -- added float suffix
1829
        book_weight_learn = 1.0;
1711
        book_weight_freq = 0.2f; // Pierre-Marie Baty -- added float suffix
1830
        book_weight_freq = 0.2f; // Pierre-Marie Baty -- added type cast
1712
        book_weight_eval = 0.1f; // Pierre-Marie Baty -- added float suffix
1831
        book_weight_eval = 0.1f; // Pierre-Marie Baty -- added type cast
1713
      } else {
1832
      } else {
1714
        printf("usage:  mode normal|tournament|match\n");
1833
        printf("usage:  mode normal|tournament|match\n");
1715
        mode = normal_mode;
1834
        mode = normal_mode;
1716
        book_weight_learn = 1.0f; // Pierre-Marie Baty -- added float suffix
1835
        book_weight_learn = 1.0;
1717
        book_weight_freq = 1.0f; // Pierre-Marie Baty -- added float suffix
1836
        book_weight_freq = 1.0;
1718
        book_weight_eval = 0.5f; // Pierre-Marie Baty -- added float suffix
1837
        book_weight_eval = 0.5;
1719
      }
1838
      }
1720
    }
1839
    }
1721
    if (mode == tournament_mode)
1840
    if (mode == tournament_mode)
1722
      printf("tournament mode.\n");
1841
      printf("tournament mode.\n");
1723
    else if (mode == normal_mode)
1842
    else if (mode == normal_mode)
Line 1736... Line 1855...
1736
 *   accordingly.                                           *
1855
 *   accordingly.                                           *
1737
 *                                                          *
1856
 *                                                          *
1738
 ************************************************************
1857
 ************************************************************
1739
 */
1858
 */
1740
  else if (OptionMatch("name", *args)) {
1859
  else if (OptionMatch("name", *args)) {
1741
    int i;
-
 
1742
    char *next;
1860
    char *next;
-
 
1861
    int i;
1743
 
1862
 
1744
    if (nargs < 2) {
1863
    if (nargs < 2) {
1745
      printf("usage:  name <name>\n");
1864
      printf("usage:  name <name>\n");
1746
      return 1;
1865
      return 1;
1747
    }
1866
    }
1748
    if (game_wtm) {
1867
    if (game_wtm) {
1749
      strcpy_s(pgn_white, sizeof (pgn_white), args[1]); // Pierre-Marie Baty -- use safe version
1868
      strcpy(pgn_white, args[1]);
1750
      sprintf_s(pgn_black, sizeof (pgn_black), "Crafty %s", version);
1869
      sprintf(pgn_black, "Crafty %s", version);
1751
    } else {
1870
    } else {
1752
      strcpy_s(pgn_black, sizeof (pgn_black), args[1]); // Pierre-Marie Baty -- use safe version
1871
      strcpy(pgn_black, args[1]);
1753
      sprintf_s(pgn_white, sizeof (pgn_white), "Crafty %s", version);
1872
      sprintf(pgn_white, "Crafty %s", version);
1754
    }
1873
    }
1755
    Print(128, "Crafty %s vs %s\n", version, args[1]);
1874
    Print(32, "Crafty %s vs %s\n", version, args[1]);
1756
    next = args[1];
1875
    next = args[1];
1757
    while (*next) {
1876
    while (*next) {
1758
      *next = tolower(*next);
1877
      *next = tolower(*next);
1759
      next++;
1878
      next++;
1760
    }
1879
    }
Line 1764... Line 1883...
1764
          kibitz = 4;
1883
          kibitz = 4;
1765
          break;
1884
          break;
1766
        }
1885
        }
1767
      for (i = 0; i < 128; i++)
1886
      for (i = 0; i < 128; i++)
1768
        if (GM_list[i] && !strcmp(GM_list[i], args[1])) {
1887
        if (GM_list[i] && !strcmp(GM_list[i], args[1])) {
1769
          Print(128, "playing a GM!\n");
1888
          Print(32, "playing a GM!\n");
1770
          book_selection_width = 3;
1889
          book_selection_width = 3;
1771
          resign = Min(6, resign);
1890
          resign = Min(6, resign);
1772
          resign_count = 4;
1891
          resign_count = 4;
1773
          draw_count = 4;
1892
          draw_count = 4;
1774
          accept_draws = 1;
1893
          accept_draws = 1;
1775
          kibitz = 0;
1894
          kibitz = 0;
1776
          break;
1895
          break;
1777
        }
1896
        }
1778
      for (i = 0; i < 128; i++)
1897
      for (i = 0; i < 128; i++)
1779
        if (IM_list[i] && !strcmp(IM_list[i], args[1])) {
1898
        if (IM_list[i] && !strcmp(IM_list[i], args[1])) {
1780
          Print(128, "playing an IM!\n");
1899
          Print(32, "playing an IM!\n");
1781
          book_selection_width = 4;
1900
          book_selection_width = 4;
1782
          resign = Min(9, resign);
1901
          resign = Min(9, resign);
1783
          resign_count = 5;
1902
          resign_count = 5;
1784
          draw_count = 4;
1903
          draw_count = 4;
1785
          accept_draws = 1;
1904
          accept_draws = 1;
Line 1788... Line 1907...
1788
        }
1907
        }
1789
      for (i = 0; i < 128; i++)
1908
      for (i = 0; i < 128; i++)
1790
        if (SP_list[i] && !strcmp(SP_list[i], args[1])) {
1909
        if (SP_list[i] && !strcmp(SP_list[i], args[1])) {
1791
          FILE *normal_bs_file = books_file;
1910
          FILE *normal_bs_file = books_file;
1792
 
1911
 
1793
          Print(128, "playing a special player!\n");
1912
          Print(32, "playing a special player!\n");
1794
          if (SP_opening_filename[i]) {
1913
          if (SP_opening_filename[i]) {
1795
            books_file = fopen(SP_opening_filename[i], "rb");
1914
            books_file = fopen(SP_opening_filename[i], "rb");
1796
            if (!books_file) {
1915
            if (!books_file) {
1797
              Print(4095, "Error!  unable to open %s for player %s.\n",
1916
              Print(4095, "Error!  unable to open %s for player %s.\n",
1798
                  SP_opening_filename[i], SP_list[i]);
1917
                  SP_opening_filename[i], SP_list[i]);
1799
              books_file = normal_bs_file;
1918
              books_file = normal_bs_file;
1800
            }
1919
            }
1801
          }
1920
          }
1802
          if (SP_personality_filename[i]) {
1921
          if (SP_personality_filename[i]) {
1803
            sprintf_s(buffer, sizeof (buffer), "personality load %s\n", // Pierre-Marie Baty -- use safe version
1922
            sprintf(buffer, "personality load %s\n",
1804
                SP_personality_filename[i]);
1923
                SP_personality_filename[i]);
1805
            (void) Option(tree);
1924
            Option(tree);
1806
          }
1925
          }
1807
          break;
1926
          break;
1808
        }
1927
        }
1809
    }
1928
    }
1810
    printf("tellicsnoalias kibitz Hello from Crafty v%s! (%d cpus)\n",
1929
    printf("tellicsnoalias kibitz Hello from Crafty v%s! (%d cpus)\n",
Line 1822... Line 1941...
1822
    if (thinking || pondering)
1941
    if (thinking || pondering)
1823
      return 3;
1942
      return 3;
1824
    if (smp_max_threads) {
1943
    if (smp_max_threads) {
1825
      int proc;
1944
      int proc;
1826
 
1945
 
1827
      Print(128, "parallel threads terminated.\n");
1946
      Print(32, "parallel threads terminated.\n");
1828
      for (proc = 1; proc < CPUS; proc++)
1947
      for (proc = 1; proc < CPUS; proc++)
1829
        thread[proc].tree = (TREE *) - 1;
1948
        thread[proc].terminate = 1;
1830
    }
1949
    }
1831
    NewGame(0);
1950
    NewGame(0);
1832
    return 3;
1951
    return 3;
1833
  }
1952
  }
1834
/*
1953
/*
1835
 ************************************************************
1954
 ************************************************************
1836
 *                                                          *
1955
 *                                                          *
1837
 *  "noise" command sets a minimum limit on nodes searched  *
1956
 *  "noise" command sets a minimum limit on time searched   *
1838
 *  such that until this number of nodes has been searched  *
1957
 *  before we start to display the normal search output.    *
1839
 *  no program output will occur.  This is used to prevent  *
1958
 *  With today's hardware and deep searches, it is easy to  *
1840
 *  simple endgames from swamping the display device since  *
1959
 *  get "swamped" with output.  Using "noise" you can say   *
1841
 *  30+ ply searches are possible, which can produce 100's  *
1960
 *  "hold the output until you have searched for <x> time   *
1842
 *  of lines of output.                                     *
1961
 *  (where time can be x.xx seconds or just x seconds.)     *
1843
 *                                                          *
1962
 *                                                          *
1844
 ************************************************************
1963
 ************************************************************
1845
 */
1964
 */
1846
  else if (OptionMatch("noise", *args)) {
1965
  else if (OptionMatch("noise", *args)) {
1847
    if (nargs < 2) {
1966
    if (nargs < 2) {
1848
      printf("usage:  noise <n>\n");
1967
      printf("usage:  noise <n>\n");
1849
      return 1;
1968
      return 1;
1850
    }
1969
    }
1851
    noise_level = atoi(args[1]);
1970
    noise_level = (int) (atof(args[1]) * 100); // Pierre-Marie Baty -- added type cast
1852
    Print(128, "noise level set to %d.\n", noise_level);
1971
    Print(32, "noise level set to %.2f seconds.\n",
-
 
1972
        (float) noise_level / 100.0);
1853
  }
1973
  }
1854
/*
1974
/*
1855
 ************************************************************
1975
 ************************************************************
1856
 *                                                          *
1976
 *                                                          *
1857
 *  "operator" command sets the operator time.  This time   *
1977
 *  "null" command sets the minimum null-move reduction and *
1858
 *  is the time per move that the operator needs.  It is    *
1978
 *  a value that is used to compute the max reduction.      *
-
 
1979
 *                                                          *
-
 
1980
 *     null <min> <divisor>                                 *
-
 
1981
 *                                                          *
1859
 *  multiplied by the number of moves left to time control  *
1982
 *  <min> is the minimum null move reduction.  The default  *
-
 
1983
 *  is 3 which is pretty reliable.                          *
1860
 *  to reserve operator time.                               *
1984
 *                                                          *
-
 
1985
 *  <divisor> increases the null move by the following      *
-
 
1986
 *  simple formula:                                         *
-
 
1987
 *                                                          *
-
 
1988
 *    null_reduction = min + depth / divisor                *
-
 
1989
 *                                                          *
-
 
1990
 *  The default value is currently 10, which will increase  *
-
 
1991
 *  R (null-move reduction) by one at any position where    *
-
 
1992
 *  depth >= 10 and < 20.  Or by two when depth > 20.  Etc. *
1861
 *                                                          *
1993
 *                                                          *
1862
 ************************************************************
1994
 ************************************************************
1863
 */
1995
 */
1864
  else if (OptionMatch("operator", *args)) {
1996
  else if (OptionMatch("null", *args)) {
-
 
1997
 
1865
    if (nargs < 2) {
1998
    if (nargs > 3) {
1866
      printf("usage:  operator <seconds>\n");
1999
      printf("usage:  null <min> <divisor>\n");
1867
      return 1;
2000
      return 1;
1868
    }
2001
    }
1869
    tc_operator_time = ParseTime(args[1]) * 100;
2002
    if (nargs > 1) {
1870
    Print(128, "reserving %d seconds per move for operator overhead.\n",
2003
      null_depth = atoi(args[1]);
1871
        tc_operator_time / 100);
2004
      null_divisor = atoi(args[2]);
-
 
2005
    }
-
 
2006
    Print(32, "null move:  R = %d + depth / %d\n", null_depth, null_divisor);
1872
  }
2007
  }
1873
/*
2008
/*
1874
 ************************************************************
2009
 ************************************************************
1875
 *                                                          *
2010
 *                                                          *
1876
 *  "otime" command sets the opponent's time remaining.     *
2011
 *  "otim" command sets the opponent's time remaining.      *
1877
 *  This is used to determine if the opponent is in time    *
2012
 *  This is used to determine if the opponent is in time    *
1878
 *  trouble, and is factored into the draw score if he is.  *
2013
 *  trouble, and is factored into the draw score if he is.  *
1879
 *                                                          *
2014
 *                                                          *
1880
 ************************************************************
2015
 ************************************************************
1881
 */
2016
 */
1882
  else if (OptionMatch("otime", *args)) {
2017
  else if (OptionMatch("otim", *args)) {
1883
    if (nargs < 2) {
2018
    if (nargs < 2) {
1884
      printf("usage:  otime <time(unit=.01 secs))>\n");
2019
      printf("usage:  otime <time(unit=.01 secs))>\n");
1885
      return 1;
2020
      return 1;
1886
    }
2021
    }
1887
    tc_time_remaining[Flip(root_wtm)] = atoi(args[1]);
2022
    tc_time_remaining[game_wtm] = atoi(args[1]);
1888
    if (log_file && time_limit > 99)
2023
    if (log_file && time_limit > 99)
1889
      fprintf(log_file, "time remaining: %s (opponent).\n",
2024
      fprintf(log_file, "time remaining: %s (opponent).\n",
1890
          DisplayTime(tc_time_remaining[Flip(root_wtm)]));
2025
          DisplayTime(tc_time_remaining[game_wtm]));
1891
    if (call_flag && xboard && tc_time_remaining[Flip(root_wtm)] < 1) {
2026
    if (call_flag && xboard && tc_time_remaining[game_wtm] < 1) {
1892
      if (crafty_is_white)
2027
      if (crafty_is_white)
1893
        Print(128, "1-0 {Black ran out of time}\n");
2028
        Print(32, "1-0 {Black ran out of time}\n");
1894
      else
2029
      else
1895
        Print(128, "0-1 {White ran out of time}\n");
2030
        Print(32, "0-1 {White ran out of time}\n");
1896
    }
2031
    }
1897
  }
2032
  }
1898
/*
2033
/*
1899
 ************************************************************
2034
 ************************************************************
1900
 *                                                          *
2035
 *                                                          *
Line 1913... Line 2048...
1913
    else if (!strcmp(args[1], "short"))
2048
    else if (!strcmp(args[1], "short"))
1914
      output_format = 0;
2049
      output_format = 0;
1915
    else
2050
    else
1916
      printf("usage:  output long|short\n");
2051
      printf("usage:  output long|short\n");
1917
    if (output_format == 1)
2052
    if (output_format == 1)
1918
      Print(128, "output moves in long algebraic format\n");
2053
      Print(32, "output moves in long algebraic format\n");
1919
    else if (output_format == 0)
2054
    else if (output_format == 0)
1920
      Print(128, "output moves in short algebraic format\n");
2055
      Print(32, "output moves in short algebraic format\n");
1921
  }
2056
  }
1922
/*
2057
/*
1923
 ************************************************************
2058
 ************************************************************
1924
 *                                                          *
2059
 *                                                          *
1925
 *  "personality" command is used to adjust the eval terms  *
2060
 *  "personality" command is used to adjust the eval terms  *
Line 1945... Line 2080...
1945
          continue;
2080
          continue;
1946
        if (personality_packet[i].value) {
2081
        if (personality_packet[i].value) {
1947
          switch (personality_packet[i].type) {
2082
          switch (personality_packet[i].type) {
1948
            case 1:
2083
            case 1:
1949
              printf("%3d  %s %7d\n", i, personality_packet[i].description,
2084
              printf("%3d  %s %7d\n", i, personality_packet[i].description,
1950
                  *personality_packet[i].value);
2085
                  *(int *) personality_packet[i].value);
1951
              break;
2086
              break;
1952
            case 2:
2087
            case 2:
1953
              printf("%3d  %s %7d (mg) %7d (eg)\n", i,
2088
              printf("%3d  %s %7d (mg) %7d (eg)\n", i,
1954
                  personality_packet[i].description,
2089
                  personality_packet[i].description,
1955
                  personality_packet[i].value[mg],
2090
                  ((int *) personality_packet[i].value)[mg],
1956
                  personality_packet[i].value[eg]);
2091
                  ((int *) personality_packet[i].value)[eg]);
1957
              break;
2092
              break;
1958
            case 3:
2093
            case 3:
1959
              printf("%3d  %s\n", i, personality_packet[i].description);
2094
              printf("%3d  %s %7.2f\n", i, personality_packet[i].description,
1960
              DisplayType3(personality_packet[i].value,
2095
                  *(double *) personality_packet[i].value);
1961
                  personality_packet[i].value + 128);
-
 
1962
              break;
2096
              break;
1963
            case 4:
2097
            case 4:
1964
              printf("%3d  %s\n", i, personality_packet[i].description);
2098
              printf("%3d  %s    ", i, personality_packet[i].description);
1965
              DisplayType4(personality_packet[i].value,
-
 
1966
                  personality_packet[i].value + 64);
2099
              for (j = 0; j < personality_packet[i].size; j++)
1967
              break;
-
 
1968
            case 5:
-
 
1969
              printf("%3d  %s\n", i, personality_packet[i].description);
2100
                printf("%4d", ((int *) personality_packet[i].value)[j]);
1970
              DisplayType5(personality_packet[i].value,
-
 
1971
                  personality_packet[i].size);
-
 
1972
              break;
2101
              printf("\n");
1973
            case 6:
-
 
1974
              printf("%3d  %s\n", i, personality_packet[i].description);
-
 
1975
              DisplayType6(personality_packet[i].value);
-
 
1976
              break;
2102
              break;
1977
          }
2103
          }
1978
        } else {
2104
        } else {
1979
          printf("==================================================\n");
2105
          printf("==================================================\n");
1980
          printf("=         %s  =\n", personality_packet[i].description);
2106
          printf("=         %s  =\n", personality_packet[i].description);
Line 1994... Line 2120...
1994
 */
2120
 */
1995
    if (!strcmp(args[1], "load")) {
2121
    if (!strcmp(args[1], "load")) {
1996
      FILE *file;
2122
      FILE *file;
1997
      char filename[256];
2123
      char filename[256];
1998
 
2124
 
1999
      strcpy_s(filename, sizeof (filename), args[2]); // Pierre-Marie Baty -- use safe version
2125
      strcpy(filename, args[2]);
2000
      if (!strstr(filename, ".cpf"))
2126
      if (!strstr(filename, ".cpf"))
2001
        strcat_s(filename, sizeof (filename), ".cpf"); // Pierre-Marie Baty -- use safe version
2127
        strcat(filename, ".cpf");
2002
      Print(128, "Loading personality file %s\n", filename);
2128
      Print(32, "Loading personality file %s\n", filename);
2003
      fopen_s (&file, filename, "r+"); // Pierre-Marie Baty -- use safe version
-
 
2004
      if (file) {
2129
      if ((file = fopen(filename, "r+"))) {
2005
        while (fgets(buffer, 4096, file)) {
2130
        while (fgets(buffer, 4096, file)) {
2006
          char *delim;
2131
          char *delim;
2007
 
2132
 
2008
          delim = strchr(buffer, '\n');
2133
          delim = strchr(buffer, '\n');
2009
          if (delim)
2134
          if (delim)
Line 2012... Line 2137...
2012
          if (delim)
2137
          if (delim)
2013
            *delim = 0;
2138
            *delim = 0;
2014
          delim = strchr(buffer, '\r');
2139
          delim = strchr(buffer, '\r');
2015
          if (delim)
2140
          if (delim)
2016
            *delim = ' ';
2141
            *delim = ' ';
2017
          (void) Option(tree);
2142
          Option(tree);
2018
        }
2143
        }
2019
        fclose(file);
2144
        fclose(file);
2020
      }
2145
      }
2021
      return 1;
2146
      return 1;
2022
    }
2147
    }
Line 2030... Line 2155...
2030
 */
2155
 */
2031
    if (nargs == 3 && !strcmp(args[1], "save")) {
2156
    if (nargs == 3 && !strcmp(args[1], "save")) {
2032
      char filename[256];
2157
      char filename[256];
2033
      FILE *file;
2158
      FILE *file;
2034
 
2159
 
2035
      strcpy_s(filename, sizeof (filename), args[2]); // Pierre-Marie Baty -- use safe version
2160
      strcpy(filename, args[2]);
2036
      if (!strstr(filename, ".cpf"))
2161
      if (!strstr(filename, ".cpf"))
2037
        strcat_s(filename, sizeof (filename), ".cpf"); // Pierre-Marie Baty -- use safe version
2162
        strcat(filename, ".cpf");
2038
      fopen_s (&file, filename, "w"); // Pierre-Marie Baty -- use safe version
2163
      file = fopen(filename, "w");
2039
      if (!file) {
2164
      if (!file) {
2040
        printf("ERROR.  Unable to open %s for writing\n", args[2]);
2165
        printf("ERROR.  Unable to open %s for writing\n", args[2]);
2041
        return 1;
2166
        return 1;
2042
      }
2167
      }
2043
      printf("saving to file \"%s\"\n", filename);
2168
      printf("saving to file \"%s\"\n", filename);
Line 2046... Line 2171...
2046
        if (!personality_packet[i].description)
2171
        if (!personality_packet[i].description)
2047
          continue;
2172
          continue;
2048
        if (personality_packet[i].value) {
2173
        if (personality_packet[i].value) {
2049
          if (personality_packet[i].size <= 1)
2174
          if (personality_packet[i].size <= 1)
2050
            fprintf(file, "personality %3d %7d\n", i,
2175
            fprintf(file, "personality %3d %7d\n", i,
2051
                *personality_packet[i].value);
2176
                *((int *) personality_packet[i].value));
2052
          else if (personality_packet[i].size > 1) {
2177
          else if (personality_packet[i].size > 1) {
2053
            fprintf(file, "personality %3d ", i);
2178
            fprintf(file, "personality %3d ", i);
2054
            for (j = 0; j < personality_packet[i].size; j++)
2179
            for (j = 0; j < personality_packet[i].size; j++)
2055
              fprintf(file, "%d ", personality_packet[i].value[j]);
2180
              fprintf(file, "%d ", ((int *) personality_packet[i].value)[j]);
2056
            fprintf(file, "\n");
2181
            fprintf(file, "\n");
2057
          }
2182
          }
2058
        }
2183
        }
2059
      }
2184
      }
2060
      fprintf(file, "exit\n");
2185
      fprintf(file, "exit\n");
Line 2078... Line 2203...
2078
    if (personality_packet[param].size == 0) {
2203
    if (personality_packet[param].size == 0) {
2079
      if (nargs > 3) {
2204
      if (nargs > 3) {
2080
        printf("this eval term requires exactly 1 value.\n");
2205
        printf("this eval term requires exactly 1 value.\n");
2081
        return 1;
2206
        return 1;
2082
      }
2207
      }
2083
      *personality_packet[param].value = value;
2208
      *(int *) personality_packet[param].value = value;
2084
    }
2209
    }
2085
/*
2210
/*
2086
 ************************************************************
2211
 ************************************************************
2087
 *                                                          *
2212
 *                                                          *
2088
 *  Handle the "personality index v1 v2 .. vn" command that *
2213
 *  Handle the "personality index v1 v2 .. vn" command that *
Line 2098... Line 2223...
2098
            personality_packet[param].description, param,
2223
            personality_packet[param].description, param,
2099
            Abs(personality_packet[param].size), index);
2224
            Abs(personality_packet[param].size), index);
2100
        return 1;
2225
        return 1;
2101
      }
2226
      }
2102
      for (i = 0; i < index; i++)
2227
      for (i = 0; i < index; i++)
2103
        personality_packet[param].value[i] = atoi(args[i + 2]);
2228
        ((int *) personality_packet[param].value)[i] = atoi(args[i + 2]);
2104
    }
2229
    }
2105
    InitializeKingSafety();
2230
    InitializeKingSafety();
2106
  }
2231
  }
2107
/*
2232
/*
2108
 ************************************************************
2233
 ************************************************************
Line 2123... Line 2248...
2123
      printf("usage:  bookpath|perspath|logpath|tbpath <path>\n");
2248
      printf("usage:  bookpath|perspath|logpath|tbpath <path>\n");
2124
      return 1;
2249
      return 1;
2125
    }
2250
    }
2126
    if (!strchr(args[1], '(')) {
2251
    if (!strchr(args[1], '(')) {
2127
      if (strstr(args[0], "bookpath"))
2252
      if (strstr(args[0], "bookpath"))
2128
        strcpy_s(book_path, sizeof (book_path), args[1]); // Pierre-Marie Baty -- use safe version
2253
        strcpy(book_path, args[1]);
2129
      else if (strstr(args[0], "logpath"))
2254
      else if (strstr(args[0], "logpath"))
2130
        strcpy_s(log_path, sizeof (log_path), args[1]); // Pierre-Marie Baty -- use safe version
2255
        strcpy(log_path, args[1]);
2131
#if !defined(NOEGTB)
2256
#if !defined(NOEGTB)
2132
      else if (strstr(args[0], "tbpath"))
2257
      else if (strstr(args[0], "tbpath"))
2133
        strcpy_s(tb_path, sizeof (tb_path), args[1]); // Pierre-Marie Baty -- use safe version
2258
        strcpy(tb_path, args[1]);
2134
#endif
2259
#endif
2135
    } else {
2260
    } else {
2136
      if (strchr(args[1], ')')) {
2261
      if (strchr(args[1], ')')) {
2137
        *strchr(args[1], ')') = 0;
2262
        *strchr(args[1], ')') = 0;
2138
        if (strstr(args[0], "bookpath"))
2263
        if (strstr(args[0], "bookpath"))
2139
          strcpy_s(book_path, sizeof (book_path), args[1] + 1); // Pierre-Marie Baty -- use safe version
2264
          strcpy(book_path, args[1] + 1);
2140
        else if (strstr(args[0], "logpath"))
2265
        else if (strstr(args[0], "logpath"))
2141
          strcpy_s(log_path, sizeof (log_path), args[1] + 1); // Pierre-Marie Baty -- use safe version
2266
          strcpy(log_path, args[1] + 1);
2142
#if !defined(NOEGTB)
2267
#if !defined(NOEGTB)
2143
        else if (strstr(args[0], "tbpath"))
2268
        else if (strstr(args[0], "tbpath"))
2144
          strcpy_s(tb_path, sizeof (tb_path), args[1] + 1); // Pierre-Marie Baty -- use safe version
2269
          strcpy(tb_path, args[1] + 1);
2145
#endif
2270
#endif
2146
      } else
2271
      } else
2147
        Print(4095, "ERROR multiple paths must be enclosed in ( and )\n");
2272
        Print(4095, "ERROR multiple paths must be enclosed in ( and )\n");
2148
    }
2273
    }
2149
  }
2274
  }
Line 2154... Line 2279...
2154
 *                                                          *
2279
 *                                                          *
2155
 ************************************************************
2280
 ************************************************************
2156
 */
2281
 */
2157
#define PERF_CYCLES 4000000
2282
#define PERF_CYCLES 4000000
2158
  else if (OptionMatch("perf", *args)) {
2283
  else if (OptionMatch("perf", *args)) {
2159
    int i, *mv, clock_before, clock_after;
2284
    int i, clock_before, clock_after;
-
 
2285
    unsigned *mv;
2160
    float time_used;
2286
    float time_used;
2161
 
2287
 
2162
    if (thinking || pondering)
2288
    if (thinking || pondering)
2163
      return 2;
2289
      return 2;
2164
    clock_before = clock();
2290
    clock_before = clock();
Line 2181... Line 2307...
2181
    clock_before = clock();
2307
    clock_before = clock();
2182
    for (i = 0; i < PERF_CYCLES; i++) {
2308
    for (i = 0; i < PERF_CYCLES; i++) {
2183
      tree->last[1] = GenerateCaptures(tree, 0, game_wtm, tree->last[0]);
2309
      tree->last[1] = GenerateCaptures(tree, 0, game_wtm, tree->last[0]);
2184
      tree->last[1] = GenerateNoncaptures(tree, 0, game_wtm, tree->last[1]);
2310
      tree->last[1] = GenerateNoncaptures(tree, 0, game_wtm, tree->last[1]);
2185
      for (mv = tree->last[0]; mv < tree->last[1]; mv++) {
2311
      for (mv = tree->last[0]; mv < tree->last[1]; mv++) {
2186
        MakeMove(tree, 0, *mv, game_wtm);
2312
        MakeMove(tree, 0, game_wtm, *mv);
2187
        UnmakeMove(tree, 0, *mv, game_wtm);
2313
        UnmakeMove(tree, 0, game_wtm, *mv);
2188
      }
2314
      }
2189
    }
2315
    }
2190
    clock_after = clock();
2316
    clock_after = clock();
2191
    time_used =
2317
    time_used =
2192
        ((float) clock_after - (float) clock_before) / (float) CLOCKS_PER_SEC;
2318
        ((float) clock_after - (float) clock_before) / (float) CLOCKS_PER_SEC;
Line 2202... Line 2328...
2202
 *  "perft" command turns tests move generator/make_move.   *
2328
 *  "perft" command turns tests move generator/make_move.   *
2203
 *                                                          *
2329
 *                                                          *
2204
 ************************************************************
2330
 ************************************************************
2205
 */
2331
 */
2206
  else if (OptionMatch("perft", *args)) {
2332
  else if (OptionMatch("perft", *args)) {
2207
    int i, clock_before, clock_after;
-
 
2208
    float time_used;
2333
    float time_used;
-
 
2334
    int i, clock_before, clock_after;
2209
 
2335
 
2210
    if (thinking || pondering)
2336
    if (thinking || pondering)
2211
      return 2;
2337
      return 2;
2212
    clock_before = clock();
2338
    clock_before = clock();
2213
    while (clock() == clock_before);
2339
    while (clock() == clock_before);
2214
    clock_before = clock();
2340
    clock_before = clock();
2215
    if (nargs < 2) {
2341
    if (nargs < 2) {
2216
      printf("usage:  perftest <depth>\n");
2342
      printf("usage:  perft <depth>\n");
2217
      return 1;
2343
      return 1;
2218
    }
2344
    }
2219
    tree->status[1] = tree->status[0];
2345
    tree->status[1] = tree->status[0];
2220
    tree->last[0] = tree->move_list;
2346
    tree->last[0] = tree->move_list;
2221
    i = atoi(args[1]);
2347
    i = atoi(args[1]);
2222
    if (i <= 0) {
2348
    if (i <= 0) {
2223
      Print(128, "usage:  perft <maxply>\n");
2349
      Print(32, "usage:  perft <maxply>\n");
2224
      return 1;
2350
      return 1;
2225
    }
2351
    }
2226
    total_moves = 0;
2352
    total_moves = 0;
2227
    OptionPerft(tree, 1, i, game_wtm);
2353
    OptionPerft(tree, 1, i, game_wtm);
2228
    clock_after = clock();
2354
    clock_after = clock();
Line 2245... Line 2371...
2245
      return 1;
2371
      return 1;
2246
    }
2372
    }
2247
    if (!strcmp(args[1], "Event")) {
2373
    if (!strcmp(args[1], "Event")) {
2248
      pgn_event[0] = 0;
2374
      pgn_event[0] = 0;
2249
      for (i = 2; i < nargs; i++) {
2375
      for (i = 2; i < nargs; i++) {
2250
        strcat_s(pgn_event, sizeof (pgn_event), args[i]); // Pierre-Marie Baty -- use safe version
2376
        strcpy(pgn_event + strlen(pgn_event), args[i]);
2251
        strcat_s(pgn_event, sizeof (pgn_event), " "); // Pierre-Marie Baty -- use safe version
2377
        strcpy(pgn_event + strlen(pgn_event), " ");
2252
      }
2378
      }
2253
    } else if (!strcmp(args[1], "Site")) {
2379
    } else if (!strcmp(args[1], "Site")) {
2254
      pgn_site[0] = 0;
2380
      pgn_site[0] = 0;
2255
      for (i = 2; i < nargs; i++) {
2381
      for (i = 2; i < nargs; i++) {
2256
        strcat_s(pgn_site, sizeof (pgn_site), args[i]); // Pierre-Marie Baty -- use safe version
2382
        strcpy(pgn_site + strlen(pgn_site), args[i]);
2257
        strcat_s(pgn_site, sizeof (pgn_site), " "); // Pierre-Marie Baty -- use safe version
2383
        strcpy(pgn_site + strlen(pgn_site), " ");
2258
      }
2384
      }
2259
    } else if (!strcmp(args[1], "Round")) {
2385
    } else if (!strcmp(args[1], "Round")) {
2260
      pgn_round[0] = 0;
2386
      pgn_round[0] = 0;
2261
      strcpy_s(pgn_round, sizeof (pgn_round), args[2]); // Pierre-Marie Baty -- use safe version
2387
      strcpy(pgn_round, args[2]);
2262
    } else if (!strcmp(args[1], "White")) {
2388
    } else if (!strcmp(args[1], "White")) {
2263
      pgn_white[0] = 0;
2389
      pgn_white[0] = 0;
2264
      for (i = 2; i < nargs; i++) {
2390
      for (i = 2; i < nargs; i++) {
2265
        strcat_s(pgn_white, sizeof (pgn_white), args[i]); // Pierre-Marie Baty -- use safe version
2391
        strcpy(pgn_white + strlen(pgn_white), args[i]);
2266
        strcat_s(pgn_white, sizeof (pgn_white), " "); // Pierre-Marie Baty -- use safe version
2392
        strcpy(pgn_white + strlen(pgn_white), " ");
2267
      }
2393
      }
2268
    } else if (!strcmp(args[1], "WhiteElo")) {
2394
    } else if (!strcmp(args[1], "WhiteElo")) {
2269
      pgn_white_elo[0] = 0;
2395
      pgn_white_elo[0] = 0;
2270
      strcpy_s(pgn_white_elo, sizeof (pgn_white_elo), args[2]); // Pierre-Marie Baty -- use safe version
2396
      strcpy(pgn_white_elo, args[2]);
2271
    } else if (!strcmp(args[1], "Black")) {
2397
    } else if (!strcmp(args[1], "Black")) {
2272
      pgn_black[0] = 0;
2398
      pgn_black[0] = 0;
2273
      for (i = 2; i < nargs; i++) {
2399
      for (i = 2; i < nargs; i++) {
2274
        strcat_s(pgn_black, sizeof (pgn_black), args[i]); // Pierre-Marie Baty -- use safe version
2400
        strcpy(pgn_black + strlen(pgn_black), args[i]);
2275
        strcat_s(pgn_black, sizeof (pgn_black), " "); // Pierre-Marie Baty -- use safe version
2401
        strcpy(pgn_black + strlen(pgn_black), " ");
2276
      }
2402
      }
2277
    } else if (!strcmp(args[1], "BlackElo")) {
2403
    } else if (!strcmp(args[1], "BlackElo")) {
2278
      pgn_black_elo[0] = 0;
2404
      pgn_black_elo[0] = 0;
2279
      strcpy_s(pgn_black_elo, sizeof (pgn_black_elo), args[2]); // Pierre-Marie Baty -- use safe version
2405
      strcpy(pgn_black_elo, args[2]);
2280
    }
2406
    }
2281
  }
2407
  }
2282
/*
2408
/*
2283
 ************************************************************
2409
 ************************************************************
2284
 *                                                          *
2410
 *                                                          *
Line 2286... Line 2412...
2286
 *  to let it know all previous commands have been executed *
2412
 *  to let it know all previous commands have been executed *
2287
 *  and we are ready for whatever is next.                  *
2413
 *  and we are ready for whatever is next.                  *
2288
 *                                                          *
2414
 *                                                          *
2289
 ************************************************************
2415
 ************************************************************
2290
 */
2416
 */
2291
  else if (!strcmp("ping", *args)) {
2417
  else if (OptionMatch("ping", *args)) {
2292
    if (pondering) {
2418
    if (pondering)
2293
      Print(4095, "pong %s\n", args[1]);
2419
      Print(-1, "pong %s\n", args[1]);
2294
    } else {
2420
    else
2295
      pong = atoi(args[1]);
2421
      pong = atoi(args[1]);
2296
    }
-
 
2297
  }
2422
  }
2298
/*
2423
/*
2299
 ************************************************************
2424
 ************************************************************
2300
 *                                                          *
2425
 *                                                          *
2301
 *  "playother" command says "position is set up, we are    *
2426
 *  "playother" command says "position is set up, we are    *
2302
 *  waiting on the opponent to move, ponder if you want to  *
2427
 *  waiting on the opponent to move, ponder if you want to  *
2303
 *  do so.                                                  *
2428
 *  do so.                                                  *
2304
 *                                                          *
2429
 *                                                          *
2305
 ************************************************************
2430
 ************************************************************
2306
 */
2431
 */
2307
  else if (!strcmp("playother", *args)) {
2432
  else if (OptionMatch("playother", *args)) {
2308
    force = 0;
2433
    force = 0;
2309
  }
2434
  }
2310
/*
2435
/*
2311
 ************************************************************
2436
 ************************************************************
2312
 *                                                          *
2437
 *                                                          *
Line 2322... Line 2447...
2322
      printf("usage:  ponder off|on|<move>\n");
2447
      printf("usage:  ponder off|on|<move>\n");
2323
      return 1;
2448
      return 1;
2324
    }
2449
    }
2325
    if (!strcmp(args[1], "on")) {
2450
    if (!strcmp(args[1], "on")) {
2326
      ponder = 1;
2451
      ponder = 1;
2327
      Print(128, "pondering enabled.\n");
2452
      Print(32, "pondering enabled.\n");
2328
    } else if (!strcmp(args[1], "off")) {
2453
    } else if (!strcmp(args[1], "off")) {
2329
      ponder = 0;
2454
      ponder = 0;
2330
      Print(128, "pondering disabled.\n");
2455
      Print(32, "pondering disabled.\n");
2331
    } else {
2456
    } else {
2332
      ponder_move = InputMove(tree, args[1], 0, game_wtm, 0, 0);
2457
      ponder_move = InputMove(tree, 0, game_wtm, 0, 0, args[1]);
2333
      last_pv.pathd = 0;
2458
      last_pv.pathd = 0;
2334
      last_pv.pathl = 0;
2459
      last_pv.pathl = 0;
2335
    }
2460
    }
2336
  }
2461
  }
2337
/*
2462
/*
Line 2340... Line 2465...
2340
 *  "post/nopost" command sets/resets "show thinking" mode  *
2465
 *  "post/nopost" command sets/resets "show thinking" mode  *
2341
 *  for xboard compatibility.                               *
2466
 *  for xboard compatibility.                               *
2342
 *                                                          *
2467
 *                                                          *
2343
 ************************************************************
2468
 ************************************************************
2344
 */
2469
 */
2345
  else if (!strcmp("post", *args)) {
2470
  else if (OptionMatch("post", *args)) {
2346
    post = 1;
2471
    post = 1;
2347
  } else if (!strcmp("nopost", *args)) {
2472
  } else if (OptionMatch("nopost", *args)) {
2348
    post = 0;
2473
    post = 0;
2349
  }
2474
  }
2350
/*
2475
/*
2351
 ************************************************************
2476
 ************************************************************
2352
 *                                                          *
2477
 *                                                          *
Line 2354... Line 2479...
2354
 *  xboard protocol version and discover what the engine    *
2479
 *  xboard protocol version and discover what the engine    *
2355
 *  can handle.                                             *
2480
 *  can handle.                                             *
2356
 *                                                          *
2481
 *                                                          *
2357
 ************************************************************
2482
 ************************************************************
2358
 */
2483
 */
2359
  else if (!strcmp("protover", *args)) {
2484
  else if (OptionMatch("protover", *args)) {
2360
    int pversion = atoi(args[1]);
2485
    int pversion = atoi(args[1]);
2361
 
2486
 
2362
    if (pversion >= 1 && pversion <= 3) {
2487
    if (pversion >= 1 && pversion <= 3) {
2363
      if (pversion >= 2) {
2488
      if (pversion >= 2) {
2364
        Print(4095, "feature ping=1 setboard=1 san=1 time=1 draw=1\n");
2489
        Print(-1, "feature ping=1 setboard=1 san=1 time=1 draw=1\n");
2365
        Print(4095, "feature sigint=0 sigterm=0 reuse=1 analyze=1\n");
2490
        Print(-1, "feature sigint=0 sigterm=0 reuse=1 analyze=1\n");
2366
        Print(4095, "feature myname=\"Crafty-%s\" name=1\n", version);
2491
        Print(-1, "feature myname=\"Crafty-%s\" name=1\n", version);
2367
        Print(4095, "feature playother=1 colors=0 memory=%d\n", allow_memory);
2492
        Print(-1, "feature playother=1 colors=0 memory=%d\n", allow_memory);
2368
#if (CPUS > 1)
2493
#if (CPUS > 1)
2369
        Print(4095, "feature smp=%d\n", allow_cores);
2494
        Print(-1, "feature smp=%d\n", allow_cores);
2370
#endif
2495
#endif
2371
        Print(4095, "feature variants=\"normal,nocastle\"\n");
2496
        Print(-1, "feature variants=\"normal,nocastle\"\n");
2372
        Print(4095, "feature done=1\n");
2497
        Print(-1, "feature done=1\n");
2373
        done = 1;
2498
        xboard_done = 1;
2374
      }
2499
      }
2375
    } else
2500
    } else
2376
      Print(4095, "ERROR, bogus xboard protocol version received.\n");
2501
      Print(4095, "ERROR, bogus xboard protocol version received.\n");
2377
  }
2502
  }
2378
/*
2503
/*
Line 2394... Line 2519...
2394
 *                                                          *
2519
 *                                                          *
2395
 ************************************************************
2520
 ************************************************************
2396
 */
2521
 */
2397
  else if (OptionMatch("rating", *args)) {
2522
  else if (OptionMatch("rating", *args)) {
2398
    int rd;
2523
    int rd;
-
 
2524
 
2399
    if (nargs < 3) {
2525
    if (nargs < 3) {
2400
      printf("usage:  rating <Crafty> <opponent>\n");
2526
      printf("usage:  rating <Crafty> <opponent>\n");
2401
      return 1;
2527
      return 1;
2402
    }
2528
    }
2403
    crafty_rating = atoi(args[1]);
2529
    crafty_rating = atoi(args[1]);
2404
    opponent_rating = atoi(args[2]);
2530
    opponent_rating = atoi(args[2]);
2405
    if (crafty_rating == 0 && opponent_rating == 0) {
2531
    if (crafty_rating == 0 && opponent_rating == 0) {
2406
      crafty_rating = 2500;
2532
      crafty_rating = 2500;
2407
      opponent_rating = 2300;
2533
      opponent_rating = 2300;
2408
    }
2534
    }
-
 
2535
    if (dynamic_draw_score) {
2409
    rd = opponent_rating - crafty_rating;
2536
      rd = opponent_rating - crafty_rating;
2410
    rd = Max(Min(rd, 300), -300);
2537
      rd = Max(Min(rd, 300), -300);
2411
    abs_draw_score = (rd + 60) / 7;
2538
      abs_draw_score = rd / 8;
2412
    if (log_file) {
2539
      if (log_file) {
2413
      fprintf(log_file, "Crafty's rating: %d.\n", crafty_rating);
2540
        fprintf(log_file, "Crafty's rating: %d.\n", crafty_rating);
2414
      fprintf(log_file, "opponent's rating: %d.\n", opponent_rating);
2541
        fprintf(log_file, "opponent's rating: %d.\n", opponent_rating);
2415
      fprintf(log_file, "draw score: %d.\n", abs_draw_score);
2542
        fprintf(log_file, "draw score: %d.\n", abs_draw_score);
-
 
2543
      }
2416
    }
2544
    }
2417
  }
2545
  }
2418
/*
2546
/*
2419
 ************************************************************
2547
 ************************************************************
2420
 *                                                          *
2548
 *                                                          *
Line 2422... Line 2550...
2422
 *  leaving the opponent still on move.  It's intended for  *
2550
 *  leaving the opponent still on move.  It's intended for  *
2423
 *  xboard compatibility, but works in any mode.            *
2551
 *  xboard compatibility, but works in any mode.            *
2424
 *                                                          *
2552
 *                                                          *
2425
 ************************************************************
2553
 ************************************************************
2426
 */
2554
 */
2427
  else if (!strcmp("remove", *args)) {
2555
  else if (OptionMatch("remove", *args)) {
2428
    if (thinking || pondering)
2556
    if (thinking || pondering)
2429
      return 2;
2557
      return 2;
2430
    move_number--;
2558
    move_number--;
2431
    sprintf_s(buffer, sizeof (buffer), "reset %d", move_number); // Pierre-Marie Baty -- use safe version
-
 
2432
    (void) Option(tree);
-
 
2433
  }
-
 
2434
/*
-
 
2435
 ************************************************************
-
 
2436
 *                                                          *
-
 
2437
 *  "reset" restores (backs up) a game to a prior position  *
-
 
2438
 *  with the same side on move.  Reset 17 would reset the   *
-
 
2439
 *  position to what it was at move 17 with the current     *
-
 
2440
 *  still on move (you can use white/black commands to      *
-
 
2441
 *  change the side to move first, if needed.)              *
-
 
2442
 *                                                          *
-
 
2443
 ************************************************************
-
 
2444
 */
-
 
2445
  else if (OptionMatch("reset", *args)) {
-
 
2446
    int i, move, nmoves;
-
 
2447
 
-
 
2448
    if (!history_file)
-
 
2449
      return 1;
-
 
2450
    if (thinking || pondering)
-
 
2451
      return 2;
-
 
2452
    if (nargs < 2) {
-
 
2453
      printf("usage:  reset <movenumber>\n");
2559
    sprintf(buffer, "reset %d", move_number);
2454
      return 1;
-
 
2455
    }
-
 
2456
    ponder_move = 0;
-
 
2457
    last_mate_score = 0;
-
 
2458
    last_pv.pathd = 0;
-
 
2459
    last_pv.pathl = 0;
-
 
2460
    if (thinking || pondering)
-
 
2461
      return 2;
-
 
2462
    over = 0;
-
 
2463
    move_number = atoi(args[1]);
-
 
2464
    if (!move_number) {
-
 
2465
      move_number = 1;
-
 
2466
      return 1;
-
 
2467
    }
-
 
2468
    nmoves = (move_number - 1) * 2 + 1 - game_wtm;
-
 
2469
    root_wtm = Flip(game_wtm);
-
 
2470
    InitializeChessBoard(tree);
-
 
2471
    game_wtm = 1;
-
 
2472
    move_number = 1;
-
 
2473
    tc_moves_remaining[white] = tc_moves;
-
 
2474
    tc_moves_remaining[black] = tc_moves;
-
 
2475
    for (i = 0; i < nmoves; i++) {
-
 
2476
      fseek(history_file, i * 10, SEEK_SET);
-
 
2477
      fscanf_s(history_file, "%s", buffer, sizeof (buffer)); // Pierre-Marie Baty -- use safe version
-
 
2478
/*
-
 
2479
 If the move is "pass", that means that the side on move passed.
-
 
2480
 This includes the case where the game started from a black-to-move
-
 
2481
 position; then white's first move is recorded as a pass.
-
 
2482
 */
-
 
2483
      if (strcmp(buffer, "pass") == 0) {
-
 
2484
        game_wtm = Flip(game_wtm);
-
 
2485
        if (game_wtm)
-
 
2486
          move_number++;
-
 
2487
        continue;
-
 
2488
      }
-
 
2489
      move = InputMove(tree, buffer, 0, game_wtm, 0, 0);
-
 
2490
      if (move) {
2560
    Option(tree);
2491
        MakeMoveRoot(tree, move, game_wtm);
-
 
2492
      } else {
-
 
2493
        printf("ERROR!  move %s is illegal\n", buffer);
-
 
2494
        break;
-
 
2495
      }
-
 
2496
      TimeAdjust(0, game_wtm);
-
 
2497
      game_wtm = Flip(game_wtm);
-
 
2498
      if (game_wtm)
-
 
2499
        move_number++;
-
 
2500
    }
-
 
2501
    moves_out_of_book = 0;
-
 
2502
    printf("NOTICE: %d moves to next time control\n",
-
 
2503
        tc_moves_remaining[root_wtm]);
-
 
2504
  }
2561
  }
2505
/*
2562
/*
2506
 ************************************************************
2563
 ************************************************************
2507
 *                                                          *
2564
 *                                                          *
2508
 *  "read" reads game moves in and makes them.  This can    *
2565
 *  "read" reads game moves in and makes them.  This can    *
Line 2517... Line 2574...
2517
 *  before reading moves.                                   *
2574
 *  before reading moves.                                   *
2518
 *                                                          *
2575
 *                                                          *
2519
 ************************************************************
2576
 ************************************************************
2520
 */
2577
 */
2521
  else if (OptionMatch("read", *args) || OptionMatch("reada", *args)) {
2578
  else if (OptionMatch("read", *args) || OptionMatch("reada", *args)) {
2522
    int append, move, readstat;
-
 
2523
    FILE *read_input = 0;
2579
    FILE *read_input = 0;
-
 
2580
    int append, move, readstat;
2524
 
2581
 
2525
    if (thinking || pondering)
2582
    if (thinking || pondering)
2526
      return 2;
2583
      return 2;
2527
    nargs = ReadParse(buffer, args, " \t=");
2584
    nargs = ReadParse(buffer, args, " \t=");
2528
    if (!strcmp("reada", *args))
2585
    if (!strcmp("reada", *args))
Line 2531... Line 2588...
2531
      append = 0;
2588
      append = 0;
2532
    ponder_move = 0;
2589
    ponder_move = 0;
2533
    last_pv.pathd = 0;
2590
    last_pv.pathd = 0;
2534
    last_pv.pathl = 0;
2591
    last_pv.pathl = 0;
2535
    if (nargs > 1) {
2592
    if (nargs > 1) {
2536
      fopen_s(&read_input, args[1], "r"); // Pierre-Marie Baty -- use safe version
-
 
2537
      if (!read_input) {
2593
      if (!(read_input = fopen(args[1], "r"))) {
2538
        printf("file %s does not exist.\n", args[1]);
2594
        printf("file %s does not exist.\n", args[1]);
2539
        return 1;
2595
        return 1;
2540
      }
2596
      }
2541
    } else {
2597
    } else {
2542
      printf("type \"exit\" to terminate.\n");
2598
      printf("type \"exit\" to terminate.\n");
Line 2571... Line 2627...
2571
    do {
2627
    do {
2572
      move = 0;
2628
      move = 0;
2573
      move = ReadNextMove(tree, buffer, 0, game_wtm);
2629
      move = ReadNextMove(tree, buffer, 0, game_wtm);
2574
      if (move) {
2630
      if (move) {
2575
        if (read_input != stdin) {
2631
        if (read_input != stdin) {
2576
          printf("%s ", OutputMove(tree, move, 0, game_wtm));
2632
          printf("%s ", OutputMove(tree, 0, game_wtm, move));
2577
          if (!(move_number % 8) && Flip(game_wtm))
2633
          if (!(move_number % 8) && Flip(game_wtm))
2578
            printf("\n");
2634
            printf("\n");
2579
        }
2635
        }
2580
        fseek(history_file, ((move_number - 1) * 2 + 1 - game_wtm) * 10,
2636
        fseek(history_file, ((move_number - 1) * 2 + 1 - game_wtm) * 10,
2581
            SEEK_SET);
2637
            SEEK_SET);
2582
        fprintf(history_file, "%9s\n", OutputMove(tree, move, 0, game_wtm));
2638
        fprintf(history_file, "%9s\n", OutputMove(tree, 0, game_wtm, move));
2583
        MakeMoveRoot(tree, move, game_wtm);
2639
        MakeMoveRoot(tree, game_wtm, move);
2584
        TimeAdjust(0, game_wtm);
2640
        TimeAdjust(game_wtm, 0);
2585
#if defined(DEBUG)
2641
#if defined(DEBUG)
2586
        ValidatePosition(tree, 1, move, "Option()");
2642
        ValidatePosition(tree, 1, move, "Option()");
2587
#endif
2643
#endif
2588
      } else if (!read_input)
2644
      } else if (!read_input)
2589
        printf("illegal move.\n");
2645
        printf("illegal move.\n");
Line 2622... Line 2678...
2622
 *                                                          *
2678
 *                                                          *
2623
 ************************************************************
2679
 ************************************************************
2624
 */
2680
 */
2625
  else if (OptionMatch("rejected", *args)) {
2681
  else if (OptionMatch("rejected", *args)) {
2626
    Print(4095, "ERROR.  feature %s rejected by xboard\n", args[1]);
2682
    Print(4095, "ERROR.  feature %s rejected by xboard\n", args[1]);
-
 
2683
  }
-
 
2684
/*
-
 
2685
 ************************************************************
-
 
2686
 *                                                          *
-
 
2687
 *  "reset" restores (backs up) a game to a prior position  *
-
 
2688
 *  with the same side on move.  Reset 17 would reset the   *
-
 
2689
 *  position to what it was at move 17 with the current     *
-
 
2690
 *  still on move (you can use white/black commands to      *
-
 
2691
 *  change the side to move first, if needed.)              *
-
 
2692
 *                                                          *
-
 
2693
 ************************************************************
-
 
2694
 */
-
 
2695
  else if (OptionMatch("reset", *args)) {
-
 
2696
    int i, move, nmoves;
-
 
2697
 
-
 
2698
    if (!history_file)
-
 
2699
      return 1;
-
 
2700
    if (thinking || pondering)
-
 
2701
      return 2;
-
 
2702
    if (nargs < 2) {
-
 
2703
      printf("usage:  reset <movenumber>\n");
-
 
2704
      return 1;
-
 
2705
    }
-
 
2706
    ponder_move = 0;
-
 
2707
    last_mate_score = 0;
-
 
2708
    last_pv.pathd = 0;
-
 
2709
    last_pv.pathl = 0;
-
 
2710
    if (thinking || pondering)
-
 
2711
      return 2;
-
 
2712
    over = 0;
-
 
2713
    move_number = atoi(args[1]);
-
 
2714
    if (!move_number) {
-
 
2715
      move_number = 1;
-
 
2716
      return 1;
-
 
2717
    }
-
 
2718
    nmoves = (move_number - 1) * 2 + 1 - game_wtm;
-
 
2719
    root_wtm = Flip(game_wtm);
-
 
2720
    InitializeChessBoard(tree);
-
 
2721
    game_wtm = 1;
-
 
2722
    move_number = 1;
-
 
2723
    tc_moves_remaining[white] = tc_moves;
-
 
2724
    tc_moves_remaining[black] = tc_moves;
-
 
2725
    for (i = 0; i < nmoves; i++) {
-
 
2726
      fseek(history_file, i * 10, SEEK_SET);
-
 
2727
      v = fscanf(history_file, "%s", buffer);
-
 
2728
      if (v <= 0)
-
 
2729
        perror("Option() fscanf error: ");
-
 
2730
/*
-
 
2731
 If the move is "pass", that means that the side on move passed.
-
 
2732
 This includes the case where the game started from a black-to-move
-
 
2733
 position; then white's first move is recorded as a pass.
-
 
2734
 */
-
 
2735
      if (strcmp(buffer, "pass") == 0) {
-
 
2736
        game_wtm = Flip(game_wtm);
-
 
2737
        if (game_wtm)
-
 
2738
          move_number++;
-
 
2739
        continue;
-
 
2740
      }
-
 
2741
      move = InputMove(tree, 0, game_wtm, 0, 0, buffer);
-
 
2742
      if (move)
-
 
2743
        MakeMoveRoot(tree, game_wtm, move);
-
 
2744
      else {
-
 
2745
        printf("ERROR!  move %s is illegal\n", buffer);
-
 
2746
        break;
-
 
2747
      }
-
 
2748
      TimeAdjust(game_wtm, 0);
-
 
2749
      game_wtm = Flip(game_wtm);
-
 
2750
      if (game_wtm)
-
 
2751
        move_number++;
-
 
2752
    }
-
 
2753
    moves_out_of_book = 0;
-
 
2754
    printf("NOTICE: %d moves to next time control\n",
-
 
2755
        tc_moves_remaining[root_wtm]);
2627
  }
2756
  }
2628
/*
2757
/*
2629
 ************************************************************
2758
 ************************************************************
2630
 *                                                          *
2759
 *                                                          *
2631
 *  "resign" command sets the resignation threshold to the  *
2760
 *  "resign" command sets the resignation threshold to the  *
Line 2638... Line 2767...
2638
 */
2767
 */
2639
  else if (OptionMatch("resign", *args)) {
2768
  else if (OptionMatch("resign", *args)) {
2640
    if (nargs < 2) {
2769
    if (nargs < 2) {
2641
      if (crafty_is_white) {
2770
      if (crafty_is_white) {
2642
        Print(4095, "result 1-0\n");
2771
        Print(4095, "result 1-0\n");
2643
        strcpy_s(pgn_result, sizeof (pgn_result), "1-0"); // Pierre-Marie Baty -- use safe version
2772
        strcpy(pgn_result, "1-0");
2644
      } else {
2773
      } else {
2645
        Print(4095, "result 0-1\n");
2774
        Print(4095, "result 0-1\n");
2646
        strcpy_s(pgn_result, sizeof (pgn_result), "0-1"); // Pierre-Marie Baty -- use safe version
2775
        strcpy(pgn_result, "0-1");
2647
      }
2776
      }
2648
      learn_value = 300;
2777
      learn_value = 300;
2649
      LearnBook();
2778
      LearnBook();
2650
      return 1;
2779
      return 1;
2651
    }
2780
    }
2652
    resign = atoi(args[1]);
2781
    resign = atoi(args[1]);
2653
    if (nargs == 3)
2782
    if (nargs == 3)
2654
      resign_count = atoi(args[2]);
2783
      resign_count = atoi(args[2]);
2655
    if (resign)
2784
    if (resign)
2656
      Print(128, "resign after %d consecutive moves with score < %d.\n",
2785
      Print(32, "resign after %d consecutive moves with score < %d.\n",
2657
          resign_count, -resign);
2786
          resign_count, -resign);
2658
    else
2787
    else
2659
      Print(128, "disabled resignations.\n");
2788
      Print(32, "disabled resignations.\n");
2660
  }
2789
  }
2661
/*
2790
/*
2662
 ************************************************************
2791
 ************************************************************
2663
 *                                                          *
2792
 *                                                          *
2664
 *  "result" command comes from xboard/winboard and gives   *
2793
 *  "result" command comes from xboard/winboard and gives   *
Line 2668... Line 2797...
2668
 ************************************************************
2797
 ************************************************************
2669
 */
2798
 */
2670
  else if (OptionMatch("result", *args)) {
2799
  else if (OptionMatch("result", *args)) {
2671
    if (nargs > 1) {
2800
    if (nargs > 1) {
2672
      if (!strcmp(args[1], "1-0")) {
2801
      if (!strcmp(args[1], "1-0")) {
2673
        strcpy_s(pgn_result, sizeof (pgn_result), "1-0"); // Pierre-Marie Baty -- use safe version
2802
        strcpy(pgn_result, "1-0");
2674
        if (crafty_is_white)
2803
        if (crafty_is_white)
2675
          learn_value = 300;
2804
          learn_value = 300;
2676
        else
2805
        else
2677
          learn_value = -300;
2806
          learn_value = -300;
2678
      } else if (!strcmp(args[1], "0-1")) {
2807
      } else if (!strcmp(args[1], "0-1")) {
2679
        strcpy_s(pgn_result, sizeof (pgn_result), "0-1"); // Pierre-Marie Baty -- use safe version
2808
        strcpy(pgn_result, "0-1");
2680
        if (crafty_is_white)
2809
        if (crafty_is_white)
2681
          learn_value = -300;
2810
          learn_value = -300;
2682
        else
2811
        else
2683
          learn_value = 300;
2812
          learn_value = 300;
2684
      } else if (!strcmp(args[1], "1/2-1/2")) {
2813
      } else if (!strcmp(args[1], "1/2-1/2")) {
2685
        strcpy_s(pgn_result, sizeof (pgn_result), "1/2-1/2"); // Pierre-Marie Baty -- use safe version
2814
        strcpy(pgn_result, "1/2-1/2");
2686
        learn_value = 1;
2815
        learn_value = 1;
2687
      }
2816
      }
2688
      LearnBook();
2817
      LearnBook();
2689
      return 1;
2818
      return 1;
2690
    }
2819
    }
-
 
2820
  }
-
 
2821
/*
-
 
2822
 ************************************************************
-
 
2823
 *                                                          *
-
 
2824
 *  "safety" command sets a specific time safety margin     *
-
 
2825
 *  target for normal timed games.  This can generally be   *
-
 
2826
 *  left at the default value unless Crafty is being        *
-
 
2827
 *  manually operated.                                      *
-
 
2828
 *                                                          *
-
 
2829
 ************************************************************
-
 
2830
 */
-
 
2831
  else if (OptionMatch("safety", *args)) {
-
 
2832
    if (nargs == 2)
-
 
2833
      tc_safety_margin = atoi(args[1]) * 100;
-
 
2834
    Print(32, "safety margin set to %s.\n", DisplayTime(tc_safety_margin));
2691
  }
2835
  }
2692
/*
2836
/*
2693
 ************************************************************
2837
 ************************************************************
2694
 *                                                          *
2838
 *                                                          *
2695
 *  "savegame" command saves the game in a file in PGN      *
2839
 *  "savegame" command saves the game in a file in PGN      *
Line 2697... Line 2841...
2697
 *                                                          *
2841
 *                                                          *
2698
 ************************************************************
2842
 ************************************************************
2699
 */
2843
 */
2700
  else if (OptionMatch("savegame", *args)) {
2844
  else if (OptionMatch("savegame", *args)) {
2701
    struct tm *timestruct;
2845
    struct tm *timestruct;
2702
    int i, more, swtm;
-
 
2703
    time_t secs;
-
 
2704
    FILE *output_file;
2846
    FILE *output_file;
-
 
2847
    time_t secs;
-
 
2848
    int i, more, swtm;
2705
    char input[128], text[128], *next;
2849
    char input[128], text[128], *next;
2706
 
2850
 
2707
    output_file = stdout;
2851
    output_file = stdout;
2708
    secs = time(0);
2852
    secs = time(0);
2709
    timestruct = localtime((time_t *) & secs);
2853
    timestruct = localtime((time_t *) & secs);
2710
    if (nargs > 1) {
2854
    if (nargs > 1) {
2711
      fopen_s(&output_file, args[1], "w"); // Pierre-Marie Baty -- use safe version
-
 
2712
      if (!output_file) {
2855
      if (!(output_file = fopen(args[1], "w"))) {
2713
        printf("unable to open %s for write.\n", args[1]);
2856
        printf("unable to open %s for write.\n", args[1]);
2714
        return 1;
2857
        return 1;
2715
      }
2858
      }
2716
    }
2859
    }
2717
    fprintf(output_file, "[Event \"%s\"]\n", pgn_event);
2860
    fprintf(output_file, "[Event \"%s\"]\n", pgn_event);
Line 2727... Line 2870...
2727
    fprintf(output_file, "[Result \"%s\"]\n", pgn_result);
2870
    fprintf(output_file, "[Result \"%s\"]\n", pgn_result);
2728
/* Handle setup positions and initial pass by white */
2871
/* Handle setup positions and initial pass by white */
2729
    swtm = 1;
2872
    swtm = 1;
2730
    if (move_number > 1 || !game_wtm) {
2873
    if (move_number > 1 || !game_wtm) {
2731
      fseek(history_file, 0, SEEK_SET);
2874
      fseek(history_file, 0, SEEK_SET);
2732
      if (fscanf_s(history_file, "%s", input, sizeof (input)) == 1 && // Pierre-Marie Baty -- use safe version
2875
      if (fscanf(history_file, "%s", input) == 1 &&
2733
          strcmp(input, "pass") == 0)
2876
          strcmp(input, "pass") == 0)
2734
        swtm = 0;
2877
        swtm = 0;
2735
    }
2878
    }
2736
    if (initial_position[0])
2879
    if (initial_position[0])
2737
      fprintf(output_file, "[FEN \"%s\"]\n[SetUp \"1\"]\n", initial_position);
2880
      fprintf(output_file, "[FEN \"%s\"]\n[SetUp \"1\"]\n", initial_position);
Line 2741... Line 2884...
2741
          "[SetUp \"1\"]\n");
2884
          "[SetUp \"1\"]\n");
2742
    }
2885
    }
2743
    fprintf(output_file, "\n");
2886
    fprintf(output_file, "\n");
2744
    next = text;
2887
    next = text;
2745
    if (!swtm) {
2888
    if (!swtm) {
2746
      strcpy_s(text, sizeof (text), "1... "); // Pierre-Marie Baty -- use safe version
2889
      strcpy(next, "1... ");
2747
      next = text + strlen(text);
2890
      next = text + strlen(text);
2748
    }
2891
    }
2749
/* Output the moves */
2892
/* Output the moves */
2750
    more = 0;
2893
    more = 0;
2751
    for (i = (swtm ? 0 : 1); i < (move_number - 1) * 2 - game_wtm + 1; i++) {
2894
    for (i = (swtm ? 0 : 1); i < (move_number - 1) * 2 - game_wtm + 1; i++) {
2752
      fseek(history_file, i * 10, SEEK_SET);
2895
      fseek(history_file, i * 10, SEEK_SET);
2753
      fscanf(history_file, "%s", input);
2896
      v = fscanf(history_file, "%s", input);
-
 
2897
      if (v <= 0)
-
 
2898
        perror("Option() fscanf error: ");
2754
      if (!(i % 2)) {
2899
      if (!(i % 2)) {
2755
        sprintf(next, "%d. ", i / 2 + 1);
2900
        sprintf(next, "%d. ", i / 2 + 1);
2756
        next = text + strlen(text);
2901
        next = text + strlen(text);
2757
      }
2902
      }
2758
      sprintf(next, "%s ", input);
2903
      sprintf(next, "%s ", input);
Line 2779... Line 2924...
2779
 *  used to recreate this exact position.                   *
2924
 *  used to recreate this exact position.                   *
2780
 *                                                          *
2925
 *                                                          *
2781
 ************************************************************
2926
 ************************************************************
2782
 */
2927
 */
2783
  else if (OptionMatch("savepos", *args)) {
2928
  else if (OptionMatch("savepos", *args)) {
2784
    int rank, file, nempty;
-
 
2785
    FILE *output_file;
2929
    FILE *output_file;
-
 
2930
    int rank, file, nempty;
2786
 
2931
 
2787
    output_file = stdout;
2932
    output_file = stdout;
2788
    if (nargs > 1) {
2933
    if (nargs > 1) {
2789
      if (!strcmp(args[1], "*")) {
2934
      if (!strcmp(args[1], "*")) {
2790
        output_file = 0;
2935
        output_file = 0;
2791
        initial_position[0] = 0; // Pierre-Marie Baty -- use safe version
2936
        strcpy(initial_position, "");
2792
      } else if (!(output_file = fopen(args[1], "w"))) {
2937
      } else if (!(output_file = fopen(args[1], "w"))) {
2793
        printf("unable to open %s for write.\n", args[1]);
2938
        printf("unable to open %s for write.\n", args[1]);
2794
        return 1;
2939
        return 1;
2795
      }
2940
      }
2796
    }
2941
    }
Line 2826... Line 2971...
2826
      }
2971
      }
2827
      if (rank != RANK1) {
2972
      if (rank != RANK1) {
2828
        if (output_file)
2973
        if (output_file)
2829
          fprintf(output_file, "/");
2974
          fprintf(output_file, "/");
2830
        else
2975
        else
2831
          strcat_s(initial_position, sizeof (initial_position), "/"); // Pierre-Marie Baty -- use safe version
2976
          sprintf(initial_position + strlen(initial_position), "/");
2832
      }
2977
      }
2833
    }
2978
    }
2834
    if (output_file)
2979
    if (output_file)
2835
      fprintf(output_file, " %c ", (game_wtm) ? 'w' : 'b');
2980
      fprintf(output_file, " %c ", (game_wtm) ? 'w' : 'b');
2836
    else
2981
    else
2837
      strcat_s(initial_position, sizeof (initial_position), (game_wtm) ? " w " : " b "); // Pierre-Marie Baty -- use safe version
2982
      sprintf(initial_position + strlen(initial_position), " %c ",
-
 
2983
          (game_wtm) ? 'w' : 'b');
2838
    if (Castle(0, white) & 1) {
2984
    if (Castle(0, white) & 1) {
2839
      if (output_file)
2985
      if (output_file)
2840
        fprintf(output_file, "K");
2986
        fprintf(output_file, "K");
2841
      else
2987
      else
2842
        strcat_s(initial_position, sizeof (initial_position), "K"); // Pierre-Marie Baty -- use safe version
2988
        sprintf(initial_position + strlen(initial_position), "K");
2843
    }
2989
    }
2844
    if (Castle(0, white) & 2) {
2990
    if (Castle(0, white) & 2) {
2845
      if (output_file)
2991
      if (output_file)
2846
        fprintf(output_file, "Q");
2992
        fprintf(output_file, "Q");
2847
      else
2993
      else
2848
        strcat_s(initial_position, sizeof (initial_position), "Q"); // Pierre-Marie Baty -- use safe version
2994
        sprintf(initial_position + strlen(initial_position), "Q");
2849
    }
2995
    }
2850
    if (Castle(0, black) & 1) {
2996
    if (Castle(0, black) & 1) {
2851
      if (output_file)
2997
      if (output_file)
2852
        fprintf(output_file, "k");
2998
        fprintf(output_file, "k");
2853
      else
2999
      else
2854
        strcat_s(initial_position, sizeof (initial_position), "k"); // Pierre-Marie Baty -- use safe version
3000
        sprintf(initial_position + strlen(initial_position), "k");
2855
    }
3001
    }
2856
    if (Castle(0, black) & 2) {
3002
    if (Castle(0, black) & 2) {
2857
      if (output_file)
3003
      if (output_file)
2858
        fprintf(output_file, "q");
3004
        fprintf(output_file, "q");
2859
      else
3005
      else
2860
        strcat_s(initial_position, sizeof (initial_position), "q"); // Pierre-Marie Baty -- use safe version
3006
        sprintf(initial_position + strlen(initial_position), "q");
2861
    }
3007
    }
2862
    if (!Castle(0, white) && !Castle(0, black)) {
3008
    if (!Castle(0, white) && !Castle(0, black)) {
2863
      if (output_file)
3009
      if (output_file)
2864
        fprintf(output_file, " -");
3010
        fprintf(output_file, " -");
2865
      else
3011
      else
2866
        strcat_s(initial_position, sizeof (initial_position), " -"); // Pierre-Marie Baty -- use safe version
3012
        sprintf(initial_position + strlen(initial_position), " -");
2867
    }
3013
    }
2868
    if (EnPassant(0)) {
3014
    if (EnPassant(0)) {
2869
      if (output_file)
3015
      if (output_file)
2870
        fprintf(output_file, " %c%c", File(EnPassant(0)) + 'a',
3016
        fprintf(output_file, " %c%c", File(EnPassant(0)) + 'a',
2871
            Rank(EnPassant(0)) + '1');
3017
            Rank(EnPassant(0)) + '1');
Line 2874... Line 3020...
2874
            File(EnPassant(0)) + 'a', Rank(EnPassant(0)) + '1');
3020
            File(EnPassant(0)) + 'a', Rank(EnPassant(0)) + '1');
2875
    } else {
3021
    } else {
2876
      if (output_file)
3022
      if (output_file)
2877
        fprintf(output_file, " -");
3023
        fprintf(output_file, " -");
2878
      else
3024
      else
2879
        strcat_s(initial_position, sizeof (initial_position), " -"); // Pierre-Marie Baty -- use safe version
3025
        sprintf(initial_position + strlen(initial_position), " -");
2880
    }
3026
    }
2881
    if (output_file)
3027
    if (output_file)
2882
      fprintf(output_file, "\n");
3028
      fprintf(output_file, "\n");
2883
    if (output_file && output_file != stdout) {
3029
    if (output_file && output_file != stdout) {
2884
      fprintf(output_file, "exit\n");
3030
      fprintf(output_file, "exit\n");
Line 2894... Line 3040...
2894
 *  scale some scoring value(s) by a percentage that can    *
3040
 *  scale some scoring value(s) by a percentage that can    *
2895
 *  be either positive or negative.                         *
3041
 *  be either positive or negative.                         *
2896
 *                                                          *
3042
 *                                                          *
2897
 ************************************************************
3043
 ************************************************************
2898
 */
3044
 */
2899
 
-
 
2900
  else if (!strcmp("scale", *args)) {
3045
  else if (!strcmp("scale", *args)) {
2901
    scale = atoi(args[1]);
3046
    scale = atoi(args[1]);
2902
  }
-
 
2903
/*
-
 
2904
 ************************************************************
-
 
2905
 *                                                          *
-
 
2906
 *  "search" command sets a specific move for the search    *
-
 
2907
 *  to analyze, ignoring all others completely.             *
-
 
2908
 *                                                          *
-
 
2909
 ************************************************************
-
 
2910
 */
-
 
2911
  else if (OptionMatch("search", *args)) {
-
 
2912
    if (thinking || pondering)
-
 
2913
      return 2;
-
 
2914
    if (nargs < 2) {
-
 
2915
      printf("usage:  search <move>\n");
-
 
2916
      return 1;
-
 
2917
    }
-
 
2918
    search_move = InputMove(tree, args[1], 0, game_wtm, 0, 0);
-
 
2919
    if (!search_move)
-
 
2920
      search_move = InputMove(tree, args[1], 0, Flip(game_wtm), 0, 0);
-
 
2921
    if (!search_move)
-
 
2922
      printf("illegal move.\n");
-
 
2923
  }
-
 
2924
/*
-
 
2925
 ************************************************************
-
 
2926
 *                                                          *
-
 
2927
 *  "settc" command is used to reset the time controls      *
-
 
2928
 *  after a complete restart.                               *
-
 
2929
 *                                                          *
-
 
2930
 ************************************************************
-
 
2931
 */
-
 
2932
  else if (OptionMatch("settc", *args)) {
-
 
2933
    if (thinking || pondering)
-
 
2934
      return 2;
-
 
2935
    if (nargs < 4) {
-
 
2936
      printf("usage:  settc <wmoves> <wtime> <bmoves> <btime>\n");
-
 
2937
      return 1;
-
 
2938
    }
-
 
2939
    tc_moves_remaining[white] = atoi(args[1]);
-
 
2940
    tc_time_remaining[white] = ParseTime(args[2]) * 6000;
-
 
2941
    tc_moves_remaining[black] = atoi(args[3]);
-
 
2942
    tc_time_remaining[black] = ParseTime(args[4]) * 6000;
-
 
2943
    Print(128, "time remaining: %s (white).\n",
-
 
2944
        DisplayTime(tc_time_remaining[white]));
-
 
2945
    Print(128, "time remaining: %s (black).\n",
-
 
2946
        DisplayTime(tc_time_remaining[black]));
-
 
2947
    if (tc_sudden_death != 1) {
-
 
2948
      Print(128, "%d moves to next time control (white)\n",
-
 
2949
          tc_moves_remaining[white]);
-
 
2950
      Print(128, "%d moves to next time control (black)\n",
-
 
2951
          tc_moves_remaining[black]);
-
 
2952
    } else
-
 
2953
      Print(128, "Sudden-death time control in effect\n");
-
 
2954
  }
-
 
2955
/*
-
 
2956
 ************************************************************
-
 
2957
 *                                                          *
-
 
2958
 *  "setboard" command sets the board to a specific         *
-
 
2959
 *  position for analysis by the program.                   *
-
 
2960
 *                                                          *
-
 
2961
 ************************************************************
-
 
2962
 */
-
 
2963
  else if (OptionMatch("setboard", *args)) {
-
 
2964
    if (thinking || pondering)
-
 
2965
      return 2;
-
 
2966
    nargs = ReadParse(buffer, args, " \t;=");
-
 
2967
    if (nargs < 3) {
-
 
2968
      printf("usage:  setboard <fen>\n");
-
 
2969
      return 1;
-
 
2970
    }
-
 
2971
    SetBoard(tree, nargs - 1, args + 1, 0);
-
 
2972
    move_number = 1;
-
 
2973
    if (!game_wtm) {
-
 
2974
      game_wtm = 1;
-
 
2975
      Pass();
-
 
2976
    }
-
 
2977
    ponder_move = 0;
-
 
2978
    last_pv.pathd = 0;
-
 
2979
    last_pv.pathl = 0;
-
 
2980
    over = 0;
-
 
2981
    strcpy_s(buffer, sizeof (buffer), "savepos *"); // Pierre-Marie Baty -- use safe version
-
 
2982
    (void) Option(tree);
-
 
2983
  } else if (StrCnt(*args, '/') > 3) {
-
 
2984
    if (thinking || pondering)
-
 
2985
      return 2;
-
 
2986
    nargs = ReadParse(buffer, args, " \t;=");
-
 
2987
    SetBoard(tree, nargs, args, 0);
-
 
2988
    move_number = 1;
-
 
2989
    if (!game_wtm) {
-
 
2990
      game_wtm = 1;
-
 
2991
      Pass();
-
 
2992
    }
-
 
2993
    ponder_move = 0;
-
 
2994
    last_pv.pathd = 0;
-
 
2995
    last_pv.pathl = 0;
-
 
2996
    over = 0;
-
 
2997
    strcpy_s(buffer, sizeof (buffer), "savepos *"); // Pierre-Marie Baty -- use safe version
-
 
2998
    (void) Option(tree);
-
 
2999
  }
3047
  }
3000
/*
3048
/*
3001
 ************************************************************
3049
 ************************************************************
3002
 *                                                          *
3050
 *                                                          *
3003
 *  "score" command displays static evaluation of the       *
3051
 *  "score" command displays static evaluation of the       *
3004
 *  current board position.                                 *
3052
 *  current board position.                                 *
3005
 *                                                          *
3053
 *                                                          *
3006
 ************************************************************
3054
 ************************************************************
3007
 */
3055
 */
3008
  else if (OptionMatch("score", *args)) {
3056
  else if (OptionMatch("score", *args)) {
3009
    int phase, s, tw, tb;
-
 
3010
    int mgb, mgw, egb, egw;
3057
    int phase, s, tw, tb, mgb, mgw, egb, egw, trop[2];
3011
 
3058
 
3012
    if (thinking || pondering)
3059
    if (thinking || pondering)
3013
      return 2;
3060
      return 2;
-
 
3061
    memset((void *) &(tree->pawn_score), 0, sizeof(tree->pawn_score));
3014
    Print(128, "note: scores are for the white side\n");
3062
    Print(32, "note: scores are for the white side\n");
3015
    Print(128, "                       ");
3063
    Print(32, "                       ");
3016
    Print(128, " +-----------white----------+");
3064
    Print(32, " +-----------white----------+");
3017
    Print(128, "-----------black----------+\n");
3065
    Print(32, "-----------black----------+\n");
3018
    tree->score_mg = 0;
3066
    tree->score_mg = 0;
3019
    tree->score_eg = 0;
3067
    tree->score_eg = 0;
3020
    mgb = tree->score_mg;
3068
    mgb = tree->score_mg;
3021
    EvaluateMaterial(tree, game_wtm);
3069
    EvaluateMaterial(tree, game_wtm);
3022
    mgb = tree->score_mg - mgb;
3070
    mgb = tree->score_mg - mgb;
3023
    Print(128, "material.......%s", DisplayEvaluation(mgb, 1));
3071
    Print(32, "material.......%s", DisplayEvaluation(mgb, 1));
3024
    Print(128, "  |    comp     mg      eg   |");
3072
    Print(32, "  |    comp     mg      eg   |");
3025
    Print(128, "    comp     mg      eg   |\n");
3073
    Print(32, "    comp     mg      eg   |\n");
3026
    root_wtm = Flip(game_wtm);
3074
    root_wtm = Flip(game_wtm);
3027
    tree->status[1] = tree->status[0];
3075
    tree->status[1] = tree->status[0];
3028
    s = Evaluate(tree, 1, game_wtm, -99999, 99999);
3076
    s = Evaluate(tree, 1, game_wtm, -99999, 99999);
-
 
3077
    trop[black] = tree->tropism[black];
-
 
3078
    trop[white] = tree->tropism[white];
3029
    if (!game_wtm)
3079
    if (!game_wtm)
3030
      s = -s;
3080
      s = -s;
3031
    tree->score_mg = 0;
3081
    tree->score_mg = 0;
3032
    tree->score_eg = 0;
3082
    tree->score_eg = 0;
3033
    tree->tropism[black] = 0;
-
 
3034
    tree->tropism[white] = 0;
-
 
3035
    phase =
3083
    phase =
3036
        Min(62, TotalPieces(white, occupied) + TotalPieces(black, occupied));
3084
        Min(62, TotalPieces(white, occupied) + TotalPieces(black, occupied));
3037
    tree->pawn_score.score_mg = 0;
3085
    tree->pawn_score.score_mg = 0;
3038
    tree->pawn_score.score_eg = 0;
3086
    tree->pawn_score.score_eg = 0;
3039
    mgb = tree->pawn_score.score_mg;
3087
    mgb = tree->pawn_score.score_mg;
Line 3046... Line 3094...
3046
    EvaluatePawns(tree, white);
3094
    EvaluatePawns(tree, white);
3047
    mgw = tree->pawn_score.score_mg - mgw;
3095
    mgw = tree->pawn_score.score_mg - mgw;
3048
    egw = tree->pawn_score.score_eg - egw;
3096
    egw = tree->pawn_score.score_eg - egw;
3049
    tb = (mgb * phase + egb * (62 - phase)) / 62;
3097
    tb = (mgb * phase + egb * (62 - phase)) / 62;
3050
    tw = (mgw * phase + egw * (62 - phase)) / 62;
3098
    tw = (mgw * phase + egw * (62 - phase)) / 62;
3051
    Print(128, "pawns..........%s  |", DisplayEvaluation(tb + tw, 1));
3099
    Print(32, "pawns..........%s  |", DisplayEvaluation(tb + tw, 1));
3052
    Print(128, " %s", DisplayEvaluation(tw, 1));
3100
    Print(32, " %s", DisplayEvaluation(tw, 1));
3053
    Print(128, " %s", DisplayEvaluation(mgw, 1));
3101
    Print(32, " %s", DisplayEvaluation(mgw, 1));
3054
    Print(128, " %s  |", DisplayEvaluation(egw, 1));
3102
    Print(32, " %s  |", DisplayEvaluation(egw, 1));
3055
    Print(128, " %s", DisplayEvaluation(tb, 1));
3103
    Print(32, " %s", DisplayEvaluation(tb, 1));
3056
    Print(128, " %s", DisplayEvaluation(mgb, 1));
3104
    Print(32, " %s", DisplayEvaluation(mgb, 1));
3057
    Print(128, " %s  |\n", DisplayEvaluation(egb, 1));
3105
    Print(32, " %s  |\n", DisplayEvaluation(egb, 1));
3058
    mgb = tree->score_mg;
3106
    mgb = tree->score_mg;
3059
    egb = tree->score_eg;
3107
    egb = tree->score_eg;
3060
    EvaluatePassedPawns(tree, black, game_wtm);
3108
    EvaluatePassedPawns(tree, black, game_wtm);
3061
    mgb = tree->score_mg - mgb;
3109
    mgb = tree->score_mg - mgb;
3062
    egb = tree->score_eg - egb;
3110
    egb = tree->score_eg - egb;
Line 3065... Line 3113...
3065
    EvaluatePassedPawns(tree, white, game_wtm);
3113
    EvaluatePassedPawns(tree, white, game_wtm);
3066
    mgw = tree->score_mg - mgw;
3114
    mgw = tree->score_mg - mgw;
3067
    egw = tree->score_eg - egw;
3115
    egw = tree->score_eg - egw;
3068
    tb = (mgb * phase + egb * (62 - phase)) / 62;
3116
    tb = (mgb * phase + egb * (62 - phase)) / 62;
3069
    tw = (mgw * phase + egw * (62 - phase)) / 62;
3117
    tw = (mgw * phase + egw * (62 - phase)) / 62;
3070
    Print(128, "passed pawns...%s  |", DisplayEvaluation(tb + tw, 1));
3118
    Print(32, "passed pawns...%s  |", DisplayEvaluation(tb + tw, 1));
3071
    Print(128, " %s", DisplayEvaluation(tw, 1));
3119
    Print(32, " %s", DisplayEvaluation(tw, 1));
3072
    Print(128, " %s", DisplayEvaluation(mgw, 1));
3120
    Print(32, " %s", DisplayEvaluation(mgw, 1));
3073
    Print(128, " %s  |", DisplayEvaluation(egw, 1));
3121
    Print(32, " %s  |", DisplayEvaluation(egw, 1));
3074
    Print(128, " %s", DisplayEvaluation(tb, 1));
3122
    Print(32, " %s", DisplayEvaluation(tb, 1));
3075
    Print(128, " %s", DisplayEvaluation(mgb, 1));
3123
    Print(32, " %s", DisplayEvaluation(mgb, 1));
3076
    Print(128, " %s  |\n", DisplayEvaluation(egb, 1));
3124
    Print(32, " %s  |\n", DisplayEvaluation(egb, 1));
3077
    mgb = tree->score_mg;
3125
    mgb = tree->score_mg;
3078
    egb = tree->score_eg;
3126
    egb = tree->score_eg;
3079
    EvaluateKnights(tree, black);
3127
    EvaluateKnights(tree, black);
3080
    mgb = tree->score_mg - mgb;
3128
    mgb = tree->score_mg - mgb;
3081
    egb = tree->score_eg - egb;
3129
    egb = tree->score_eg - egb;
Line 3084... Line 3132...
3084
    EvaluateKnights(tree, white);
3132
    EvaluateKnights(tree, white);
3085
    mgw = tree->score_mg - mgw;
3133
    mgw = tree->score_mg - mgw;
3086
    egw = tree->score_eg - egw;
3134
    egw = tree->score_eg - egw;
3087
    tb = (mgb * phase + egb * (62 - phase)) / 62;
3135
    tb = (mgb * phase + egb * (62 - phase)) / 62;
3088
    tw = (mgw * phase + egw * (62 - phase)) / 62;
3136
    tw = (mgw * phase + egw * (62 - phase)) / 62;
3089
    Print(128, "knights........%s  |", DisplayEvaluation(tb + tw, 1));
3137
    Print(32, "knights........%s  |", DisplayEvaluation(tb + tw, 1));
3090
    Print(128, " %s", DisplayEvaluation(tw, 1));
3138
    Print(32, " %s", DisplayEvaluation(tw, 1));
3091
    Print(128, " %s", DisplayEvaluation(mgw, 1));
3139
    Print(32, " %s", DisplayEvaluation(mgw, 1));
3092
    Print(128, " %s  |", DisplayEvaluation(egw, 1));
3140
    Print(32, " %s  |", DisplayEvaluation(egw, 1));
3093
    Print(128, " %s", DisplayEvaluation(tb, 1));
3141
    Print(32, " %s", DisplayEvaluation(tb, 1));
3094
    Print(128, " %s", DisplayEvaluation(mgb, 1));
3142
    Print(32, " %s", DisplayEvaluation(mgb, 1));
3095
    Print(128, " %s  |\n", DisplayEvaluation(egb, 1));
3143
    Print(32, " %s  |\n", DisplayEvaluation(egb, 1));
3096
    mgb = tree->score_mg;
3144
    mgb = tree->score_mg;
3097
    egb = tree->score_eg;
3145
    egb = tree->score_eg;
3098
    EvaluateBishops(tree, black);
3146
    EvaluateBishops(tree, black);
3099
    mgb = tree->score_mg - mgb;
3147
    mgb = tree->score_mg - mgb;
3100
    egb = tree->score_eg - egb;
3148
    egb = tree->score_eg - egb;
Line 3103... Line 3151...
3103
    EvaluateBishops(tree, white);
3151
    EvaluateBishops(tree, white);
3104
    mgw = tree->score_mg - mgw;
3152
    mgw = tree->score_mg - mgw;
3105
    egw = tree->score_eg - egw;
3153
    egw = tree->score_eg - egw;
3106
    tb = (mgb * phase + egb * (62 - phase)) / 62;
3154
    tb = (mgb * phase + egb * (62 - phase)) / 62;
3107
    tw = (mgw * phase + egw * (62 - phase)) / 62;
3155
    tw = (mgw * phase + egw * (62 - phase)) / 62;
3108
    Print(128, "bishops........%s  |", DisplayEvaluation(tb + tw, 1));
3156
    Print(32, "bishops........%s  |", DisplayEvaluation(tb + tw, 1));
3109
    Print(128, " %s", DisplayEvaluation(tw, 1));
3157
    Print(32, " %s", DisplayEvaluation(tw, 1));
3110
    Print(128, " %s", DisplayEvaluation(mgw, 1));
3158
    Print(32, " %s", DisplayEvaluation(mgw, 1));
3111
    Print(128, " %s  |", DisplayEvaluation(egw, 1));
3159
    Print(32, " %s  |", DisplayEvaluation(egw, 1));
3112
    Print(128, " %s", DisplayEvaluation(tb, 1));
3160
    Print(32, " %s", DisplayEvaluation(tb, 1));
3113
    Print(128, " %s", DisplayEvaluation(mgb, 1));
3161
    Print(32, " %s", DisplayEvaluation(mgb, 1));
3114
    Print(128, " %s  |\n", DisplayEvaluation(egb, 1));
3162
    Print(32, " %s  |\n", DisplayEvaluation(egb, 1));
3115
    mgb = tree->score_mg;
3163
    mgb = tree->score_mg;
3116
    egb = tree->score_eg;
3164
    egb = tree->score_eg;
3117
    EvaluateRooks(tree, black);
3165
    EvaluateRooks(tree, black);
3118
    mgb = tree->score_mg - mgb;
3166
    mgb = tree->score_mg - mgb;
3119
    egb = tree->score_eg - egb;
3167
    egb = tree->score_eg - egb;
Line 3122... Line 3170...
3122
    EvaluateRooks(tree, white);
3170
    EvaluateRooks(tree, white);
3123
    mgw = tree->score_mg - mgw;
3171
    mgw = tree->score_mg - mgw;
3124
    egw = tree->score_eg - egw;
3172
    egw = tree->score_eg - egw;
3125
    tb = (mgb * phase + egb * (62 - phase)) / 62;
3173
    tb = (mgb * phase + egb * (62 - phase)) / 62;
3126
    tw = (mgw * phase + egw * (62 - phase)) / 62;
3174
    tw = (mgw * phase + egw * (62 - phase)) / 62;
3127
    Print(128, "rooks..........%s  |", DisplayEvaluation(tb + tw, 1));
3175
    Print(32, "rooks..........%s  |", DisplayEvaluation(tb + tw, 1));
3128
    Print(128, " %s", DisplayEvaluation(tw, 1));
3176
    Print(32, " %s", DisplayEvaluation(tw, 1));
3129
    Print(128, " %s", DisplayEvaluation(mgw, 1));
3177
    Print(32, " %s", DisplayEvaluation(mgw, 1));
3130
    Print(128, " %s  |", DisplayEvaluation(egw, 1));
3178
    Print(32, " %s  |", DisplayEvaluation(egw, 1));
3131
    Print(128, " %s", DisplayEvaluation(tb, 1));
3179
    Print(32, " %s", DisplayEvaluation(tb, 1));
3132
    Print(128, " %s", DisplayEvaluation(mgb, 1));
3180
    Print(32, " %s", DisplayEvaluation(mgb, 1));
3133
    Print(128, " %s  |\n", DisplayEvaluation(egb, 1));
3181
    Print(32, " %s  |\n", DisplayEvaluation(egb, 1));
3134
    mgb = tree->score_mg;
3182
    mgb = tree->score_mg;
3135
    egb = tree->score_eg;
3183
    egb = tree->score_eg;
3136
    EvaluateQueens(tree, black);
3184
    EvaluateQueens(tree, black);
3137
    mgb = tree->score_mg - mgb;
3185
    mgb = tree->score_mg - mgb;
3138
    egb = tree->score_eg - egb;
3186
    egb = tree->score_eg - egb;
Line 3141... Line 3189...
3141
    EvaluateQueens(tree, white);
3189
    EvaluateQueens(tree, white);
3142
    mgw = tree->score_mg - mgw;
3190
    mgw = tree->score_mg - mgw;
3143
    egw = tree->score_eg - egw;
3191
    egw = tree->score_eg - egw;
3144
    tb = (mgb * phase + egb * (62 - phase)) / 62;
3192
    tb = (mgb * phase + egb * (62 - phase)) / 62;
3145
    tw = (mgw * phase + egw * (62 - phase)) / 62;
3193
    tw = (mgw * phase + egw * (62 - phase)) / 62;
3146
    Print(128, "queens.........%s  |", DisplayEvaluation(tb + tw, 1));
3194
    Print(32, "queens.........%s  |", DisplayEvaluation(tb + tw, 1));
3147
    Print(128, " %s", DisplayEvaluation(tw, 1));
3195
    Print(32, " %s", DisplayEvaluation(tw, 1));
3148
    Print(128, " %s", DisplayEvaluation(mgw, 1));
3196
    Print(32, " %s", DisplayEvaluation(mgw, 1));
3149
    Print(128, " %s  |", DisplayEvaluation(egw, 1));
3197
    Print(32, " %s  |", DisplayEvaluation(egw, 1));
3150
    Print(128, " %s", DisplayEvaluation(tb, 1));
3198
    Print(32, " %s", DisplayEvaluation(tb, 1));
3151
    Print(128, " %s", DisplayEvaluation(mgb, 1));
3199
    Print(32, " %s", DisplayEvaluation(mgb, 1));
3152
    Print(128, " %s  |\n", DisplayEvaluation(egb, 1));
3200
    Print(32, " %s  |\n", DisplayEvaluation(egb, 1));
-
 
3201
    tree->tropism[black] = trop[black];
-
 
3202
    tree->tropism[white] = trop[white];
3153
    mgb = tree->score_mg;
3203
    mgb = tree->score_mg;
3154
    egb = tree->score_eg;
3204
    egb = tree->score_eg;
3155
    EvaluateKings(tree, 1, black);
3205
    EvaluateKing(tree, 1, black);
3156
    mgb = tree->score_mg - mgb;
3206
    mgb = tree->score_mg - mgb;
3157
    egb = tree->score_eg - egb;
3207
    egb = tree->score_eg - egb;
3158
    mgw = tree->score_mg;
3208
    mgw = tree->score_mg;
3159
    egw = tree->score_eg;
3209
    egw = tree->score_eg;
3160
    EvaluateKings(tree, 1, white);
3210
    EvaluateKing(tree, 1, white);
3161
    mgw = tree->score_mg - mgw;
3211
    mgw = tree->score_mg - mgw;
3162
    egw = tree->score_eg - egw;
3212
    egw = tree->score_eg - egw;
3163
    tb = (mgb * phase + egb * (62 - phase)) / 62;
3213
    tb = (mgb * phase + egb * (62 - phase)) / 62;
3164
    tw = (mgw * phase + egw * (62 - phase)) / 62;
3214
    tw = (mgw * phase + egw * (62 - phase)) / 62;
3165
    Print(128, "kings..........%s  |", DisplayEvaluation(tb + tw, 1));
3215
    Print(32, "kings..........%s  |", DisplayEvaluation(tb + tw, 1));
3166
    Print(128, " %s", DisplayEvaluation(tw, 1));
3216
    Print(32, " %s", DisplayEvaluation(tw, 1));
3167
    Print(128, " %s", DisplayEvaluation(mgw, 1));
3217
    Print(32, " %s", DisplayEvaluation(mgw, 1));
3168
    Print(128, " %s  |", DisplayEvaluation(egw, 1));
3218
    Print(32, " %s  |", DisplayEvaluation(egw, 1));
3169
    Print(128, " %s", DisplayEvaluation(tb, 1));
3219
    Print(32, " %s", DisplayEvaluation(tb, 1));
3170
    Print(128, " %s", DisplayEvaluation(mgb, 1));
3220
    Print(32, " %s", DisplayEvaluation(mgb, 1));
3171
    Print(128, " %s  |\n", DisplayEvaluation(egb, 1));
3221
    Print(32, " %s  |\n", DisplayEvaluation(egb, 1));
3172
    mgb = tree->score_mg;
3222
    mgb = tree->score_mg;
3173
    egb = tree->score_eg;
3223
    egb = tree->score_eg;
3174
    EvaluateDevelopment(tree, 1, black);
3224
    EvaluateCastling(tree, 1, black);
3175
    mgb = tree->score_mg - mgb;
3225
    mgb = tree->score_mg - mgb;
3176
    egb = tree->score_eg - egb;
3226
    egb = tree->score_eg - egb;
3177
    mgw = tree->score_mg;
3227
    mgw = tree->score_mg;
3178
    egw = tree->score_eg;
3228
    egw = tree->score_eg;
3179
    EvaluateDevelopment(tree, 1, white);
3229
    EvaluateCastling(tree, 1, white);
3180
    mgw = tree->score_mg - mgw;
3230
    mgw = tree->score_mg - mgw;
3181
    egw = tree->score_eg - egw;
3231
    egw = tree->score_eg - egw;
3182
    tb = (mgb * phase + egb * (62 - phase)) / 62;
3232
    tb = (mgb * phase + egb * (62 - phase)) / 62;
3183
    tw = (mgw * phase + egw * (62 - phase)) / 62;
3233
    tw = (mgw * phase + egw * (62 - phase)) / 62;
3184
    Print(128, "development....%s  |", DisplayEvaluation(tb + tw, 1));
3234
    Print(32, "castling.......%s  |", DisplayEvaluation(tb + tw, 1));
3185
    Print(128, " %s", DisplayEvaluation(tw, 1));
3235
    Print(32, " %s", DisplayEvaluation(tw, 1));
3186
    Print(128, " %s", DisplayEvaluation(mgw, 1));
3236
    Print(32, " %s", DisplayEvaluation(mgw, 1));
3187
    Print(128, " %s  |", DisplayEvaluation(egw, 1));
3237
    Print(32, " %s  |", DisplayEvaluation(egw, 1));
3188
    Print(128, " %s", DisplayEvaluation(tb, 1));
3238
    Print(32, " %s", DisplayEvaluation(tb, 1));
3189
    Print(128, " %s", DisplayEvaluation(mgb, 1));
3239
    Print(32, " %s", DisplayEvaluation(mgb, 1));
3190
    Print(128, " %s  |\n", DisplayEvaluation(egb, 1));
3240
    Print(32, " %s  |\n", DisplayEvaluation(egb, 1));
3191
    egb = tree->score_eg;
3241
    egb = tree->score_eg;
3192
    if ((TotalPieces(white, occupied) == 0 && tree->pawn_score.passed[black])
3242
    if ((TotalPieces(white, occupied) == 0 && tree->pawn_score.passed[black])
3193
        || (TotalPieces(black, occupied) == 0 &&
3243
        || (TotalPieces(black, occupied) == 0 &&
3194
            tree->pawn_score.passed[white]))
3244
            tree->pawn_score.passed[white]))
3195
      EvaluatePassedPawnRaces(tree, game_wtm);
3245
      EvaluatePassedPawnRaces(tree, game_wtm);
3196
    egb = tree->score_eg - egb;
3246
    egb = tree->score_eg - egb;
3197
    Print(128, "pawn races.....%s", DisplayEvaluation(egb, 1));
3247
    Print(32, "pawn races.....%s", DisplayEvaluation(egb, 1));
3198
    Print(128, "  +--------------------------+--------------------------+\n");
3248
    Print(32, "  +--------------------------+--------------------------+\n");
3199
    Print(128, "total..........%s\n", DisplayEvaluation(s, 1));
3249
    Print(32, "total..........%s\n", DisplayEvaluation(s, 1));
-
 
3250
  }
-
 
3251
/*
-
 
3252
 ************************************************************
-
 
3253
 *                                                          *
-
 
3254
 *  "screen" command runs runs through a test suite of      *
-
 
3255
 *  positions and culls any where a search returns a value  *
-
 
3256
 *  outside the margin given to the screen command.         *
-
 
3257
 *                                                          *
-
 
3258
 ************************************************************
-
 
3259
 */
-
 
3260
  else if (OptionMatch("screen", *args)) {
-
 
3261
    int margin = 9999999, save_noise, save_display;
-
 
3262
 
-
 
3263
    nargs = ReadParse(buffer, args, " \t;=");
-
 
3264
    if (thinking || pondering)
-
 
3265
      return 2;
-
 
3266
    if (nargs < 3) {
-
 
3267
      printf("usage:  screen <filename> score-margin\n");
-
 
3268
      return 1;
-
 
3269
    }
-
 
3270
    save_noise = noise_level;
-
 
3271
    save_display = display_options;
-
 
3272
    early_exit = 99;
-
 
3273
    margin = atoi(args[2]);
-
 
3274
    noise_level = 99999999;
-
 
3275
    display_options = 2048;
-
 
3276
    Test(args[1], 0, 1, margin);
-
 
3277
    noise_level = save_noise;
-
 
3278
    display_options = save_display;
-
 
3279
    ponder_move = 0;
-
 
3280
    last_pv.pathd = 0;
-
 
3281
    last_pv.pathl = 0;
3200
  }
3282
  }
3201
/*
3283
/*
3202
 ************************************************************
3284
 ************************************************************
3203
 *                                                          *
3285
 *                                                          *
3204
 *  "sd" command sets a specific search depth to control    *
3286
 *  "sd" command sets a specific search depth to control    *
Line 3210... Line 3292...
3210
    if (nargs < 2) {
3292
    if (nargs < 2) {
3211
      printf("usage:  sd <depth>\n");
3293
      printf("usage:  sd <depth>\n");
3212
      return 1;
3294
      return 1;
3213
    }
3295
    }
3214
    search_depth = atoi(args[1]);
3296
    search_depth = atoi(args[1]);
3215
    Print(128, "search depth set to %d.\n", search_depth);
3297
    Print(32, "search depth set to %d.\n", search_depth);
-
 
3298
  }
-
 
3299
/*
-
 
3300
 ************************************************************
-
 
3301
 *                                                          *
-
 
3302
 *  "search" command sets a specific move for the search    *
-
 
3303
 *  to analyze, ignoring all others completely.             *
-
 
3304
 *                                                          *
-
 
3305
 ************************************************************
-
 
3306
 */
-
 
3307
  else if (OptionMatch("search", *args)) {
-
 
3308
    if (thinking || pondering)
-
 
3309
      return 2;
-
 
3310
    if (nargs < 2) {
-
 
3311
      printf("usage:  search <move>\n");
-
 
3312
      return 1;
-
 
3313
    }
-
 
3314
    search_move = InputMove(tree, 0, game_wtm, 0, 0, args[1]);
-
 
3315
    if (!search_move)
-
 
3316
      search_move = InputMove(tree, 0, Flip(game_wtm), 0, 0, args[1]);
-
 
3317
    if (!search_move)
-
 
3318
      printf("illegal move.\n");
-
 
3319
  }
-
 
3320
/*
-
 
3321
 ************************************************************
-
 
3322
 *                                                          *
-
 
3323
 *  "setboard" command sets the board to a specific         *
-
 
3324
 *  position for analysis by the program.                   *
-
 
3325
 *                                                          *
-
 
3326
 ************************************************************
-
 
3327
 */
-
 
3328
  else if (OptionMatch("setboard", *args)) {
-
 
3329
    if (thinking || pondering)
-
 
3330
      return 2;
-
 
3331
    nargs = ReadParse(buffer, args, " \t;=");
-
 
3332
    if (nargs < 3) {
-
 
3333
      printf("usage:  setboard <fen>\n");
-
 
3334
      return 1;
-
 
3335
    }
-
 
3336
    SetBoard(tree, nargs - 1, args + 1, 0);
-
 
3337
    move_number = 1;
-
 
3338
    if (!game_wtm) {
-
 
3339
      game_wtm = 1;
-
 
3340
      Pass();
-
 
3341
    }
-
 
3342
    ponder_move = 0;
-
 
3343
    last_pv.pathd = 0;
-
 
3344
    last_pv.pathl = 0;
-
 
3345
    over = 0;
-
 
3346
    strcpy(buffer, "savepos *");
-
 
3347
    Option(tree);
-
 
3348
  } else if (StrCnt(*args, '/') > 3) {
-
 
3349
    if (thinking || pondering)
-
 
3350
      return 2;
-
 
3351
    nargs = ReadParse(buffer, args, " \t;=");
-
 
3352
    SetBoard(tree, nargs, args, 0);
-
 
3353
    move_number = 1;
-
 
3354
    if (!game_wtm) {
-
 
3355
      game_wtm = 1;
-
 
3356
      Pass();
-
 
3357
    }
-
 
3358
    ponder_move = 0;
-
 
3359
    last_pv.pathd = 0;
-
 
3360
    last_pv.pathl = 0;
-
 
3361
    over = 0;
-
 
3362
    strcpy(buffer, "savepos *");
-
 
3363
    Option(tree);
-
 
3364
  }
-
 
3365
/*
-
 
3366
 ************************************************************
-
 
3367
 *                                                          *
-
 
3368
 *  "settc" command is used to reset the time controls      *
-
 
3369
 *  after a complete restart.                               *
-
 
3370
 *                                                          *
-
 
3371
 ************************************************************
-
 
3372
 */
-
 
3373
  else if (OptionMatch("settc", *args)) {
-
 
3374
    if (thinking || pondering)
-
 
3375
      return 2;
-
 
3376
    if (nargs < 4) {
-
 
3377
      printf("usage:  settc <wmoves> <wtime> <bmoves> <btime>\n");
-
 
3378
      return 1;
-
 
3379
    }
-
 
3380
    tc_moves_remaining[white] = atoi(args[1]);
-
 
3381
    tc_time_remaining[white] = ParseTime(args[2]) * 6000;
-
 
3382
    tc_moves_remaining[black] = atoi(args[3]);
-
 
3383
    tc_time_remaining[black] = ParseTime(args[4]) * 6000;
-
 
3384
    Print(32, "time remaining: %s (white).\n",
-
 
3385
        DisplayTime(tc_time_remaining[white]));
-
 
3386
    Print(32, "time remaining: %s (black).\n",
-
 
3387
        DisplayTime(tc_time_remaining[black]));
-
 
3388
    if (tc_sudden_death != 1) {
-
 
3389
      Print(32, "%d moves to next time control (white)\n",
-
 
3390
          tc_moves_remaining[white]);
-
 
3391
      Print(32, "%d moves to next time control (black)\n",
-
 
3392
          tc_moves_remaining[black]);
-
 
3393
    } else
-
 
3394
      Print(32, "Sudden-death time control in effect\n");
-
 
3395
    TimeSet(999);
3216
  }
3396
  }
3217
/*
3397
/*
3218
 ************************************************************
3398
 ************************************************************
3219
 *                                                          *
3399
 *                                                          *
3220
 *  "show" command enables/disables whether or not we want  *
3400
 *  "show" command enables/disables whether or not we want  *
Line 3228... Line 3408...
3228
      return 1;
3408
      return 1;
3229
    }
3409
    }
3230
    if (OptionMatch("book", args[1])) {
3410
    if (OptionMatch("book", args[1])) {
3231
      show_book = !show_book;
3411
      show_book = !show_book;
3232
      if (show_book)
3412
      if (show_book)
3233
        Print(128, "show book statistics\n");
3413
        Print(32, "show book statistics\n");
3234
      else
3414
      else
3235
        Print(128, "don't show book statistics\n");
3415
        Print(32, "don't show book statistics\n");
3236
    }
3416
    }
3237
  }
3417
  }
3238
/*
3418
/*
3239
 ************************************************************
3419
 ************************************************************
3240
 *                                                          *
3420
 *                                                          *
Line 3249... Line 3429...
3249
  else if (OptionMatch("skill", *args)) {
3429
  else if (OptionMatch("skill", *args)) {
3250
    if (nargs < 2) {
3430
    if (nargs < 2) {
3251
      printf("usage:  skill <1-100>\n");
3431
      printf("usage:  skill <1-100>\n");
3252
      return 1;
3432
      return 1;
3253
    }
3433
    }
3254
    if (skill != 100) {
3434
    if (skill != 100)
3255
      printf("ERROR:  skill can only be changed one time in a game\n");
3435
      printf("ERROR:  skill can only be changed one time in a game\n");
3256
    } else {
3436
    else {
3257
      skill = atoi(args[1]);
3437
      skill = atoi(args[1]);
3258
      if (skill < 1 || skill > 100) {
3438
      if (skill < 1 || skill > 100) {
3259
        printf("ERROR: skill range is 1-100 only\n");
3439
        printf("ERROR: skill range is 1-100 only\n");
3260
        skill = 100;
3440
        skill = 100;
3261
      }
3441
      }
3262
      Print(128, "skill level set to %d%%\n", skill);
3442
      Print(32, "skill level set to %d%%\n", skill);
3263
      null_depth = null_depth * skill / 100;
3443
      null_depth = (null_depth * skill + 50) / 100;
-
 
3444
      if (skill < 100)
-
 
3445
        null_divisor = null_divisor + 2 * (100 - skill) / 10;
3264
      check_depth = check_depth * skill / 100;
3446
      check_depth = (check_depth * skill + 50) / 100;
3265
      LMR_min_reduction = LMR_min_reduction * skill / 100;
3447
      LMR_min = (LMR_min * skill + 50) / 100;
3266
      LMR_max_reduction = LMR_max_reduction * skill / 100;
3448
      LMR_max = (LMR_max * skill + 50) / 100;
-
 
3449
      InitializeReductions();
3267
    }
3450
    }
3268
  }
3451
  }
3269
#endif
3452
#endif
3270
/*
3453
/*
3271
 ************************************************************
3454
 ************************************************************
3272
 *                                                          *
3455
 *                                                          *
3273
 *   "smp" command is used to tune the various SMP search   *
3456
 *   "smp" command is used to tune the various SMP search   *
3274
 *   parameters.                                            *
3457
 *   parameters.                                            *
-
 
3458
 *                                                          *
-
 
3459
 *   "smpaffinity" command is used to enable (>= 0) and to  *
-
 
3460
 *   disable smp processor affinity (off).  If you try to   *
-
 
3461
 *   run two instances of Crafty on the same machine, ONE   *
-
 
3462
 *   them (if not both) need to have processor affinity     *
-
 
3463
 *   disabled or else you can use the smpaffinity=<n> to    *
-
 
3464
 *   prevent processor conflicts.  If you use a 32 core     *
-
 
3465
 *   machine, and you want to run two instances of Crafty,  *
-
 
3466
 *   use smpaffinity=0 on one, and smpaffinity=16 on the    *
-
 
3467
 *   other.  The first will bind to processors 0-15, and    *
-
 
3468
 *   the second will bind to processors 16-31.              *
3275
 *                                                          *
3469
 *                                                          *
3276
 *   "smpgroup" command is used to control how many threads *
3470
 *   "smpgroup" command is used to control how many threads *
3277
 *   may work together at any point in the tree.  The       *
3471
 *   may work together at any point in the tree.  The       *
3278
 *   usual default is 6, but this might be reduced on a     *
3472
 *   usual default is 6, but this might be reduced on a     *
3279
 *   machine with a large number of processors.  It should  *
3473
 *   machine with a large number of processors.  It should  *
Line 3288... Line 3482...
3288
 *   larger than the compiled-in -DCPUS=n value.            *
3482
 *   larger than the compiled-in -DCPUS=n value.            *
3289
 *                                                          *
3483
 *                                                          *
3290
 *   "smpnice" command turns on "nice" mode where idle      *
3484
 *   "smpnice" command turns on "nice" mode where idle      *
3291
 *   processors are terminated between searches to avoid    *
3485
 *   processors are terminated between searches to avoid    *
3292
 *   burning CPU time in the idle loop.                     *
3486
 *   burning CPU time in the idle loop.                     *
-
 
3487
 *                                                          *
-
 
3488
 *   "smpnuma" command enables NUMA mode which distributes  *
-
 
3489
 *   hash tables across all NUMA nodes evenly.  If your     *
-
 
3490
 *   machine is not NUMA, or only has one socket (node) you *
-
 
3491
 *   should set this to zero as it will be slightly more    *
-
 
3492
 *   efficient when you change hash sizes.                  *
3293
 *                                                          *
3493
 *                                                          *
3294
 *   "smproot" command is used to enable (1) or disable (0) *
3494
 *   "smproot" command is used to enable (1) or disable (0) *
3295
 *   splitting the tree at the root (ply=1).  Splitting at  *
3495
 *   splitting the tree at the root (ply=1).  Splitting at  *
3296
 *   the root is more efficient, but might slow finding the *
3496
 *   the root is more efficient, but might slow finding the *
3297
 *   move in some test positions.                           *
3497
 *   move in some test positions.                           *
3298
 *                                                          *
3498
 *                                                          *
-
 
3499
 *   "smpgsd" sets the minimum depth remaining at which a   *
-
 
3500
 *   gratuitous split can be done.                          *
-
 
3501
 *                                                          *
3299
 *   "smpsn" sets the minimum number of nodes that must be  *
3502
 *   "smpgsl" sets the maximum number of gratuitous splits  *
3300
 *   searched at any node before we can do a parallel split *
3503
 *   per thread.  This only counts splits that have not yet *
3301
 *   to search the remaining moves there in parallel.       *
3504
 *   been joined.                                           *
3302
 *                                                          *
3505
 *                                                          *
3303
 ************************************************************
3506
 ************************************************************
3304
 */
3507
 */
-
 
3508
  else if (OptionMatch("smpaffinity", *args)) {
-
 
3509
    if (nargs < 2) {
-
 
3510
      printf("usage:  smpaffinity <0/1>\n");
-
 
3511
      return 1;
-
 
3512
    }
-
 
3513
    if (!strcmp(args[1], "off"))
-
 
3514
      smp_affinity = -1;
-
 
3515
    else
-
 
3516
      smp_affinity = atoi(args[1]);
-
 
3517
    if (smp_affinity >= 0)
-
 
3518
      Print(32, "smp processor affinity enabled.\n");
-
 
3519
    else
-
 
3520
      Print(32, "smp processor affinity disabled.\n");
3305
  else if (OptionMatch("smpmin", *args)) {
3521
  } else if (OptionMatch("smpmin", *args)) {
3306
    if (nargs < 2) {
3522
    if (nargs < 2) {
3307
      printf("usage:  smpmin <depth>\n");
3523
      printf("usage:  smpmin <depth>\n");
3308
      return 1;
3524
      return 1;
3309
    }
3525
    }
3310
    smp_min_split_depth = atoi(args[1]);
3526
    smp_min_split_depth = atoi(args[1]);
3311
    Print(128, "minimum thread depth set to %d.\n", smp_min_split_depth);
3527
    Print(32, "minimum thread depth set to %d.\n", smp_min_split_depth);
3312
  } else if (OptionMatch("smpgroup", *args)) {
3528
  } else if (OptionMatch("smpgroup", *args)) {
3313
    if (nargs < 2) {
3529
    if (nargs < 2) {
3314
      printf("usage:  smpgroup <threads>\n");
3530
      printf("usage:  smpgroup <threads>\n");
3315
      return 1;
3531
      return 1;
3316
    }
3532
    }
3317
    smp_split_group = atoi(args[1]);
3533
    smp_split_group = atoi(args[1]);
3318
    Print(128, "maximum thread group size set to %d.\n", smp_split_group);
3534
    Print(32, "maximum thread group size set to %d.\n", smp_split_group);
3319
  } else if (OptionMatch("smpmt", *args) || OptionMatch("mt", *args)
3535
  } else if (OptionMatch("smpmt", *args) || OptionMatch("mt", *args)
3320
      || OptionMatch("cores", *args)) {
3536
      || OptionMatch("cores", *args)) {
3321
    int proc;
3537
    int proc;
3322
 
3538
 
3323
    if (nargs < 2) {
3539
    if (nargs < 2) {
Line 3325... Line 3541...
3325
      return 1;
3541
      return 1;
3326
    }
3542
    }
3327
    if (thinking || pondering)
3543
    if (thinking || pondering)
3328
      return 3;
3544
      return 3;
3329
    allow_cores = 0;
3545
    allow_cores = 0;
-
 
3546
    if (xboard)
3330
    Print(4095, "Warning--  xboard 'cores' option disabled\n");
3547
      Print(4095, "Warning--  xboard 'cores' option disabled\n");
3331
    smp_max_threads = atoi(args[1]);
3548
    smp_max_threads = atoi(args[1]);
3332
    if (smp_max_threads > CPUS) {
3549
    if (smp_max_threads > CPUS) {
3333
      Print(4095, "ERROR - Crafty was compiled with CPUS=%d.", CPUS);
3550
      Print(4095, "ERROR - Crafty was compiled with CPUS=%d.", CPUS);
3334
      Print(4095, "  mt can not exceed this value.\n");
3551
      Print(4095, "  mt can not exceed this value.\n");
3335
      smp_max_threads = CPUS;
3552
      smp_max_threads = CPUS;
-
 
3553
    }
-
 
3554
    if (smp_max_threads == 1) {
-
 
3555
      Print(4095, "ERROR - max threads can be set to zero (0) to");
-
 
3556
      Print(4095, " disable parallel search, otherwise it must be > 1.\n");
-
 
3557
      smp_max_threads = 0;
3336
    }
3558
    }
3337
    if (smp_max_threads)
3559
    if (smp_max_threads)
3338
      Print(128, "max threads set to %d.\n", smp_max_threads);
3560
      Print(32, "max threads set to %d.\n", smp_max_threads);
3339
    else
3561
    else
3340
      Print(128, "parallel threads disabled.\n");
3562
      Print(32, "parallel threads disabled.\n");
3341
    for (proc = 1; proc < CPUS; proc++)
3563
    for (proc = 1; proc < CPUS; proc++)
3342
      if (proc >= smp_max_threads)
3564
      if (proc >= (int) smp_max_threads) // Pierre-Marie Baty -- added type cast
3343
        thread[proc].tree = (TREE *) - 1;
3565
        thread[proc].terminate = 1;
3344
  } else if (OptionMatch("smpnice", *args)) {
3566
  } else if (OptionMatch("smpnice", *args)) {
3345
    if (nargs < 2) {
3567
    if (nargs < 2) {
3346
      printf("usage:  smpnice 0|1\n");
3568
      printf("usage:  smpnice 0|1\n");
3347
      return 1;
3569
      return 1;
3348
    }
3570
    }
3349
    smp_nice = atoi(args[1]);
3571
    smp_nice = atoi(args[1]);
3350
    if (smp_nice)
3572
    if (smp_nice)
3351
      Print(128, "SMP terminate extra threads when idle.\n");
3573
      Print(32, "SMP terminate extra threads when idle.\n");
3352
    else
3574
    else
3353
      Print(128, "SMP keep extra threads spinning when idle.\n");
3575
      Print(32, "SMP keep extra threads spinning when idle.\n");
-
 
3576
  } else if (OptionMatch("smpnuma", *args)) {
-
 
3577
    if (nargs < 2) {
-
 
3578
      printf("usage:  smpnuma 0|1\n");
-
 
3579
      return 1;
-
 
3580
    }
-
 
3581
    smp_numa = atoi(args[1]);
-
 
3582
    if (smp_numa)
-
 
3583
      Print(32, "SMP NUMA mode enabled.\n");
-
 
3584
    else
-
 
3585
      Print(32, "SMP NUMA mode disabled.\n");
3354
  } else if (OptionMatch("smproot", *args)) {
3586
  } else if (OptionMatch("smproot", *args)) {
3355
    if (nargs < 2) {
3587
    if (nargs < 2) {
3356
      printf("usage:  smproot 0|1\n");
3588
      printf("usage:  smproot 0|1\n");
3357
      return 1;
3589
      return 1;
3358
    }
3590
    }
3359
    smp_split_at_root = atoi(args[1]);
3591
    smp_split_at_root = atoi(args[1]);
3360
    if (smp_split_at_root)
3592
    if (smp_split_at_root)
3361
      Print(128, "SMP search split at ply >= 1.\n");
3593
      Print(32, "SMP search split at ply >= 1.\n");
3362
    else
3594
    else
3363
      Print(128, "SMP search split at ply > 1.\n");
3595
      Print(32, "SMP search split at ply > 1.\n");
-
 
3596
  } else if (OptionMatch("smpgsl", *args)) {
-
 
3597
    if (nargs < 2) {
-
 
3598
      printf("usage:  smpgsl <n>\n");
-
 
3599
      return 1;
-
 
3600
    }
-
 
3601
    smp_gratuitous_limit = atoi(args[1]);
-
 
3602
    Print(32, "maximum gratuitous splits allowed %d.\n",
-
 
3603
        smp_gratuitous_limit);
3364
  } else if (OptionMatch("smpsn", *args)) {
3604
  } else if (OptionMatch("smpgsd", *args)) {
3365
    if (nargs < 2) {
3605
    if (nargs < 2) {
3366
      printf("usage:  smpsn <nodes>\n");
3606
      printf("usage:  smpgsd <nodes>\n");
3367
      return 1;
3607
      return 1;
3368
    }
3608
    }
3369
    smp_split_nodes = atoi(args[1]);
3609
    smp_gratuitous_depth = atoi(args[1]);
3370
    Print(128, "minimum nodes before a split %d.\n", smp_split_nodes);
3610
    Print(32, "gratuitous split min depth %d.\n", smp_gratuitous_depth);
3371
  }
3611
  }
3372
/*
3612
/*
3373
 ************************************************************
3613
 ************************************************************
3374
 *                                                          *
3614
 *                                                          *
3375
 *  "sn" command sets a specific number of nodes to search  *
3615
 *  "sn" command sets a specific number of nodes to search  *
Line 3382... Line 3622...
3382
    if (nargs < 2) {
3622
    if (nargs < 2) {
3383
      printf("usage:  sn <nodes>\n");
3623
      printf("usage:  sn <nodes>\n");
3384
      return 1;
3624
      return 1;
3385
    }
3625
    }
3386
    search_nodes = atoi(args[1]);
3626
    search_nodes = atoi(args[1]);
3387
    Print(128, "search nodes set to %" PRIu64 ".\n", search_nodes);
3627
    Print(32, "search nodes set to %" PRIu64 ".\n", search_nodes);
3388
    ponder = 0;
3628
    ponder = 0;
3389
  }
3629
  }
3390
/*
3630
/*
3391
 ************************************************************
3631
 ************************************************************
3392
 *                                                          *
3632
 *                                                          *
Line 3414... Line 3654...
3414
 *  "st" command sets a specific search time to control the *
3654
 *  "st" command sets a specific search time to control the *
3415
 *  tree search time.                                       *
3655
 *  tree search time.                                       *
3416
 *                                                          *
3656
 *                                                          *
3417
 ************************************************************
3657
 ************************************************************
3418
 */
3658
 */
3419
  else if (!strcmp("st", *args)) {
3659
  else if (OptionMatch("st", *args)) {
3420
    if (nargs < 2) {
3660
    if (nargs < 2) {
3421
      printf("usage:  st <time>\n");
3661
      printf("usage:  st <time>\n");
3422
      return 1;
3662
      return 1;
3423
    }
3663
    }
3424
    search_time_limit = (int) (atof(args[1]) * 100); // Pierre-Marie Baty -- added type cast
3664
    search_time_limit = (int) (atof(args[1]) * 100); // Pierre-Marie Baty -- added type cast
3425
    Print(128, "search time set to %.2f.\n",
3665
    Print(32, "search time set to %.2f.\n",
3426
        (float) search_time_limit / 100.0);
3666
        (float) search_time_limit / 100.0);
3427
  }
-
 
3428
/*
-
 
3429
 ************************************************************
-
 
3430
 *                                                          *
-
 
3431
 *  "surplus" command sets a specific time surplus target   *
-
 
3432
 *  for normal tournament games.                            *
-
 
3433
 *                                                          *
-
 
3434
 ************************************************************
-
 
3435
 */
-
 
3436
  else if (OptionMatch("surplus", *args)) {
-
 
3437
    if (nargs == 2)
-
 
3438
      tc_safety_margin = atoi(args[1]) * 6000;
-
 
3439
    Print(128, "time surplus set to %s.\n", DisplayTime(tc_safety_margin));
-
 
3440
  }
3667
  }
3441
/*
3668
/*
3442
 ************************************************************
3669
 ************************************************************
3443
 *                                                          *
3670
 *                                                          *
3444
 *  "swindle" command turns swindle mode off/on.            *
3671
 *  "swindle" command turns swindle mode off/on.            *
Line 3484... Line 3711...
3484
 *  displays results.                                       *
3711
 *  displays results.                                       *
3485
 *                                                          *
3712
 *                                                          *
3486
 ************************************************************
3713
 ************************************************************
3487
 */
3714
 */
3488
  else if (OptionMatch("test", *args)) {
3715
  else if (OptionMatch("test", *args)) {
-
 
3716
    FILE *unsolved = NULL;
3489
    nargs = ReadParse(buffer, args, "\t ;=");
3717
    int save_noise, save_display;
-
 
3718
 
3490
    if (thinking || pondering)
3719
    if (thinking || pondering)
3491
      return 2;
3720
      return 2;
-
 
3721
    nargs = ReadParse(buffer, args, " \t;=");
3492
    if (nargs < 2) {
3722
    if (nargs < 2) {
3493
      printf("usage:  test <filename> [exitcnt]\n");
3723
      printf("usage:  test <filename> [exitcnt]\n");
3494
      return 1;
3724
      return 1;
3495
    }
3725
    }
-
 
3726
    save_noise = noise_level;
-
 
3727
    save_display = display_options;
3496
    if (nargs > 2)
3728
    if (nargs > 2)
3497
      early_exit = atoi(args[2]);
3729
      early_exit = atoi(args[2]);
3498
    Test(args[1]);
3730
    if (nargs > 3)
-
 
3731
      unsolved = fopen(args[3], "w+");
-
 
3732
    Test(args[1], unsolved, 0, 0);
-
 
3733
    noise_level = save_noise;
-
 
3734
    display_options = save_display;
3499
    ponder_move = 0;
3735
    ponder_move = 0;
3500
    last_pv.pathd = 0;
3736
    last_pv.pathd = 0;
3501
    last_pv.pathl = 0;
3737
    last_pv.pathl = 0;
-
 
3738
    if (unsolved)
-
 
3739
      fclose(unsolved);
3502
  }
3740
  }
3503
/*
3741
/*
3504
 ************************************************************
3742
 ************************************************************
3505
 *                                                          *
3743
 *                                                          *
3506
 *  "time" is used to set the basic search timing controls. *
3744
 *  "time" is used to set the basic search timing controls. *
Line 3531... Line 3769...
3531
 *                                                          *
3769
 *                                                          *
3532
 ************************************************************
3770
 ************************************************************
3533
 */
3771
 */
3534
  else if (OptionMatch("time", *args)) {
3772
  else if (OptionMatch("time", *args)) {
3535
    if (xboard) {
3773
    if (xboard) {
3536
      tc_time_remaining[root_wtm] = atoi(args[1]);
3774
      tc_time_remaining[Flip(game_wtm)] = atoi(args[1]);
3537
      if (log_file && time_limit > 99)
3775
      if (log_file && time_limit > 99)
3538
        fprintf(log_file, "time remaining: %s (Crafty).\n",
3776
        fprintf(log_file, "time remaining: %s (Crafty).\n",
3539
            DisplayTime(tc_time_remaining[root_wtm]));
3777
            DisplayTime(tc_time_remaining[Flip(game_wtm)]));
3540
    } else {
3778
    } else {
3541
      if (thinking || pondering)
3779
      if (thinking || pondering)
3542
        return 2;
3780
        return 2;
3543
      tc_moves = 60;
3781
      tc_moves = 60;
3544
      tc_time = 180000;
3782
      tc_time = 180000;
Line 3580... Line 3818...
3580
      tc_time_remaining[white] = tc_time;
3818
      tc_time_remaining[white] = tc_time;
3581
      tc_time_remaining[black] = tc_time;
3819
      tc_time_remaining[black] = tc_time;
3582
      tc_moves_remaining[white] = tc_moves;
3820
      tc_moves_remaining[white] = tc_moves;
3583
      tc_moves_remaining[black] = tc_moves;
3821
      tc_moves_remaining[black] = tc_moves;
3584
      if (!tc_sudden_death) {
3822
      if (!tc_sudden_death) {
3585
        Print(128, "%d moves/%d minutes primary time control\n", tc_moves,
3823
        Print(32, "%d moves/%d minutes primary time control\n", tc_moves,
3586
            tc_time / 100);
3824
            tc_time / 100);
3587
        Print(128, "%d moves/%d minutes secondary time control\n",
3825
        Print(32, "%d moves/%d minutes secondary time control\n",
3588
            tc_secondary_moves, tc_secondary_time / 100);
3826
            tc_secondary_moves, tc_secondary_time / 100);
3589
        if (tc_increment)
3827
        if (tc_increment)
3590
          Print(128, "increment %d seconds.\n", tc_increment / 100);
3828
          Print(32, "increment %d seconds.\n", tc_increment / 100);
3591
      } else if (tc_sudden_death == 1) {
3829
      } else if (tc_sudden_death == 1) {
3592
        Print(128, " game/%d minutes primary time control\n", tc_time / 100);
3830
        Print(32, " game/%d minutes primary time control\n", tc_time / 100);
3593
        if (tc_increment)
3831
        if (tc_increment)
3594
          Print(128, "increment %d seconds.\n", tc_increment / 100);
3832
          Print(32, "increment %d seconds.\n", tc_increment / 100);
3595
      } else if (tc_sudden_death == 2) {
3833
      } else if (tc_sudden_death == 2) {
3596
        Print(128, "%d moves/%d minutes primary time control\n", tc_moves,
3834
        Print(32, "%d moves/%d minutes primary time control\n", tc_moves,
3597
            tc_time / 100);
3835
            tc_time / 100);
3598
        Print(128, "game/%d minutes secondary time control\n",
3836
        Print(32, "game/%d minutes secondary time control\n",
3599
            tc_secondary_time / 100);
3837
            tc_secondary_time / 100);
3600
        if (tc_increment)
3838
        if (tc_increment)
3601
          Print(128, "increment %d seconds.\n", tc_increment / 100);
3839
          Print(32, "increment %d seconds.\n", tc_increment / 100);
3602
      }
3840
      }
3603
      tc_time *= 60;
3841
      tc_time *= 60;
3604
      tc_time_remaining[white] *= 60;
3842
      tc_time_remaining[white] *= 60;
3605
      tc_time_remaining[black] *= 60;
3843
      tc_time_remaining[black] *= 60;
3606
      tc_secondary_time *= 60;
3844
      tc_secondary_time *= 60;
Line 3667... Line 3905...
3667
 *  "undo" command backs up 1/2 move, which leaves the      *
3905
 *  "undo" command backs up 1/2 move, which leaves the      *
3668
 *  opposite side on move. [xboard compatibility]           *
3906
 *  opposite side on move. [xboard compatibility]           *
3669
 *                                                          *
3907
 *                                                          *
3670
 ************************************************************
3908
 ************************************************************
3671
 */
3909
 */
3672
  else if (!strcmp("undo", *args)) {
3910
  else if (OptionMatch("undo", *args)) {
3673
    if (thinking || pondering)
3911
    if (thinking || pondering)
3674
      return 2;
3912
      return 2;
3675
    if (!game_wtm || move_number != 1) {
3913
    if (!game_wtm || move_number != 1) {
3676
      game_wtm = Flip(game_wtm);
3914
      game_wtm = Flip(game_wtm);
3677
      if (Flip(game_wtm))
3915
      if (Flip(game_wtm))
3678
        move_number--;
3916
        move_number--;
3679
      sprintf_s(buffer, sizeof (buffer), "reset %d", move_number); // Pierre-Marie Baty -- use safe version
3917
      sprintf(buffer, "reset %d", move_number);
3680
      (void) Option(tree);
3918
      Option(tree);
3681
    }
3919
    }
3682
  }
3920
  }
3683
/*
3921
/*
3684
 *****************************************************************
3922
 ************************************************************
3685
 *                                                               *
3923
 *                                                          *
3686
 *  "usage" command controls the time usage multiplier factors   *
3924
 *  "usage" command controls the time usage multiplier      *
3687
 *  used in the game  - percentage increase or decrease in time  *
3925
 *  factors used in the game  - percentage increase or      *
3688
 *  used up front.  Enter a number between 1 to 100 for the %    *
3926
 *  decrease in time used up front.  Enter a number between *
-
 
3927
 *  1 to 100 for the % decrease (negative value) or to      *
3689
 *  decrease (negative value) or to increase (positive value)    *
3928
 *  increase (positive value) although other time           *
3690
 *  although other time limitation controls may kick in.  This   *
3929
 *  limitation controls may kick in.  This more commonly    *
3691
 *  more commonly used in the .craftyrc/crafty.rc file.          *
3930
 *  used in the .craftyrc/crafty.rc file.                   *
3692
 *                                                               *
3931
 *                                                          *
3693
 *****************************************************************
3932
 ************************************************************
3694
 */
3933
 */
3695
  else if (OptionMatch("usage", *args)) {
3934
  else if (OptionMatch("usage", *args)) {
3696
    if (nargs < 2) {
3935
    if (nargs < 2) {
3697
      printf("usage:  usage <percentage>\n");
3936
      printf("usage:  usage <percentage>\n");
3698
      return 1;
3937
      return 1;
Line 3700... Line 3939...
3700
    usage_level = atoi(args[1]);
3939
    usage_level = atoi(args[1]);
3701
    if (usage_level > 50)
3940
    if (usage_level > 50)
3702
      usage_level = 50;
3941
      usage_level = 50;
3703
    else if (usage_level < -50)
3942
    else if (usage_level < -50)
3704
      usage_level = -50;
3943
      usage_level = -50;
3705
    Print(128,
-
 
3706
        "time usage up front set to %d percent increase/(-)decrease.\n",
3944
    Print(32, "time usage up front set to %d percent increase/(-)decrease.\n",
3707
        usage_level);
3945
        usage_level);
3708
  }
3946
  }
3709
/*
3947
/*
3710
 ************************************************************
3948
 ************************************************************
3711
 *                                                          *
3949
 *                                                          *
Line 3735... Line 3973...
3735
  else if (OptionMatch("whisper", *args)) {
3973
  else if (OptionMatch("whisper", *args)) {
3736
    if (nargs < 2) {
3974
    if (nargs < 2) {
3737
      printf("usage:  whisper <level>\n");
3975
      printf("usage:  whisper <level>\n");
3738
      return 1;
3976
      return 1;
3739
    }
3977
    }
3740
    kibitz = 16 + atoi(args[1]);
3978
    kibitz = 16 + Min(0, atoi(args[1]));
-
 
3979
  }
-
 
3980
/*
-
 
3981
 ************************************************************
-
 
3982
 *                                                          *
-
 
3983
 *  "white" command sets white to move (wtm).               *
-
 
3984
 *                                                          *
-
 
3985
 ************************************************************
-
 
3986
 */
-
 
3987
  else if (OptionMatch("white", *args)) {
-
 
3988
    if (thinking || pondering)
-
 
3989
      return 2;
-
 
3990
    ponder_move = 0;
-
 
3991
    last_pv.pathd = 0;
-
 
3992
    last_pv.pathl = 0;
-
 
3993
    if (!game_wtm)
-
 
3994
      Pass();
-
 
3995
    force = 0;
3741
  }
3996
  }
3742
/*
3997
/*
3743
 ************************************************************
3998
 ************************************************************
3744
 *                                                          *
3999
 *                                                          *
3745
 *  "wild" command sets up an ICS wild position (only 7 at  *
4000
 *  "wild" command sets up an ICS wild position (only 7 at  *
Line 3757... Line 4012...
3757
      return 1;
4012
      return 1;
3758
    }
4013
    }
3759
    i = atoi(args[1]);
4014
    i = atoi(args[1]);
3760
    switch (i) {
4015
    switch (i) {
3761
      case 7:
4016
      case 7:
3762
        strcpy_s(buffer, sizeof (buffer), "setboard 4k/5ppp/////PPP/3K/ w"); // Pierre-Marie Baty -- use safe version
4017
        strcpy(buffer, "setboard 4k/5ppp/////PPP/3K/ w");
3763
        (void) Option(tree);
4018
        Option(tree);
3764
        break;
4019
        break;
3765
      default:
4020
      default:
3766
        printf("sorry, only wild7 implemented at present\n");
4021
        printf("sorry, only wild7 implemented at present\n");
3767
        break;
4022
        break;
3768
    }
4023
    }
3769
  }
-
 
3770
/*
-
 
3771
 ************************************************************
-
 
3772
 *                                                          *
-
 
3773
 *  "white" command sets white to move (wtm).               *
-
 
3774
 *                                                          *
-
 
3775
 ************************************************************
-
 
3776
 */
-
 
3777
  else if (OptionMatch("white", *args)) {
-
 
3778
    if (thinking || pondering)
-
 
3779
      return 2;
-
 
3780
    ponder_move = 0;
-
 
3781
    last_pv.pathd = 0;
-
 
3782
    last_pv.pathl = 0;
-
 
3783
    if (!game_wtm)
-
 
3784
      Pass();
-
 
3785
    force = 0;
-
 
3786
  }
4024
  }
3787
/*
4025
/*
3788
 ************************************************************
4026
 ************************************************************
3789
 *                                                          *
4027
 *                                                          *
3790
 *  "xboard" command is normally invoked from main() via    *
4028
 *  "xboard" command is normally invoked from main() via    *
Line 3795... Line 4033...
3795
 */
4033
 */
3796
  else if (OptionMatch("xboard", *args) || OptionMatch("winboard", *args)) {
4034
  else if (OptionMatch("xboard", *args) || OptionMatch("winboard", *args)) {
3797
    if (!xboard) {
4035
    if (!xboard) {
3798
      signal(SIGINT, SIG_IGN);
4036
      signal(SIGINT, SIG_IGN);
3799
      xboard = 1;
4037
      xboard = 1;
3800
      display_options &= 4095 - 1 - 2 - 4 - 8 - 16 - 32 - 128;
4038
      display_options = 2048;
3801
      printf("\n");
4039
      Print(-1, "\n");
3802
      printf("tellicsnoalias set 1 Crafty v%s (%d cpus)\n", version, Max(1,
4040
      Print(-1, "tellicsnoalias set 1 Crafty v%s (%d cpus)\n", version, Max(1,
3803
              smp_max_threads));
4041
              smp_max_threads));
3804
      printf("tellicsnoalias kibitz Hello from Crafty v%s! (%d cpus)\n",
4042
      Print(-1, "tellicsnoalias kibitz Hello from Crafty v%s! (%d cpus)\n",
3805
          version, Max(1, smp_max_threads));
4043
          version, Max(1, smp_max_threads));
3806
      fflush(stdout);
-
 
3807
    }
4044
    }
3808
  }
4045
  }
3809
/*
4046
/*
3810
 ************************************************************
4047
 ************************************************************
3811
 *                                                          *
4048
 *                                                          *
Line 3874... Line 4111...
3874
 */
4111
 */
3875
  if (strstr(command, input) == command)
4112
  if (strstr(command, input) == command)
3876
    return 1;
4113
    return 1;
3877
  return 0;
4114
  return 0;
3878
}
4115
}
-
 
4116
 
3879
void OptionPerft(TREE * RESTRICT tree, int ply, int depth, int wtm) {
4117
void OptionPerft(TREE * RESTRICT tree, int ply, int depth, int wtm) {
3880
  int *mv;
4118
  unsigned *mv;
3881
#if defined(TRACE)
4119
#if defined(TRACE)
3882
  static char line[256];
4120
  static char line[256];
3883
  static char move[16], *p[64];
4121
  static char move[16], *p[64];
3884
#endif
4122
#endif
-
 
4123
 
3885
  tree->last[ply] = GenerateCaptures(tree, ply, wtm, tree->last[ply - 1]);
4124
  tree->last[ply] = GenerateCaptures(tree, ply, wtm, tree->last[ply - 1]);
3886
  for (mv = tree->last[ply - 1]; mv < tree->last[ply]; mv++)
4125
  for (mv = tree->last[ply - 1]; mv < tree->last[ply]; mv++)
3887
    if (Captured(*mv) == king)
4126
    if (Captured(*mv) == king)
3888
      return;
4127
      return;
3889
  tree->last[ply] = GenerateNoncaptures(tree, ply, wtm, tree->last[ply]);
4128
  tree->last[ply] = GenerateNoncaptures(tree, ply, wtm, tree->last[ply]);
3890
#if defined(TRACE)
4129
#if defined(TRACE)
3891
  p[1] = line;
4130
  p[1] = line;
3892
#endif
4131
#endif
3893
  for (mv = tree->last[ply - 1]; mv < tree->last[ply]; mv++) {
4132
  for (mv = tree->last[ply - 1]; mv < tree->last[ply]; mv++) {
3894
#if defined(TRACE)
4133
#if defined(TRACE)
3895
    strcpy_s(move, sizeof (move), OutputMove(tree, *mv, ply, wtm)); // Pierre-Marie Baty -- use safe version
4134
    strcpy(move, OutputMove(tree, ply, wtm, *mv));
3896
#endif
4135
#endif
3897
    MakeMove(tree, ply, *mv, wtm);
4136
    MakeMove(tree, ply, wtm, *mv);
3898
#if defined(TRACE)
4137
#if defined(TRACE)
3899
    if (ply <= trace_level) {
4138
    if (ply <= trace_level) {
3900
      strcpy(p[ply], move);
4139
      strcpy(p[ply], move);
3901
      strcat_s(line, sizeof (line), " "); // Pierre-Marie Baty -- use safe version
4140
      strcpy(line + strlen(line), " ");
3902
      p[ply + 1] = line + strlen(line);
4141
      p[ply + 1] = line + strlen(line);
3903
      if (ply == trace_level)
4142
      if (ply == trace_level)
3904
        printf("%s\n", line);
4143
        printf("%s\n", line);
3905
    }
4144
    }
3906
#endif
4145
#endif
3907
    if (depth - 1)
4146
    if (depth - 1)
3908
      OptionPerft(tree, ply + 1, depth - 1, Flip(wtm));
4147
      OptionPerft(tree, ply + 1, depth - 1, Flip(wtm));
3909
    else if (!Check(wtm))
4148
    else if (!Check(wtm))
3910
      total_moves++;
4149
      total_moves++;
3911
    UnmakeMove(tree, ply, *mv, wtm);
4150
    UnmakeMove(tree, ply, wtm, *mv);
3912
  }
4151
  }
3913
}
4152
}