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