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 | } |