Rev 108 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
33 | pmbaty | 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 | */ |
||
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 | } |
||
154 | pmbaty | 52 | while (FOREVER) { |
33 | pmbaty | 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; |
||
108 | pmbaty | 65 | strcpy(buff, buffer); |
66 | nargs = ReadParse(buffer, args, " \t;"); |
||
33 | pmbaty | 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; |
||
108 | pmbaty | 91 | tree->pawn_score.key = 0; |
33 | pmbaty | 92 | root_wtm = game_wtm; |
93 | s1 = Evaluate(tree, 0, game_wtm, -99999, 99999); |
||
108 | pmbaty | 94 | strcpy(buffer, "flop"); |
95 | Option(tree); |
||
33 | pmbaty | 96 | tree->pawn_score.key = 0; |
108 | pmbaty | 97 | root_wtm = game_wtm; |
33 | pmbaty | 98 | s2 = Evaluate(tree, 0, game_wtm, -99999, 99999); |
108 | pmbaty | 99 | strcpy(buffer, "flip"); |
100 | Option(tree); |
||
33 | pmbaty | 101 | tree->pawn_score.key = 0; |
108 | pmbaty | 102 | root_wtm = game_wtm; |
33 | pmbaty | 103 | s3 = Evaluate(tree, 0, game_wtm, -99999, 99999); |
108 | pmbaty | 104 | strcpy(buffer, "flop"); |
105 | Option(tree); |
||
33 | pmbaty | 106 | tree->pawn_score.key = 0; |
108 | pmbaty | 107 | root_wtm = game_wtm; |
33 | pmbaty | 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) { |
||
108 | pmbaty | 121 | strcpy(buffer, "flip"); |
122 | Option(tree); |
||
33 | pmbaty | 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 | } |