Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
112 | pmbaty | 1 | /* |
2 | Protector -- a UCI chess engine |
||
3 | |||
4 | Copyright (C) 2009-2010 Raimund Heid (Raimund_Heid@yahoo.com) |
||
5 | |||
6 | This program is free software: you can redistribute it and/or modify |
||
7 | it under the terms of the GNU General Public License as published by |
||
8 | the Free Software Foundation, either version 3 of the License, or |
||
9 | (at your option) any later version. |
||
10 | |||
11 | This program is distributed in the hope that it will be useful, |
||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
14 | GNU General Public License for more details. |
||
15 | |||
16 | You should have received a copy of the GNU General Public License |
||
17 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
18 | |||
19 | */ |
||
20 | |||
21 | #include <assert.h> |
||
22 | #include <stdio.h> |
||
23 | #include <stdlib.h> |
||
24 | #include <string.h> |
||
25 | #include "test.h" |
||
26 | #include "io.h" |
||
27 | #include "pgn.h" |
||
28 | #include "coordination.h" |
||
29 | #include "evaluation.h" |
||
30 | |||
31 | extern bool resetSharedHashtable; |
||
32 | |||
33 | static void handleSearchEvent(int eventId, void *var) |
||
34 | { |
||
35 | Variation *variation = (Variation *) var; |
||
36 | long time; |
||
37 | char *pvMoves; |
||
38 | |||
39 | switch (eventId) |
||
40 | { |
||
41 | case SEARCHEVENT_SEARCH_FINISHED: |
||
42 | time = variation->finishTimeProcess - variation->startTimeProcess; |
||
43 | |||
44 | logReport("%lld nodes in %ld msec\n", getNodeCount(), time); |
||
45 | |||
46 | if (time > 1000) |
||
47 | { |
||
48 | logReport("%ld knps\n", getNodeCount() / max(1, time)); |
||
49 | } |
||
50 | |||
51 | break; |
||
52 | |||
53 | case SEARCHEVENT_PLY_FINISHED: |
||
54 | case SEARCHEVENT_NEW_PV: |
||
55 | pvMoves = getPrincipalVariation(var); |
||
56 | dumpPv(variation->iteration, |
||
57 | (getTimestamp() - variation->startTime), pvMoves, |
||
58 | variation->pv[0].score, variation->nodes, |
||
59 | variation->startPosition.activeColor); |
||
60 | free(pvMoves); |
||
61 | break; |
||
62 | |||
63 | default: |
||
64 | break; |
||
65 | } |
||
66 | } |
||
67 | |||
68 | static bool solveMateProblem(SearchTask * entry) |
||
69 | { |
||
70 | bool result = TRUE; |
||
71 | int i; |
||
72 | |||
73 | completeTask(entry); |
||
74 | |||
75 | if (entry->solutions.numberOfMoves != |
||
76 | entry->calculatedSolutions.numberOfMoves) |
||
77 | { |
||
78 | result = FALSE; |
||
79 | } |
||
80 | |||
81 | for (i = 0; i < entry->solutions.numberOfMoves; i++) |
||
82 | { |
||
83 | if (listContainsMove |
||
84 | (&entry->calculatedSolutions, entry->solutions.moves[i]) == FALSE) |
||
85 | { |
||
86 | result = FALSE; |
||
87 | } |
||
88 | } |
||
89 | |||
90 | return result; |
||
91 | } |
||
92 | |||
93 | static bool solveBestMoveProblem(SearchTask * entry) |
||
94 | { |
||
95 | completeTask(entry); |
||
96 | |||
97 | return listContainsMove(&entry->solutions, entry->bestMove); |
||
98 | } |
||
99 | |||
100 | static bool dumpEvaluation(SearchTask * entry) |
||
101 | { |
||
102 | EvaluationBase base; |
||
103 | |||
104 | prepareSearch(entry->variation); |
||
105 | getValue(&entry->variation->startPosition, |
||
106 | &base, |
||
107 | entry->variation->pawnHashtable, |
||
108 | entry->variation->kingsafetyHashtable); |
||
109 | |||
110 | return TRUE; |
||
111 | } |
||
112 | |||
113 | int processTestsuite(const char *filename) |
||
114 | { |
||
115 | PGNFile pgnfile; |
||
116 | PGNGame *game; |
||
117 | SearchTask entry; |
||
118 | Gamemove *gamemove; |
||
119 | long i; |
||
120 | UINT64 overallNodes = 0; |
||
121 | const char *fmt = "\nTestsuite '%s': %d/%d solved, %s nodes\n"; |
||
122 | char ons[32]; |
||
123 | int solved = 0; |
||
124 | String notSolved = getEmptyString(); |
||
125 | Variation variation; |
||
126 | |||
127 | if (openPGNFile(&pgnfile, filename) != 0) |
||
128 | { |
||
129 | return -1; |
||
130 | } |
||
131 | |||
132 | logReport("\nProcessing file '%s' [%ld game(s)]\n", filename, |
||
133 | pgnfile.numGames); |
||
134 | |||
135 | statCount1 = statCount2 = 0; |
||
136 | variation.timeTarget = 60 * 1000; |
||
137 | variation.timeLimit = 60 * 1000; |
||
138 | variation.ponderMode = FALSE; |
||
139 | entry.variation = &variation; |
||
140 | |||
141 | for (i = 1; i <= pgnfile.numGames; i++) |
||
142 | { |
||
143 | game = getGame(&pgnfile, i); |
||
144 | |||
145 | if (game == 0) |
||
146 | { |
||
147 | continue; |
||
148 | } |
||
149 | |||
150 | logReport("\n%ld (%ld): %s-%s\n", i, pgnfile.numGames, |
||
151 | game->white, game->black); |
||
152 | logPosition(&game->firstMove->position); |
||
153 | |||
154 | entry.solutions.numberOfMoves = 0; |
||
155 | gamemove = game->firstMove; |
||
156 | |||
157 | while (gamemove != 0) |
||
158 | { |
||
159 | entry.solutions.moves |
||
160 | [entry.solutions.numberOfMoves++] = |
||
161 | getPackedMove(gamemove->from, gamemove->to, gamemove->newPiece); |
||
162 | |||
163 | gamemove = gamemove->alternativeMove; |
||
164 | } |
||
165 | |||
166 | initializeVariation(&variation, game->fen); |
||
167 | resetSharedHashtable = TRUE; |
||
168 | variation.handleSearchEvent = &handleSearchEvent; |
||
169 | |||
170 | if (strstr(game->white, "[#") != NULL) |
||
171 | { |
||
172 | char *tmp = strstr(game->white, "[#"); |
||
173 | |||
174 | entry.type = TASKTYPE_TEST_MATE_IN_N; |
||
175 | entry.numberOfMoves = atoi(tmp + 2); |
||
176 | |||
177 | if (solveMateProblem(&entry) != FALSE) |
||
178 | { |
||
179 | solved++; |
||
180 | } |
||
181 | else |
||
182 | { |
||
183 | assert(0); |
||
184 | } |
||
185 | |||
186 | overallNodes += entry.nodes; |
||
187 | } |
||
188 | else |
||
189 | { |
||
190 | entry.type = TASKTYPE_TEST_BEST_MOVE; |
||
191 | entry.numberOfMoves = 0; |
||
192 | |||
193 | if (commandlineOptions.dumpEvaluation) |
||
194 | { |
||
195 | dumpEvaluation(&entry); |
||
196 | } |
||
197 | else |
||
198 | { |
||
199 | if (solveBestMoveProblem(&entry) != FALSE) |
||
200 | { |
||
201 | solved++; |
||
202 | } |
||
203 | else |
||
204 | { |
||
205 | appendToString(¬Solved, "%d ", i); |
||
206 | } |
||
207 | |||
208 | overallNodes += entry.nodes; |
||
209 | } |
||
210 | } |
||
211 | |||
212 | freePgnGame(game); |
||
213 | } |
||
214 | |||
215 | formatLongInteger(overallNodes, ons); |
||
216 | logReport(fmt, filename, solved, pgnfile.numGames, ons); |
||
217 | logReport("Not solved: %s\n", notSolved.buffer); |
||
218 | free(notSolved.buffer); |
||
219 | closePGNFile(&pgnfile); |
||
220 | |||
221 | return 0; |
||
222 | } |
||
223 | |||
224 | /** |
||
225 | * Initialize this module. |
||
226 | * |
||
227 | * @return 0 if no errors occurred. |
||
228 | */ |
||
229 | int initializeModuleTest(void) |
||
230 | { |
||
231 | return 0; |
||
232 | } |
||
233 | |||
234 | int testModuleTest() |
||
235 | { |
||
236 | int result; |
||
237 | |||
238 | if ((result = processTestsuite("moduletest.pgn")) != 0) |
||
239 | { |
||
240 | return result; |
||
241 | } |
||
242 | |||
243 | return 0; |
||
244 | } |