Subversion Repositories Games.Chess Giants

Rev

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

Rev 33 Rev 108
Line 1... Line 1...
1
#include "chess.h"
1
#include "chess.h"
2
#include "data.h"
2
#include "data.h"
3
/* last modified 02/26/14 */
3
/* last modified 01/09/15 */
4
/*
4
/*
5
 *******************************************************************************
5
 *******************************************************************************
6
 *                                                                             *
6
 *                                                                             *
7
 *   Test() is used to test the program against a suite of test positions to   *
7
 *   Test() is used to test the program against a suite of test positions to   *
8
 *   measure its performance on a particular machine, or to evaluate its skill *
8
 *   measure its performance on a particular machine, or to evaluate its skill *
Line 31... Line 31...
31
 *   EPD-style test positions which is more concise.  Other than the parsing   *
31
 *   EPD-style test positions which is more concise.  Other than the parsing   *
32
 *   differences, these are identical modules.                                 *
32
 *   differences, these are identical modules.                                 *
33
 *                                                                             *
33
 *                                                                             *
34
 *******************************************************************************
34
 *******************************************************************************
35
 */
35
 */
36
void Test(char *filename) {
36
void Test(char *filename, FILE * unsolved, int screen, int margin) {
-
 
37
  TREE *const tree = block[0];
37
  FILE *test_input;
38
  FILE *test_input;
38
  int i, move, right = 0, wrong = 0, correct;
-
 
39
  int time = 0, len;
-
 
40
  uint64_t nodes = 0;
39
  uint64_t nodes = 0;
41
  char *eof, *delim;
40
  int i, move, right = 0, wrong = 0, correct, time = 0, len, nfailed = 0;
42
  float avg_depth = 0.0;
41
  float avg_depth = 0.0;
43
  TREE *const tree = block[0];
42
  char failed[8][4096], *eof, *delim;
44
 
43
 
45
/*
44
/*
46
 ************************************************************
45
 ************************************************************
47
 *                                                          *
46
 *                                                          *
48
 *  Read in the position and then the solutions.  After     *
47
 *  Read in the position and then the solutions.  After     *
Line 50... Line 49...
50
 *  the program, anyway) compare it against the list of     *
49
 *  the program, anyway) compare it against the list of     *
51
 *  solutions and count it right or wrong.                  *
50
 *  solutions and count it right or wrong.                  *
52
 *                                                          *
51
 *                                                          *
53
 ************************************************************
52
 ************************************************************
54
 */
53
 */
55
  fopen_s (&test_input, filename, "r");
54
  if (!(test_input = fopen(filename, "r"))) {
56
  if (!test_input) {
-
 
57
    printf("file %s does not exist.\n", filename);
55
    printf("file %s does not exist.\n", filename);
58
    return;
56
    return;
59
  }
57
  }
60
  Print(4095, "\n");
58
  Print(4095, "\n");
61
  eof = fgets(buffer, 4096, test_input);
59
  eof = fgets(buffer, 4096, test_input);
62
  if (strstr(buffer, "title"));
60
  if (!strstr(buffer, "title")) {
63
  else {
-
 
64
    fclose(test_input);
61
    fclose(test_input);
65
    TestEPD(filename);
62
    TestEPD(filename, unsolved, screen, margin);
66
    return;
63
    return;
67
  }
64
  }
68
  if (book_file) {
65
  if (book_file) {
69
    fclose(book_file);
66
    fclose(book_file);
70
    book_file = 0;
67
    book_file = 0;
71
  }
68
  }
72
  if (books_file) {
69
  if (books_file) {
73
    fclose(books_file);
70
    fclose(books_file);
74
    books_file = 0;
71
    books_file = 0;
75
  }
72
  }
-
 
73
  fclose(test_input);
-
 
74
  test_input = fopen(filename, "r");
76
  while (1) {
75
  while (1) {
-
 
76
    eof = fgets(buffer, 4096, test_input);
-
 
77
    strcpy(failed[nfailed++], buffer);
77
    if (eof) {
78
    if (eof) {
78
      delim = strchr(buffer, '\n');
79
      delim = strchr(buffer, '\n');
79
      if (delim)
80
      if (delim)
80
        *delim = 0;
81
        *delim = 0;
81
      delim = strchr(buffer, '\r');
82
      delim = strchr(buffer, '\r');
82
      if (delim)
83
      if (delim)
83
        *delim = ' ';
84
        *delim = ' ';
84
    } else
85
    } else
85
      break;
86
      break;
86
    nargs = ReadParse(buffer, args, " ;");
87
    nargs = ReadParse(buffer, args, " \t;");
87
    if (!strcmp(args[0], "end"))
88
    if (!strcmp(args[0], "end"))
88
      break;
89
      break;
89
    else if (!strcmp(args[0], "title")) {
90
    else if (!strcmp(args[0], "title")) {
90
      Print(4095,
91
      Print(4095,
91
          "=============================================="
92
          "=============================================="
Line 116... Line 117...
116
          args[i][strlen(args[i]) - 1] = '\0';
117
          args[i][strlen(args[i]) - 1] = '\0';
117
        } else if (*(args + i)[strlen(args[i]) - 1] == '!') {
118
        } else if (*(args + i)[strlen(args[i]) - 1] == '!') {
118
          solution_type = 0;
119
          solution_type = 0;
119
          args[i][strlen(args[i]) - 1] = '\0';
120
          args[i][strlen(args[i]) - 1] = '\0';
120
        }
121
        }
121
        move = InputMove(tree, args[i], 0, game_wtm, 0, 0);
122
        move = InputMove(tree, 0, game_wtm, 0, 0, args[i]);
122
        if (move) {
123
        if (move) {
123
          solutions[number_of_solutions] = move;
124
          solutions[number_of_solutions] = move;
124
          Print(4095, "%d. %s", (number_of_solutions++) + 1, OutputMove(tree,
125
          Print(4095, "%d. %s", (number_of_solutions++) + 1, OutputMove(tree,
125
                  move, 0, game_wtm));
126
                  0, game_wtm, move));
126
          if (solution_type == 1)
127
          if (solution_type == 1)
127
            Print(4095, "? ");
128
            Print(4095, "? ");
128
          else
129
          else
129
            Print(4095, "  ");
130
            Print(4095, "  ");
130
        } else
131
        } else
131
          DisplayChessBoard(stdout, tree->position);
132
          DisplayChessBoard(stdout, tree->position);
132
      }
133
      }
133
      Print(4095, "\n");
134
      Print(4095, "\n");
134
      InitializeHashTables();
135
      InitializeHashTables(0);
135
      last_pv.pathd = 0;
136
      last_pv.pathd = 0;
136
      thinking = 1;
137
      thinking = 1;
137
      tree->status[1] = tree->status[0];
138
      tree->status[1] = tree->status[0];
138
      (void) Iterate(game_wtm, think, 0);
139
      Iterate(game_wtm, think, 0);
139
      thinking = 0;
140
      thinking = 0;
140
      nodes += tree->nodes_searched;
141
      nodes += tree->nodes_searched;
141
      avg_depth += (float) iteration_depth;
142
      avg_depth += (float) iteration;
142
      time += (end_time - start_time);
143
      time += (end_time - start_time);
143
      correct = solution_type;
144
      correct = solution_type;
144
      for (i = 0; i < number_of_solutions; i++) {
145
      for (i = 0; i < number_of_solutions; i++) {
145
        if (!solution_type) {
146
        if (!solution_type) {
146
          if (solutions[i] == tree->pv[1].path[1])
147
          if (solutions[i] == (tree->pv[1].path[1] & 0x001fffff))
147
            correct = 1;
148
            correct = 1;
148
        } else if (solutions[i] == tree->pv[1].path[1])
149
        } else if (solutions[i] == (tree->pv[1].path[1] & 0x001fffff))
149
          correct = 0;
150
          correct = 0;
150
      }
151
      }
151
      if (correct) {
152
      if (correct) {
152
        right++;
153
        right++;
153
        Print(4095, "----------------------> solution correct (%d/%d).\n",
154
        Print(4095, "----------------------> solution correct (%d/%d).\n",
154
            right, right + wrong);
155
            right, right + wrong);
155
      } else {
156
      } else {
156
        wrong++;
157
        wrong++;
157
        Print(4095, "----------------------> solution incorrect (%d/%d).\n",
158
        Print(4095, "----------------------> solution incorrect (%d/%d).\n",
158
            right, right + wrong);
159
            right, right + wrong);
-
 
160
        if (unsolved)
-
 
161
          for (i = 0; i < nfailed; i++)
-
 
162
            fputs(failed[i], unsolved);
159
      }
163
      }
-
 
164
      nfailed = 0;
160
    }
165
    }
161
    eof = fgets(buffer, 4096, test_input);
-
 
162
  }
166
  }
163
/*
167
/*
164
 ************************************************************
168
 ************************************************************
165
 *                                                          *
169
 *                                                          *
166
 *  Now print the results.                                  *
170
 *  Now print the results.                                  *
Line 187... Line 191...
187
  }
191
  }
188
  input_stream = stdin;
192
  input_stream = stdin;
189
  early_exit = 99;
193
  early_exit = 99;
190
}
194
}
191
 
195
 
192
/* last modified 02/26/14 */
196
/* last modified 06/26/15 */
193
/*
197
/*
194
 *******************************************************************************
198
 *******************************************************************************
195
 *                                                                             *
199
 *                                                                             *
196
 *   TestEPD() is used to test the program against a suite of test positions   *
200
 *   TestEPD() is used to test the program against a suite of test positions   *
197
 *   to measure its performance on a particular machine, or to evaluate its    *
201
 *   to measure its performance on a particular machine, or to evaluate its    *
Line 207... Line 211...
207
 *   have multiple moves to avoid or that are best, but both am and bm may not *
211
 *   have multiple moves to avoid or that are best, but both am and bm may not *
208
 *   appear on one position.                                                   *
212
 *   appear on one position.                                                   *
209
 *                                                                             *
213
 *                                                                             *
210
 *   The title is just a comment that is given in the program output to make   *
214
 *   The title is just a comment that is given in the program output to make   *
211
 *   it easier to match output to specific positions.                          *
215
 *   it easier to match output to specific positions.                          *
-
 
216
 *                                                                             *
-
 
217
 *   One new addition is the ability to take a set of EPD records and run a    *
-
 
218
 *   search on each one.  If the final evaluation is within some window, then  *
-
 
219
 *   the input record is written out to a second file.  This is used to screen *
-
 
220
 *   cluster-testing starting positions to weed out those that are so badly    *
-
 
221
 *   unbalanced that one side always wins.                                     *
212
 *                                                                             *
222
 *                                                                             *
213
 *******************************************************************************
223
 *******************************************************************************
214
 */
224
 */
215
void TestEPD(char *filename) {
225
void TestEPD(char *filename, FILE * unsolved, int screen, int margin) {
216
  FILE *test_input;
226
  TREE *const tree = block[0];
217
  int i, move, right = 0, wrong = 0, correct;
227
  FILE *test_input, *test_output = 0;
218
  int time = 0, len;
-
 
219
  uint64_t nodes = 0;
228
  uint64_t nodes = 0;
-
 
229
  int i, move, right = 0, wrong = 0, correct, time = 0, len, culled = 0, r =
220
  char *eof, *mvs, *title;
230
      0;
221
  float avg_depth = 0.0;
231
  float avg_depth = 0.0;
222
  TREE *const tree = block[0];
232
  char *eof, *mvs, *title, tbuffer[512], failed[4096];
223
 
233
 
224
/*
234
/*
225
 ************************************************************
235
 ************************************************************
226
 *                                                          *
236
 *                                                          *
227
 *  Read in the position and then the solutions.  After     *
237
 *  Read in the position and then the solutions.  After     *
Line 229... Line 239...
229
 *  the program, anyway) compare it against the list of     *
239
 *  the program, anyway) compare it against the list of     *
230
 *  solutions and count it right or wrong.                  *
240
 *  solutions and count it right or wrong.                  *
231
 *                                                          *
241
 *                                                          *
232
 ************************************************************
242
 ************************************************************
233
 */
243
 */
234
  fopen_s(&test_input, filename, "r"); // Pierre-Marie Baty -- use safe version
-
 
235
  if (!test_input) {
244
  if (!(test_input = fopen(filename, "r"))) {
236
    printf("file %s does not exist.\n", filename);
245
    printf("file %s does not exist.\n", filename);
237
    return;
246
    return;
-
 
247
  }
-
 
248
  if (screen) {
-
 
249
    char outfile[256];
-
 
250
 
-
 
251
    strcpy(outfile, filename);
-
 
252
    strcat(outfile, ".screened");
-
 
253
    if (!(test_output = fopen(outfile, "w"))) {
-
 
254
      printf("file %s cannot be opened for write.\n", filename);
-
 
255
      return;
-
 
256
    }
238
  }
257
  }
239
  if (book_file) {
258
  if (book_file) {
240
    fclose(book_file);
259
    fclose(book_file);
241
    book_file = 0;
260
    book_file = 0;
242
  }
261
  }
Line 244... Line 263...
244
    fclose(books_file);
263
    fclose(books_file);
245
    books_file = 0;
264
    books_file = 0;
246
  }
265
  }
247
  while (1) {
266
  while (1) {
248
    eof = fgets(buffer, 4096, test_input);
267
    eof = fgets(buffer, 4096, test_input);
-
 
268
    strcpy(failed, buffer);
-
 
269
    Print(4095, "%s\n", buffer);
-
 
270
    strcpy(tbuffer, buffer);
249
    if (eof) {
271
    if (eof) {
250
      char *delim;
272
      char *delim;
251
 
273
 
252
      delim = strchr(buffer, '\n');
274
      delim = strchr(buffer, '\n');
253
      if (delim)
275
      if (delim)
Line 255... Line 277...
255
      delim = strchr(buffer, '\r');
277
      delim = strchr(buffer, '\r');
256
      if (delim)
278
      if (delim)
257
        *delim = ' ';
279
        *delim = ' ';
258
    } else
280
    } else
259
      break;
281
      break;
-
 
282
    r++;
-
 
283
    mvs = strstr(buffer, " sd ");
-
 
284
    if (mvs) {
-
 
285
      search_depth = atoi(mvs + 3);
-
 
286
      *(mvs - 1) = 0;
-
 
287
      Print(4095, "search depth %d\n", search_depth);
-
 
288
    }
260
    mvs = strstr(buffer, " bm ");
289
    mvs = strstr(buffer, " bm ");
261
    if (!mvs)
290
    if (!mvs)
262
      mvs = strstr(buffer, " am ");
291
      mvs = strstr(buffer, " am ");
263
    if (!mvs)
292
    if (!mvs && !screen)
264
      Print(4095, "Warning. am/bm field missing, input string follows\n%s\n",
293
      Print(4095, "Warning. am/bm field missing, input string follows\n%s\n",
265
          buffer);
294
          buffer);
266
    if (mvs)
295
    if (mvs)
267
      mvs++;
296
      mvs++;
268
    title = strstr(buffer, "id");
297
    title = strstr(buffer, "id");
Line 290... Line 319...
290
          "=============================================="
319
          "=============================================="
291
          "========================\n");
320
          "========================\n");
292
    }
321
    }
293
    Option(tree);
322
    Option(tree);
294
    if (mvs) {
323
    if (mvs) {
295
      nargs = ReadParse(mvs, args, " ;");
324
      nargs = ReadParse(mvs, args, " \t;");
296
      number_of_solutions = 0;
325
      number_of_solutions = 0;
297
      solution_type = 0;
326
      solution_type = 0;
298
      if (!strcmp(args[0], "am"))
327
      if (!strcmp(args[0], "am"))
299
        solution_type = 1;
328
        solution_type = 1;
300
      Print(4095, "solution ");
329
      Print(4095, "solution ");
301
      for (i = 1; i < nargs; i++) {
330
      for (i = 1; i < nargs; i++) {
302
        if (!strcmp(args[i], "c0"))
331
        if (!strcmp(args[i], "c0"))
303
          break;
332
          break;
304
        move = InputMove(tree, args[i], 0, game_wtm, 0, 0);
333
        move = InputMove(tree, 0, game_wtm, 0, 0, args[i]);
305
        if (move) {
334
        if (move) {
306
          solutions[number_of_solutions] = move;
335
          solutions[number_of_solutions] = move;
307
          Print(4095, "%d. %s", (number_of_solutions++) + 1, OutputMove(tree,
336
          Print(4095, "%d. %s", (number_of_solutions++) + 1, OutputMove(tree,
308
                  move, 0, game_wtm));
337
                  0, game_wtm, move));
309
          if (solution_type == 1)
338
          if (solution_type == 1)
310
            Print(4095, "? ");
339
            Print(4095, "? ");
311
          else
340
          else
312
            Print(4095, "  ");
341
            Print(4095, "  ");
313
        } else
342
        } else
314
          DisplayChessBoard(stdout, tree->position);
343
          DisplayChessBoard(stdout, tree->position);
315
      }
344
      }
316
    }
345
    }
317
    Print(4095, "\n");
346
    Print(4095, "\n");
318
    InitializeHashTables();
347
    InitializeHashTables(0);
319
    last_pv.pathd = 0;
348
    last_pv.pathd = 0;
320
    thinking = 1;
349
    thinking = 1;
321
    tree->status[1] = tree->status[0];
350
    tree->status[1] = tree->status[0];
322
    (void) Iterate(game_wtm, think, 0);
351
    Iterate(game_wtm, think, 0);
-
 
352
    if (screen) {
-
 
353
      if (Abs(last_root_value) < margin)
-
 
354
        fwrite(tbuffer, 1, strlen(tbuffer), test_output);
-
 
355
      else
-
 
356
        culled++;
-
 
357
      printf("record #%d,  culled %d, score=%s          \r", r, culled,
-
 
358
          DisplayEvaluation(last_root_value, game_wtm));
-
 
359
      fflush(stdout);
-
 
360
    }
323
    thinking = 0;
361
    thinking = 0;
324
    nodes += tree->nodes_searched;
362
    nodes += tree->nodes_searched;
325
    avg_depth += (float) iteration_depth;
363
    avg_depth += (float) iteration;
326
    time += (end_time - start_time);
364
    time += (end_time - start_time);
-
 
365
    if (!screen) {
327
    correct = solution_type;
366
      correct = solution_type;
328
    for (i = 0; i < number_of_solutions; i++) {
367
      for (i = 0; i < number_of_solutions; i++) {
329
      if (!solution_type) {
368
        if (!solution_type) {
330
        if (solutions[i] == tree->pv[1].path[1])
369
          if (solutions[i] == (tree->pv[1].path[1] & 0x001fffff))
331
          correct = 1;
370
            correct = 1;
332
      } else if (solutions[i] == tree->pv[1].path[1])
371
        } else if (solutions[i] == (tree->pv[1].path[1] & 0x001fffff))
333
        correct = 0;
372
          correct = 0;
334
    }
373
      }
335
    if (correct) {
374
      if (correct) {
336
      right++;
375
        right++;
337
      Print(4095, "----------------------> solution correct (%d/%d).\n",
376
        Print(4095, "----------------------> solution correct (%d/%d).\n",
338
          right, right + wrong);
377
            right, right + wrong);
339
    } else {
378
      } else {
340
      wrong++;
379
        wrong++;
341
      Print(4095, "----------------------> solution incorrect (%d/%d).\n",
380
        Print(4095, "----------------------> solution incorrect (%d/%d).\n",
342
          right, right + wrong);
381
            right, right + wrong);
-
 
382
        if (unsolved)
-
 
383
          fputs(failed, unsolved);
-
 
384
      }
343
    }
385
    }
344
  }
386
  }
345
/*
387
/*
346
 ************************************************************
388
 ************************************************************
347
 *                                                          *
389
 *                                                          *
348
 *  Now print the results.                                  *
390
 *  Now print the results.                                  *
349
 *                                                          *
391
 *                                                          *
350
 ************************************************************
392
 ************************************************************
351
 */
393
 */
352
  if (right + wrong) {
394
  if (r) {
353
    Print(4095, "\n\n\n");
395
    Print(4095, "\n\n\n");
354
    Print(4095, "test results summary:\n\n");
396
    Print(4095, "test results summary:\n\n");
355
    Print(4095, "total positions searched..........%12d\n", right + wrong);
397
    Print(4095, "total positions searched..........%12d\n", r);
-
 
398
    if (!screen) {
356
    Print(4095, "number right......................%12d\n", right);
399
      Print(4095, "number right......................%12d\n", right);
357
    Print(4095, "number wrong......................%12d\n", wrong);
400
      Print(4095, "number wrong......................%12d\n", wrong);
358
    Print(4095, "percentage right..................%12d\n",
401
      Print(4095, "percentage right..................%12d\n",
359
        right * 100 / (right + wrong));
402
          right * 100 / (right + wrong));
360
    Print(4095, "percentage wrong..................%12d\n",
403
      Print(4095, "percentage wrong..................%12d\n",
361
        wrong * 100 / (right + wrong));
404
          wrong * 100 / (right + wrong));
-
 
405
    } else
-
 
406
      Print(4095, "records excluded..................%12d\n", culled);
-
 
407
 
362
    Print(4095, "total nodes searched..............%12" PRIu64 "\n", nodes);
408
    Print(4095, "total nodes searched..............%12" PRIu64 "\n", nodes);
363
    Print(4095, "average search depth..............%12.1f\n",
409
    Print(4095, "average search depth..............%12.1f\n", avg_depth / r);
364
        avg_depth / (right + wrong));
-
 
365
    Print(4095, "nodes per second..................%12" PRIu64 "\n",
410
    Print(4095, "nodes per second..................%12" PRIu64 "\n",
366
        nodes * 100 / Max(1, time));
411
        nodes * 100 / Max(1, time));
367
    Print(4095, "total time........................%12s\n",
412
    Print(4095, "total time........................%12s\n",
368
        DisplayTime(time));
413
        DisplayTime(time));
369
  }
414
  }