1 /*
2 Sjeng - a chess variants playing program
3 Copyright (C) 2000 Gian-Carlo Pascutto
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 File: epd.c
20 Purpose: run EPD test suite
21
22 */
23
24 #include "sjeng.h"
25 #include "protos.h"
26 #include "extvars.h"
27
setup_epd_line(char * inbuff)28 void setup_epd_line(char* inbuff)
29 {
30 int i = 0;
31 int rankp = 0; // a8
32 int rankoffset = 0;
33 int fileoffset = 0;
34 int j;
35
36 /* 0 : FEN data */
37 /* 1 : Active color */
38 /* 2 : Castling status */
39 /* 3 : EP info */
40 /* 4 : 50 move */
41 /* 5 : movenumber */
42 /* 6 : EPD data */
43 int stage = 0;
44
45 static int rankoffsets[] = {110, 98, 86, 74, 62, 50, 38, 26};
46
47 /* conversion from algebraic to sjeng internal for ep squares */
48 int converterf = (int) 'a';
49 int converterr = (int) '1';
50 int ep_file, ep_rank, norm_file, norm_rank;
51
52 memset(board, frame, sizeof(board));
53
54 white_castled = no_castle;
55 black_castled = no_castle;
56
57 book_ply = 50;
58
59 rankoffset = rankoffsets[0];
60
61 while (inbuff[i] == ' ') {i++;};
62
63 while((inbuff[i] != '\n') && (inbuff[i] != '\0'))
64 {
65 if(stage == 0 && isdigit(inbuff[i]))
66 {
67 for (j = 0; j < atoi(&inbuff[i]); j++)
68 board[rankoffset + j + fileoffset] = npiece;
69
70 fileoffset += atoi(&inbuff[i]);
71 }
72 else if (stage == 0 && inbuff[i] == '/')
73 {
74 rankp++;
75 rankoffset = rankoffsets[rankp];
76 fileoffset = 0;
77 }
78 else if (stage == 0 && isalpha(inbuff[i]))
79 {
80 switch (inbuff[i])
81 {
82 case 'p' : board[rankoffset + fileoffset] = bpawn; break;
83 case 'P' : board[rankoffset + fileoffset] = wpawn; break;
84 case 'n' : board[rankoffset + fileoffset] = bknight; break;
85 case 'N' : board[rankoffset + fileoffset] = wknight; break;
86 case 'b' : board[rankoffset + fileoffset] = bbishop; break;
87 case 'B' : board[rankoffset + fileoffset] = wbishop; break;
88 case 'r' : board[rankoffset + fileoffset] = brook; break;
89 case 'R' : board[rankoffset + fileoffset] = wrook; break;
90 case 'q' : board[rankoffset + fileoffset] = bqueen; break;
91 case 'Q' : board[rankoffset + fileoffset] = wqueen; break;
92 case 'k' :
93 bking_loc = rankoffset + fileoffset;
94 board[bking_loc] = bking;
95 break;
96 case 'K' :
97 wking_loc = rankoffset + fileoffset;
98 board[wking_loc] = wking;
99 break;
100 }
101 fileoffset++;
102 }
103 else if (inbuff[i] == ' ')
104 {
105 stage++;
106
107 if (stage == 1)
108 {
109 /* skip spaces */
110 while (inbuff[i] == ' ') i++;
111
112 if (inbuff[i] == 'w')
113 white_to_move = 1;
114 else
115 white_to_move = 0;
116 }
117 else if (stage == 2)
118 {
119 /* assume no castling at all */
120 moved[26] = moved[33] = moved[30] = 1;
121 moved[110] = moved[114] = moved[117] = 1;
122
123 while(inbuff[i] == ' ') i++;
124
125 while (inbuff[i] != ' ')
126 {
127 switch (inbuff[i])
128 {
129 case '-' :
130 break;
131 case 'K' :
132 moved[30] = moved[33] = 0;
133 break;
134 case 'Q' :
135 moved[30] = moved[26] = 0;
136 break;
137 case 'k' :
138 moved[114] = moved[117] = 0;
139 break;
140 case 'q' :
141 moved[114] = moved[110] = 0;
142 break;
143 }
144 i++;
145 }
146 i--; /* go back to space so we move to next stage */
147
148 }
149 else if (stage == 3)
150 {
151 /* skip spaces */
152 while (inbuff[i] == ' ') i++;
153
154 if (inbuff[i] == '-')
155 {
156 ep_square = 0;
157 }
158 else
159 {
160 ep_file = inbuff[i++];
161 ep_rank = inbuff[i++];
162
163 norm_file = ep_file - converterf;
164 norm_rank = ep_rank - converterr;
165
166 ep_square = ((norm_rank * 12) + 26) + (norm_file);
167 }
168 }
169 else if (stage == 4)
170 {
171 /* ignore this for now */
172 }
173 else if (stage == 5)
174 {
175 /* ignore this for now */
176 }
177 else if (stage == 6)
178 {
179 /* ignore this for now */
180 }
181 };
182
183 i++;
184 }
185
186 reset_piece_square();
187 initialize_hash();
188
189 }
190
check_solution(char * inbuff,move_s cmove)191 int check_solution(char *inbuff, move_s cmove)
192 {
193 char san[STR_BUFF];
194
195 comp_to_san(cmove, san);
196
197 // printf("Sjeng's move: %s, EPD line: %s\n", san, strstr(inbuff,"bm"));
198
199 if (strstr(inbuff, "bm") != NULL)
200 {
201 if (strstr(inbuff, san) != NULL)
202 return TRUE;
203 else
204 return FALSE;
205 }
206 else if (strstr(inbuff, "am") != NULL)
207 {
208 if (strstr(inbuff, san) != NULL)
209 return FALSE;
210 else
211 return TRUE;
212 }
213 else
214 printf("No best-move or avoid-move found!");
215
216 return FALSE;
217 }
218
run_epd_testsuite(void)219 void run_epd_testsuite(void)
220 {
221 FILE *testsuite;
222 char readbuff[2000];
223 char testname[FILENAME_MAX];
224 char tempbuff[2000];
225 float elapsed;
226 int nps;
227 long thinktime;
228 move_s comp_move;
229 int tested, found;
230
231 clock_t cpu_start, cpu_end;
232
233 tested = 0;
234 found = 0;
235
236 printf("\nName of EPD testsuite: ");
237 rinput(testname, STR_BUFF, stdin);
238 printf("\nTime per move (s): ");
239 rinput(readbuff, STR_BUFF, stdin);
240 thinktime = atol(readbuff);
241 printf("\n");
242
243 thinktime *= 100;
244
245 testsuite = fopen(testname, "r");
246
247 while (fgets(readbuff, 2000, testsuite) != NULL)
248 {
249 tested++;
250
251 setup_epd_line(readbuff);
252
253 root_to_move = ToMove;
254
255 clear_tt();
256 initialize_hash();
257
258 display_board(stdout, 1);
259
260 forcedwin = FALSE;
261 // pn_time = thinktime;
262 // cpu_start = clock();
263 // proofnumbersearch();
264 // cpu_end = clock();
265 // rdelay(2);
266
267 elapsed = (cpu_end-cpu_start)/(double) CLOCKS_PER_SEC;
268 printf("Time: %f\n", elapsed);
269
270 if (interrupt()) rinput(tempbuff, STR_BUFF, stdin);
271
272 fixed_time = thinktime;
273
274 cpu_start = clock();
275 comp_move = think();
276 cpu_end = clock();
277
278
279 printf ("\nNodes: %ld (%0.2f%% qnodes)\n", nodes,
280 (float) ((float) qnodes / (float) nodes * 100.0));
281
282 elapsed = (cpu_end-cpu_start)/(float) CLOCKS_PER_SEC;
283 nps = (int)((float) nodes/(float) elapsed);
284
285 if (!elapsed)
286 printf ("NPS: N/A\n");
287 else
288 printf ("NPS: %ld\n", (long int) nps);
289
290 printf("ECacheProbes : %ld ECacheHits : %ld HitRate : %f%%\n",
291 ECacheProbes, ECacheHits,
292 ((float)ECacheHits/((float)ECacheProbes+1)) * 100);
293
294 printf("TTStores : %ld TTProbes : %ld TTHits : %ld HitRate : %f%%\n",
295 TTStores, TTProbes, TTHits,
296 ((float)TTHits/((float)TTProbes+1)) * 100);
297
298 printf("NTries : %d NCuts : %d CutRate : %f%% TExt: %d\n",
299 NTries, NCuts, (((float)NCuts*100)/((float)NTries+1)), TExt);
300
301 printf("Check extensions: %ld Razor drops : %ld Razor Material : %ld\n", ext_check, razor_drop, razor_material);
302 printf("EGTB Hits: %d EGTB Probes: %d Efficiency: %3.1f%%\n", EGTBHits, EGTBProbes,
303 (((float)EGTBHits*100)/(float)(EGTBProbes+1)));
304
305 printf("Move ordering : %f%%\n", (((float)FHF*100)/(float)FH+1));
306
307 printf("Material score: %d Eval : %d\n", Material, eval());
308 printf("\n");
309
310 if (!forcedwin)
311 {
312 if(check_solution(readbuff, comp_move))
313 {
314 found++;
315 printf("Solution found.\n");
316 }
317 else
318 {
319 printf("Solution not found.\n");
320 }
321 }
322 else
323 {
324 found++;
325 }
326
327 printf("Solved: %d/%d\n", found, tested);
328
329 };
330
331 printf("\n");
332 };
333
334