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