1 /*>>> epdglue.c: glue to connect KnightCap to the EPD Kit routines */
2
3 /* Revised: 1998.04.18 */
4
5 /*
6 Copyright (C) 1996 by Steven J. Edwards (sje@mv.mv.com)
7 All rights reserved. This code may be freely redistibuted and used by
8 both research and commerical applications. No warranty exists.
9 */
10
11 /*
12 The contents of this source file form the programmatic glue between
13 the host program KnightCap and the EPD Kit. Therefore, this file will
14 have to be changed if used with a different host program. Also, the
15 contents of the prototype include file (epdglue.h) may also require
16 modification for a different host.
17
18 The contents of the other source files in the EPD Kit (epddefs.h,
19 epd.h, and epd.c) should not have to be changed for different hosts.
20 */
21
22 /*
23 This file was originally prepared on an Apple Macintosh using the
24 Metrowerks CodeWarrior 6 ANSI C compiler. Tabs are set at every
25 four columns. Further testing and development was performed on a
26 generic PC running Linux 1.2.9 and using the gcc 2.6.3 compiler.
27 */
28
29 /* KnightCap includes */
30 #include "includes.h"
31 #include "knightcap.h"
32
33 /* EPD Kit definitions (host program independent) */
34 #include "epddefs.h"
35
36 /* EPD Kit routine prototypes (host program independent) */
37 #include "epd.h"
38
39 /* prototypes for this file (host program dependent) */
40 #include "epdglue.h"
41
42 /* KnightCap's board is the transpose of EPD */
43 #define transpose(sq) ((map_file((sq)) << 3) | map_rank((sq)));
44
45 static gamptrT default_gamptr;
46
47 /*--> EGMapFromHostColor: map a color from the host to the EPD style */
48 static
49 cT
EGMapFromHostColor(siT color)50 EGMapFromHostColor(siT color)
51 {
52 cT c;
53
54 /* this is an internal glue routine */
55
56 /* map from KnightCap's color representation */
57
58 if (color == 1)
59 c = c_w;
60 else
61 c = c_b;
62
63 return (c);
64 }
65
66 /*--> EGMapToHostColor: map a color to the host from the EPD style */
67 static
68 siT
EGMapToHostColor(cT c)69 EGMapToHostColor(cT c)
70 {
71 siT color;
72
73 /* this is an internal glue routine */
74
75 /* map to KnightCap's color representation */
76
77 if (c == c_w)
78 color = 1;
79 else
80 color = -1;
81
82 return (color);
83 }
84
85 /*--> EGMapFromHostPiece: map a piece from the host to the EPD style */
86 static
87 pT
EGMapFromHostPiece(siT piece)88 EGMapFromHostPiece(siT piece)
89 {
90 pT p;
91
92 /* this is an internal glue routine */
93
94 /* map from KnightCap's piece representation */
95
96 switch (piece)
97 {
98 case PAWN:
99 p = p_p;
100 break;
101 case KNIGHT:
102 p = p_n;
103 break;
104 case BISHOP:
105 p = p_b;
106 break;
107 case ROOK:
108 p = p_r;
109 break;
110 case QUEEN:
111 p = p_q;
112 break;
113 case KING:
114 p = p_k;
115 break;
116 default:
117 p = p_nil;
118 break;
119 };
120
121 return (p);
122 }
123
124 /*--> EGMapToHostPiece: map a piece to the host from the EPD style */
125 static
126 siT
EGMapToHostPiece(pT p)127 EGMapToHostPiece(pT p)
128 {
129 siT piece=0;
130
131 /* this is an internal glue routine */
132
133 /* map to KnightCap's piece representation */
134
135 switch (p)
136 {
137 case p_p:
138 piece = PAWN;
139 break;
140 case p_n:
141 piece = KNIGHT;
142 break;
143 case p_b:
144 piece = BISHOP;
145 break;
146 case p_r:
147 piece = ROOK;
148 break;
149 case p_q:
150 piece = QUEEN;
151 break;
152 case p_k:
153 piece = KING;
154 break;
155 };
156
157 return (piece);
158 }
159
160 /*--> EGMapFromHostCP: map a color piece from the host to the EPD style */
161 static
162 cpT
EGMapFromHostCP(siT hostcp)163 EGMapFromHostCP(siT hostcp)
164 {
165 cpT cp=0;
166
167 /* this is an internal glue routine */
168
169 /* map from KnightCap's color-piece representation */
170
171 switch (hostcp)
172 {
173 case -QUEEN:
174 cp = cp_bq;
175 break;
176 case -ROOK:
177 cp = cp_br;
178 break;
179 case -BISHOP:
180 cp = cp_bb;
181 break;
182 case -KING:
183 cp = cp_bk;
184 break;
185 case -KNIGHT:
186 cp = cp_bn;
187 break;
188 case -PAWN:
189 cp = cp_bp;
190 break;
191 case NONE:
192 cp = cp_v0;
193 break;
194 case PAWN:
195 cp = cp_wp;
196 break;
197 case KNIGHT:
198 cp = cp_wn;
199 break;
200 case KING:
201 cp = cp_wk;
202 break;
203 case BISHOP:
204 cp = cp_wb;
205 break;
206 case ROOK:
207 cp = cp_wr;
208 break;
209 case QUEEN:
210 cp = cp_wq;
211 break;
212 };
213
214 return (cp);
215 }
216
217 /*--> EGMapToHostCP: map a color piece to the host from the EPD style */
218 static
219 siT
EGMapToHostCP(cpT cp)220 EGMapToHostCP(cpT cp)
221 {
222 siT hostcp=0;
223
224 /* this is an internal glue routine */
225
226 /* map to KnightCap's color-piece representation */
227
228 switch (cp)
229 {
230 case cp_wp:
231 hostcp = PAWN;
232 break;
233 case cp_wn:
234 hostcp = KNIGHT;
235 break;
236 case cp_wb:
237 hostcp = BISHOP;
238 break;
239 case cp_wr:
240 hostcp = ROOK;
241 break;
242 case cp_wq:
243 hostcp = QUEEN;
244 break;
245 case cp_wk:
246 hostcp = KING;
247 break;
248 case cp_bp:
249 hostcp = -PAWN;
250 break;
251 case cp_bn:
252 hostcp = -KNIGHT;
253 break;
254 case cp_bb:
255 hostcp = -BISHOP;
256 break;
257 case cp_br:
258 hostcp = -ROOK;
259 break;
260 case cp_bq:
261 hostcp = -QUEEN;
262 break;
263 case cp_bk:
264 hostcp = -KING;
265 break;
266 case cp_v0:
267 hostcp = NONE;
268 break;
269 };
270
271 return (hostcp);
272 }
273
274 /*--> EGMapFromHostSq: map square index from host style */
275 static
276 sqT
EGMapFromHostSq(siT index)277 EGMapFromHostSq(siT index)
278 {
279 sqT sq;
280
281 /* this is an internal glue routine */
282
283 /* KnightCap's square index is the transpose of the EPD Kit square index */
284
285 sq = transpose(index);
286
287 return (sq);
288 }
289
290 /*--> EGMapToHostSq: map square index to host style */
291 static
292 siT
EGMapToHostSq(sqT sq)293 EGMapToHostSq(sqT sq)
294 {
295 siT index;
296
297 /* this is an internal glue routine */
298
299 /* KnightCap's square index is the transpose of the EPD Kit square index */
300
301 index = transpose(sq);
302
303 return (index);
304 }
305
306 /*--> EGMapFromHostScore: map score from host style */
307 static
308 cpevT
EGMapFromHostScore(liT score)309 EGMapFromHostScore(liT score)
310 {
311 cpevT cpev;
312 liT distance;
313
314 /* this is an internal EPD glue routine */
315
316 /* check for a forced mate */
317
318 if (score >= FORCED_WIN)
319 {
320 /* convert forced mate score */
321
322 distance = (WIN - score) / 2;
323 cpev = synth_mate(distance);
324 }
325 else
326 if (score <= -FORCED_WIN)
327 {
328 /* convert forced loss score */
329
330 distance = (WIN + score) / 2;
331 cpev = synth_loss(distance);
332 }
333 else
334 {
335 /* convert regular score */
336
337 cpev = score*100/STATIC_PAWN_VALUE;
338 };
339
340 return (cpev);
341 }
342
343 /*--> EGMapToHostScore: map score to host style */
344 static
345 etype
EGMapToHostScore(cpevT cpev)346 EGMapToHostScore(cpevT cpev)
347 {
348 liT score;
349
350 /* this is an internal EPD glue routine */
351
352 /* check for a forced mate */
353
354 if (forced_mate(cpev))
355 {
356 /* convert forced mate score */
357
358 score = WIN - (etype)(cpev_best-cpev+1);
359 }
360 else
361 if (forced_loss(cpev))
362 {
363 /* convert forced loss score */
364
365 score = -WIN + (etype)(cpev_best+cpev+1);
366 }
367 else
368 {
369 /* convert regular score */
370
371 score = ((etype) cpev) * STATIC_PAWN_VALUE/100;
372 };
373
374 return (score);
375 }
376
377
378 /*--> EGGetIndexedHostPosition: copy from indexed host position */
379 static
380 void
EGGetIndexedHostPosition(Position * b)381 EGGetIndexedHostPosition(Position *b)
382 {
383 sqT sq;
384 rbT rb;
385 cT actc;
386 castT cast;
387 sqT epsq;
388 siT hmvc;
389 siT fmvn;
390
391 /* this is an internal EPD glue routine */
392
393 /*
394 This routine is called from within the EPD glue to copy the host program's
395 current position at the given dpeth into the EPD Kit. Information about
396 the previous EPD Kit current position is lost.
397 */
398
399 /* read from the host piece placement */
400
401 for (sq = sq_a1; sq <= sq_h8; sq++)
402 rb.rbv[sq] =
403 EGMapFromHostCP(b->board[EGMapToHostSq(sq)]);
404
405 /* read from the host piece active color */
406
407 actc = EGMapFromHostColor(next_to_play(b));
408
409 /* read from the host piece castling availability */
410
411 cast = 0;
412
413 if (b->flags & WHITE_CASTLE_LONG)
414 cast |= cf_wq;
415 if (b->flags & WHITE_CASTLE_SHORT)
416 cast |= cf_wk;
417 if (b->flags & BLACK_CASTLE_LONG)
418 cast |= cf_bq;
419 if (b->flags & BLACK_CASTLE_SHORT)
420 cast |= cf_bk;
421
422 /* read from the host piece en passant target square */
423
424 if (b->enpassent == 0)
425 epsq = sq_nil;
426 else
427 epsq = transpose(sq);
428
429 /* read from the host halfmove clock */
430
431 hmvc = b->fifty_count;
432
433 /* read from the host fullmove number */
434
435 fmvn = b->move_num;
436
437 /* set the EPD current position */
438
439 EPDSetCurrentPosition(&rb, actc, cast, epsq, hmvc, fmvn);
440
441 return;
442 }
443
444
445 /*--> EGTBScore: fetch a tablebase score for the indicated position */
446 nonstatic
447 int
EGTBScore(Position * b,etype * scoreptr)448 EGTBScore(Position *b, etype *scoreptr)
449 {
450 siT flag;
451 cpevT cpev;
452
453 /* this routine is called from KnightCap at various points in the search */
454
455 /* set default return value: score unfound */
456
457 flag = 0;
458 *scoreptr = 0;
459
460 /* copy the indexed host position as the EPD Kit new current position */
461
462 EGGetIndexedHostPosition(b);
463
464 /* perform the probe */
465
466 cpev = EPDTBScore();
467 if (cpev != cpev_wrck)
468 {
469 /* set return value */
470
471 flag = 1;
472
473 /* convert and copy score */
474
475 *scoreptr = EGMapToHostScore(cpev);
476 };
477
478 return (flag);
479 }
480
481 /*--> EGInit: one time EPD glue initialization */
482 nonstatic
483 void
EGInit(void)484 EGInit(void)
485 {
486 tbidT tbid;
487 cT c;
488 siT count;
489 static int initialised;
490
491 if (initialised)
492 return;
493
494 lprintf(0, "EPD Kit revision date: 1996.04.21\n");
495
496 /* call the EPD one time set up code */
497
498 EPDInit();
499
500 /* set up the default game structure */
501
502 default_gamptr = EPDGameOpen();
503
504 /* tablebase survey */
505
506 count = 0;
507 for (tbid = 0; tbid < tbidL; tbid++)
508 for (c = c_w; c <= c_b; c++)
509 if (EPDTBIsFilePresent(tbid, c))
510 count++;
511
512 if (count == 0)
513 {
514 lprintf(0,"No tablebase files found in the %s directory.\n",tb_path);
515 }
516 else
517 {
518 lprintf(0,"%hd tablebase file(s) found in the %s directory.\n",
519 count, tb_path);
520 };
521
522 initialised = 1;
523 return;
524 }
525
526 /*--> EGTerm: one time EPD glue termination */
527 nonstatic
528 void
EGTerm(void)529 EGTerm(void)
530 {
531 /* this is called by Option() in option.c */
532
533 /* release the default game structure */
534
535 if (default_gamptr != NULL)
536 EPDGameClose(default_gamptr);
537
538 /* call the EPD one time close down code */
539
540 EPDTerm();
541
542 return;
543 }
544
545 /*<<< epdglue.c: EOF */
546