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 28void 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 191int 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 219void 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 int32_t 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 = atoi(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)/(float) 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: %d (%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: %d\n", (int32_t) nps); 289 290 printf("ECacheProbes : %d ECacheHits : %d HitRate : %f%%\n", 291 ECacheProbes, ECacheHits, 292 ((float)ECacheHits/((float)ECacheProbes+1)) * 100); 293 294 printf("TTStores : %d TTProbes : %d TTHits : %d 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: %d Razor drops : %d Razor Material : %d\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