/*>>> epdglue.c: glue to connect KnightCap to the EPD Kit routines */ /* Revised: 1998.04.18 */ /* Copyright (C) 1996 by Steven J. Edwards (sje@mv.mv.com) All rights reserved. This code may be freely redistibuted and used by both research and commerical applications. No warranty exists. */ /* The contents of this source file form the programmatic glue between the host program KnightCap and the EPD Kit. Therefore, this file will have to be changed if used with a different host program. Also, the contents of the prototype include file (epdglue.h) may also require modification for a different host. The contents of the other source files in the EPD Kit (epddefs.h, epd.h, and epd.c) should not have to be changed for different hosts. */ /* This file was originally prepared on an Apple Macintosh using the Metrowerks CodeWarrior 6 ANSI C compiler. Tabs are set at every four columns. Further testing and development was performed on a generic PC running Linux 1.2.9 and using the gcc 2.6.3 compiler. */ /* KnightCap includes */ #include "includes.h" #include "knightcap.h" /* EPD Kit definitions (host program independent) */ #include "epddefs.h" /* EPD Kit routine prototypes (host program independent) */ #include "epd.h" /* prototypes for this file (host program dependent) */ #include "epdglue.h" /* KnightCap's board is the transpose of EPD */ #define transpose(sq) ((map_file((sq)) << 3) | map_rank((sq))); static gamptrT default_gamptr; /*--> EGMapFromHostColor: map a color from the host to the EPD style */ static cT EGMapFromHostColor(siT color) { cT c; /* this is an internal glue routine */ /* map from KnightCap's color representation */ if (color == 1) c = c_w; else c = c_b; return (c); } /*--> EGMapToHostColor: map a color to the host from the EPD style */ static siT EGMapToHostColor(cT c) { siT color; /* this is an internal glue routine */ /* map to KnightCap's color representation */ if (c == c_w) color = 1; else color = -1; return (color); } /*--> EGMapFromHostPiece: map a piece from the host to the EPD style */ static pT EGMapFromHostPiece(siT piece) { pT p; /* this is an internal glue routine */ /* map from KnightCap's piece representation */ switch (piece) { case PAWN: p = p_p; break; case KNIGHT: p = p_n; break; case BISHOP: p = p_b; break; case ROOK: p = p_r; break; case QUEEN: p = p_q; break; case KING: p = p_k; break; default: p = p_nil; break; }; return (p); } /*--> EGMapToHostPiece: map a piece to the host from the EPD style */ static siT EGMapToHostPiece(pT p) { siT piece=0; /* this is an internal glue routine */ /* map to KnightCap's piece representation */ switch (p) { case p_p: piece = PAWN; break; case p_n: piece = KNIGHT; break; case p_b: piece = BISHOP; break; case p_r: piece = ROOK; break; case p_q: piece = QUEEN; break; case p_k: piece = KING; break; }; return (piece); } /*--> EGMapFromHostCP: map a color piece from the host to the EPD style */ static cpT EGMapFromHostCP(siT hostcp) { cpT cp=0; /* this is an internal glue routine */ /* map from KnightCap's color-piece representation */ switch (hostcp) { case -QUEEN: cp = cp_bq; break; case -ROOK: cp = cp_br; break; case -BISHOP: cp = cp_bb; break; case -KING: cp = cp_bk; break; case -KNIGHT: cp = cp_bn; break; case -PAWN: cp = cp_bp; break; case NONE: cp = cp_v0; break; case PAWN: cp = cp_wp; break; case KNIGHT: cp = cp_wn; break; case KING: cp = cp_wk; break; case BISHOP: cp = cp_wb; break; case ROOK: cp = cp_wr; break; case QUEEN: cp = cp_wq; break; }; return (cp); } /*--> EGMapToHostCP: map a color piece to the host from the EPD style */ static siT EGMapToHostCP(cpT cp) { siT hostcp=0; /* this is an internal glue routine */ /* map to KnightCap's color-piece representation */ switch (cp) { case cp_wp: hostcp = PAWN; break; case cp_wn: hostcp = KNIGHT; break; case cp_wb: hostcp = BISHOP; break; case cp_wr: hostcp = ROOK; break; case cp_wq: hostcp = QUEEN; break; case cp_wk: hostcp = KING; break; case cp_bp: hostcp = -PAWN; break; case cp_bn: hostcp = -KNIGHT; break; case cp_bb: hostcp = -BISHOP; break; case cp_br: hostcp = -ROOK; break; case cp_bq: hostcp = -QUEEN; break; case cp_bk: hostcp = -KING; break; case cp_v0: hostcp = NONE; break; }; return (hostcp); } /*--> EGMapFromHostSq: map square index from host style */ static sqT EGMapFromHostSq(siT index) { sqT sq; /* this is an internal glue routine */ /* KnightCap's square index is the transpose of the EPD Kit square index */ sq = transpose(index); return (sq); } /*--> EGMapToHostSq: map square index to host style */ static siT EGMapToHostSq(sqT sq) { siT index; /* this is an internal glue routine */ /* KnightCap's square index is the transpose of the EPD Kit square index */ index = transpose(sq); return (index); } /*--> EGMapFromHostScore: map score from host style */ static cpevT EGMapFromHostScore(liT score) { cpevT cpev; liT distance; /* this is an internal EPD glue routine */ /* check for a forced mate */ if (score >= FORCED_WIN) { /* convert forced mate score */ distance = (WIN - score) / 2; cpev = synth_mate(distance); } else if (score <= -FORCED_WIN) { /* convert forced loss score */ distance = (WIN + score) / 2; cpev = synth_loss(distance); } else { /* convert regular score */ cpev = score*100/STATIC_PAWN_VALUE; }; return (cpev); } /*--> EGMapToHostScore: map score to host style */ static etype EGMapToHostScore(cpevT cpev) { liT score; /* this is an internal EPD glue routine */ /* check for a forced mate */ if (forced_mate(cpev)) { /* convert forced mate score */ score = WIN - (etype)(cpev_best-cpev+1); } else if (forced_loss(cpev)) { /* convert forced loss score */ score = -WIN + (etype)(cpev_best+cpev+1); } else { /* convert regular score */ score = ((etype) cpev) * STATIC_PAWN_VALUE/100; }; return (score); } /*--> EGGetIndexedHostPosition: copy from indexed host position */ static void EGGetIndexedHostPosition(Position *b) { sqT sq; rbT rb; cT actc; castT cast; sqT epsq; siT hmvc; siT fmvn; /* this is an internal EPD glue routine */ /* This routine is called from within the EPD glue to copy the host program's current position at the given dpeth into the EPD Kit. Information about the previous EPD Kit current position is lost. */ /* read from the host piece placement */ for (sq = sq_a1; sq <= sq_h8; sq++) rb.rbv[sq] = EGMapFromHostCP(b->board[EGMapToHostSq(sq)]); /* read from the host piece active color */ actc = EGMapFromHostColor(next_to_play(b)); /* read from the host piece castling availability */ cast = 0; if (b->flags & WHITE_CASTLE_LONG) cast |= cf_wq; if (b->flags & WHITE_CASTLE_SHORT) cast |= cf_wk; if (b->flags & BLACK_CASTLE_LONG) cast |= cf_bq; if (b->flags & BLACK_CASTLE_SHORT) cast |= cf_bk; /* read from the host piece en passant target square */ if (b->enpassent == 0) epsq = sq_nil; else epsq = transpose(sq); /* read from the host halfmove clock */ hmvc = b->fifty_count; /* read from the host fullmove number */ fmvn = b->move_num; /* set the EPD current position */ EPDSetCurrentPosition(&rb, actc, cast, epsq, hmvc, fmvn); return; } /*--> EGTBScore: fetch a tablebase score for the indicated position */ nonstatic int EGTBScore(Position *b, etype *scoreptr) { siT flag; cpevT cpev; /* this routine is called from KnightCap at various points in the search */ /* set default return value: score unfound */ flag = 0; *scoreptr = 0; /* copy the indexed host position as the EPD Kit new current position */ EGGetIndexedHostPosition(b); /* perform the probe */ cpev = EPDTBScore(); if (cpev != cpev_wrck) { /* set return value */ flag = 1; /* convert and copy score */ *scoreptr = EGMapToHostScore(cpev); }; return (flag); } /*--> EGInit: one time EPD glue initialization */ nonstatic void EGInit(void) { tbidT tbid; cT c; siT count; static int initialised; if (initialised) return; lprintf(0, "EPD Kit revision date: 1996.04.21\n"); /* call the EPD one time set up code */ EPDInit(); /* set up the default game structure */ default_gamptr = EPDGameOpen(); /* tablebase survey */ count = 0; for (tbid = 0; tbid < tbidL; tbid++) for (c = c_w; c <= c_b; c++) if (EPDTBIsFilePresent(tbid, c)) count++; if (count == 0) { lprintf(0,"No tablebase files found in the %s directory.\n",tb_path); } else { lprintf(0,"%hd tablebase file(s) found in the %s directory.\n", count, tb_path); }; initialised = 1; return; } /*--> EGTerm: one time EPD glue termination */ nonstatic void EGTerm(void) { /* this is called by Option() in option.c */ /* release the default game structure */ if (default_gamptr != NULL) EPDGameClose(default_gamptr); /* call the EPD one time close down code */ EPDTerm(); return; } /*<<< epdglue.c: EOF */