1 #include "chess.h"
2 #include "data.h"
3 /* last modified 02/26/14 */
4 /*
5 *******************************************************************************
6 * *
7 * EVTest() 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 *
9 * after modifying it in some way. *
10 * *
11 * The test is initiated by using the "evtest <filename>" command to read in *
12 * the suite of problems from file <filename>. The format of this file is *
13 * as follows: *
14 * *
15 * <forsythe-string> This sets the board position using the usual Forsythe *
16 * notation (see module SetBoard() for a full explanation explanation of the *
17 * syntax). *
18 * *
19 * After reading this position, the program then calls Evaluate() to produce *
20 * a positional evaluation, along with any debug output from Evaluate(), and *
21 * then goes on to the next position. *
22 * *
23 * A common use (with code included below) is to take a position, and then *
24 * "flip" it (reverse the board rank by rank changing the color of each *
25 * piece as this is done, giving us two positions. We then take each of *
26 * these and mirror them, which reverses them file by file, which now gives *
27 * four positions in total. We run these thru Evaluate() to make sure that *
28 * all produce exactly the same score, except for the color change for the *
29 * two that changed the piece colors. This is used to make certain that the *
30 * evaluation is not asymmetric with respect to the colors, or to the side *
31 * of the board, which catches errors that are difficult to spot otherwise. *
32 * *
33 *******************************************************************************
34 */
EVTest(char * filename)35 void EVTest(char *filename) {
36 FILE *test_input;
37 char *eof;
38 char buff[4096];
39 TREE *const tree = block[0];
40
41 /*
42 ************************************************************
43 * *
44 * Read in the position *
45 * *
46 ************************************************************
47 */
48 if (!(test_input = fopen(filename, "r"))) {
49 printf("file %s does not exist.\n", filename);
50 return;
51 }
52 while (FOREVER) {
53 eof = fgets(buffer, 4096, test_input);
54 if (eof) {
55 char *delim;
56
57 delim = strchr(buffer, '\n');
58 if (delim)
59 *delim = 0;
60 delim = strchr(buffer, '\r');
61 if (delim)
62 *delim = ' ';
63 } else
64 break;
65 strcpy(buff, buffer);
66 nargs = ReadParse(buffer, args, " \t;");
67 if (!strcmp(args[0], "end"))
68 break;
69 /*
70 ************************************************************
71 * *
72 * Now for the asymmetry tests. We use the built-in *
73 * commands "flip" and "flop" to create the four *
74 * positions, and call Evaluate() for each. *
75 * *
76 ************************************************************
77 */
78 else {
79 int s1, s2, s3, s4, id;
80
81 for (id = 2; id < nargs; id++)
82 if (!strcmp(args[id], "id"))
83 break;
84 if (id >= nargs)
85 id = 0;
86 SetBoard(tree, nargs, args, 0);
87 Castle(0, white) = 0;
88 Castle(1, white) = 0;
89 Castle(0, black) = 0;
90 Castle(1, black) = 0;
91 tree->pawn_score.key = 0;
92 root_wtm = game_wtm;
93 s1 = Evaluate(tree, 0, game_wtm, -99999, 99999);
94 strcpy(buffer, "flop");
95 Option(tree);
96 tree->pawn_score.key = 0;
97 root_wtm = game_wtm;
98 s2 = Evaluate(tree, 0, game_wtm, -99999, 99999);
99 strcpy(buffer, "flip");
100 Option(tree);
101 tree->pawn_score.key = 0;
102 root_wtm = game_wtm;
103 s3 = Evaluate(tree, 0, game_wtm, -99999, 99999);
104 strcpy(buffer, "flop");
105 Option(tree);
106 tree->pawn_score.key = 0;
107 root_wtm = game_wtm;
108 s4 = Evaluate(tree, 0, game_wtm, -99999, 99999);
109 /*
110 ************************************************************
111 * *
112 * If the evaluations (with sign corrected if piece color *
113 * was changed) are different, we display the four values *
114 * and then display the original board position so that we *
115 * can debug the cause of the asymmetry. *
116 * *
117 ************************************************************
118 */
119 if (s1 != s2 || s1 != s3 || s1 != s4 || s2 != s3 || s2 != s4 ||
120 s3 != s4) {
121 strcpy(buffer, "flip");
122 Option(tree);
123 printf("FEN = %s\n", buff);
124 DisplayChessBoard(stdout, tree->position);
125 if (id)
126 Print(4095, "id=%s ", args[id + 1]);
127 Print(4095, "wtm=%d score=%d %d (flop) %d (flip) %d (flop)\n",
128 game_wtm, s1, s2, s3, s4);
129 }
130 }
131 }
132 input_stream = stdin;
133 }
134