home *** CD-ROM | disk | FTP | other *** search
/ Dream 57 / Amiga_Dream_57.iso / Amiga / Jeux / Reflexion / Crafty-15.19.lha / crafty-15.19 / src / epdglue.c < prev    next >
C/C++ Source or Header  |  1998-09-13  |  77KB  |  3,768 lines

  1. /*>>> epdglue.c: glue to connect Crafty to the EPD Kit routines */
  2.  
  3. /* Revised: 1996.04.21 */
  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 Crafty 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. /* system includes */
  30.  
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #if !defined(NT_i386) && !defined(NT_AXP)
  34. #include <unistd.h>
  35. #endif
  36. #include <string.h>
  37. #include <ctype.h>
  38. #include <time.h>
  39. #if defined(NT_i386) || defined(NT_AXP)
  40. #include <process.h>
  41. #endif
  42. /* Crafty includes */
  43.  
  44. #include "chess.h"
  45. #include "data.h"
  46.  
  47. /* EPD Kit definitions (host program independent) */
  48.  
  49. #include "epddefs.h"
  50.  
  51. /* EPD Kit routine prototypes (host program independent) */
  52.  
  53. #include "epd.h"
  54.  
  55. /* prototypes for this file (host program dependent) */
  56.  
  57. #include "epdglue.h"
  58.  
  59. /* EPD glue command type */
  60.  
  61. typedef siT egcommT, *egcommptrT;
  62. #define egcommL 26
  63. #define egcomm_nil (-1)
  64.  
  65. #define egcomm_epdapgn  0 /* append a PGN game to a file */
  66. #define egcomm_epdbfix  1 /* fix file for Bookup import */
  67. #define egcomm_epdcert  2 /* display certain evaluation (if possible) */
  68. #define egcomm_epdcics  3 /* slave to an Internet Chess Server */
  69. #define egcomm_epdcomm  4 /* slave to the Duplex referee program */
  70. #define egcomm_epddpgn  5 /* display the current game in PGN */
  71. #define egcomm_epddsml  6 /* display SAN move list */
  72. #define egcomm_epddstr  7 /* display PGN Seven Tag Roster */
  73. #define egcomm_epddtpv  8 /* display PGN tag pair value */
  74. #define egcomm_epdenum  9 /* enumerate EPD file */
  75. #define egcomm_epdhelp 10 /* display EPD help */
  76. #define egcomm_epdlink 11 /* slave to the Argus referee program */
  77. #define egcomm_epdlpgn 12 /* load a PGN game from a file */
  78. #define egcomm_epdlrec 13 /* load an EPD record form a file */
  79. #define egcomm_epdmore 14 /* more help */
  80. #define egcomm_epdnoop 15 /* no operation */
  81. #define egcomm_epdpfdn 16 /* process file: data normalization */
  82. #define egcomm_epdpfdr 17 /* process file: data repair */
  83. #define egcomm_epdpfga 18 /* process file: general analysis */
  84. #define egcomm_epdpflc 19 /* process file: locate cooks */
  85. #define egcomm_epdpfop 20 /* process file: operation purge */
  86. #define egcomm_epdscor 21 /* score EPD benchmark result file */
  87. #define egcomm_epdshow 22 /* show EPD four fields for current position */
  88. #define egcomm_epdspgn 23 /* save a PGN game to a file */
  89. #define egcomm_epdstpv 24 /* set PGN tag pair value */
  90. #define egcomm_epdtest 25 /* developer testing */
  91.  
  92. /* output text buffer */
  93.  
  94. #define tbufL 256
  95. static char tbufv[tbufL];
  96.  
  97. /* EPD glue command strings */
  98.  
  99. static charptrT egcommstrv[egcommL];
  100.  
  101. /* EPD glue command string descriptions */
  102.  
  103. static charptrT eghelpstrv[egcommL];
  104.  
  105. /* EPD glue command parameter counts (includes command token) */
  106.  
  107. static siT egparmcountv[egcommL];
  108.  
  109. /* the current (default) EPD game structure */
  110.  
  111. static gamptrT default_gamptr;
  112.  
  113. /*--> EGPrint: print a string to the output */
  114. static
  115. void
  116. EGPrint(charptrT s)
  117. {
  118. /* this is an internal EPD glue routine */
  119.  
  120. /*
  121. This routine is provided as an alternative to direct writing to the
  122. standard output.  All EPD glue printing output goes through here.  The
  123. idea is that the host program may have some special requirements for
  124. printing output (like a window display), so a convenient single point
  125. is provided to handle this.
  126.  
  127. Note that there is no corresponding routine for reading from the
  128. standard input because the EPD glue does no interactive reading, except
  129. for a single getchar() call in the epdhelp display pager.
  130. */
  131.  
  132. /* for Crafty, the standard output is used */
  133.  
  134. printf("%s", s);
  135.  
  136. return;
  137. }
  138.  
  139. /*--> EGPrintTB: print the contents of the text buffer */
  140. static
  141. void
  142. EGPrintTB(void)
  143. {
  144. /* this is an internal EPD glue routine */
  145.  
  146. EGPrint(tbufv);
  147.  
  148. return;
  149. }
  150.  
  151. /*--> EGPL: print a string followed by a newline */
  152. static
  153. void
  154. EGPL(charptrT s)
  155. {
  156. /* this is an internal EPD glue routine */
  157.  
  158. EGPrint(s);
  159. EGPrint("\n");
  160.  
  161. return;
  162. }
  163.  
  164. /*--> EGLocateCommand: locate an EPD glue command from a token */
  165. static
  166. egcommT
  167. EGLocateCommand(charptrT s)
  168. {
  169. egcommT egcomm, index;
  170.  
  171. /* this is an internal EPD glue routine */
  172.  
  173. /* set the default return value: no match */
  174.  
  175. egcomm = egcomm_nil;
  176.  
  177. /* scan the EPD glue command string vector */
  178.  
  179. index = 0;
  180. while ((index < egcommL) && (egcomm == egcomm_nil))
  181.     if (strcmp(s, egcommstrv[index]) == 0)
  182.         egcomm = index;
  183.     else
  184.         index++;
  185.  
  186. return (egcomm);
  187. }
  188.  
  189. /*--> EGMapFromHostColor: map a color from the host to the EPD style */
  190. static
  191. cT
  192. EGMapFromHostColor(siT color)
  193. {
  194. cT c;
  195.  
  196. /* this is an internal glue routine */
  197.  
  198. /* map from Crafty's color representation */
  199.  
  200. if (color == 1)
  201.     c = c_w;
  202. else
  203.     c = c_b;
  204.  
  205. return (c);
  206. }
  207.  
  208. /*--> EGMapToHostColor: map a color to the host from the EPD style */
  209. static
  210. siT
  211. EGMapToHostColor(cT c)
  212. {
  213. siT color;
  214.  
  215. /* this is an internal glue routine */
  216.  
  217. /* map to Crafty's color representation */
  218.  
  219. if (c == c_w)
  220.     color = 1;
  221. else
  222.     color = 0;
  223.  
  224. return (color);
  225. }
  226.  
  227. /*--> EGMapToHostPiece: map a piece to the host from the EPD style */
  228. static
  229. siT
  230. EGMapToHostPiece(pT p)
  231. {
  232. siT piece=0;
  233.  
  234. /* this is an internal glue routine */
  235.  
  236. /* map to Crafty's piece representation */
  237.  
  238. switch (p)
  239.     {
  240.     case p_p:
  241.         piece = pawn;
  242.         break;
  243.     case p_n:
  244.         piece = knight;
  245.         break;
  246.     case p_b:
  247.         piece = bishop;
  248.         break;
  249.     case p_r:
  250.         piece = rook;
  251.         break;
  252.     case p_q:
  253.         piece = queen;
  254.         break;
  255.     case p_k:
  256.         piece = king;
  257.         break;
  258.     };
  259.  
  260. return (piece);
  261. }
  262.  
  263. /*--> EGMapFromHostCP: map a color piece from the host to the EPD style */
  264. static
  265. cpT
  266. EGMapFromHostCP(siT hostcp)
  267. {
  268. cpT cp=0;
  269.  
  270. /* this is an internal glue routine */
  271.  
  272. /* map from Crafty's color-piece representation */
  273.  
  274. switch (hostcp)
  275.     {
  276.     case -queen:
  277.         cp = cp_bq;
  278.         break;
  279.     case -rook:
  280.         cp = cp_br;
  281.         break;
  282.     case -bishop:
  283.         cp = cp_bb;
  284.         break;
  285.     case -king:
  286.         cp = cp_bk;
  287.         break;
  288.     case -knight:
  289.         cp = cp_bn;
  290.         break;
  291.     case -pawn:
  292.         cp = cp_bp;
  293.         break;
  294.     case 0:
  295.         cp = cp_v0;
  296.         break;
  297.     case pawn:
  298.         cp = cp_wp;
  299.         break;
  300.     case knight:
  301.         cp = cp_wn;
  302.         break;
  303.     case king:
  304.         cp = cp_wk;
  305.         break;
  306.     case bishop:
  307.         cp = cp_wb;
  308.         break;
  309.     case rook:
  310.         cp = cp_wr;
  311.         break;
  312.     case queen:
  313.         cp = cp_wq;
  314.         break;
  315.     };
  316.  
  317. return (cp);
  318. }
  319.  
  320. /*--> EGMapToHostCP: map a color piece to the host from the EPD style */
  321. static
  322. siT
  323. EGMapToHostCP(cpT cp)
  324. {
  325. siT hostcp=0;
  326.  
  327. /* this is an internal glue routine */
  328.  
  329. /* map to Crafty's color-piece representation */
  330.  
  331. switch (cp)
  332.     {
  333.     case cp_wp:
  334.         hostcp = pawn;
  335.         break;
  336.     case cp_wn:
  337.         hostcp = knight;
  338.         break;
  339.     case cp_wb:
  340.         hostcp = bishop;
  341.         break;
  342.     case cp_wr:
  343.         hostcp = rook;
  344.         break;
  345.     case cp_wq:
  346.         hostcp = queen;
  347.         break;
  348.     case cp_wk:
  349.         hostcp = king;
  350.         break;
  351.     case cp_bp:
  352.         hostcp = -pawn;
  353.         break;
  354.     case cp_bn:
  355.         hostcp = -knight;
  356.         break;
  357.     case cp_bb:
  358.         hostcp = -bishop;
  359.         break;
  360.     case cp_br:
  361.         hostcp = -rook;
  362.         break;
  363.     case cp_bq:
  364.         hostcp = -queen;
  365.         break;
  366.     case cp_bk:
  367.         hostcp = -king;
  368.         break;
  369.     case cp_v0:
  370.         hostcp = 0;
  371.         break;
  372.     };
  373.  
  374. return (hostcp);
  375. }
  376.  
  377. /*--> EGMapFromHostSq: map square index from host style */
  378. static
  379. sqT
  380. EGMapFromHostSq(siT index)
  381. {
  382. sqT sq;
  383.  
  384. /* this is an internal glue routine */
  385.  
  386. /* Crafty's square index is the same as the EPD Kit square index */
  387.  
  388. sq = index;
  389.  
  390. return (sq);
  391. }
  392.  
  393. /*--> EGMapToHostSq: map square index to host style */
  394. static
  395. siT
  396. EGMapToHostSq(sqT sq)
  397. {
  398. siT index;
  399.  
  400. /* this is an internal glue routine */
  401.  
  402. /* Crafty's square index is the same as the EPD Kit square index */
  403.  
  404. index = sq;
  405.  
  406. return (index);
  407. }
  408.  
  409. /*--> EGMapFromHostScore: map score from host style */
  410. static
  411. cpevT
  412. EGMapFromHostScore(liT score)
  413. {
  414. cpevT cpev;
  415. liT distance;
  416.  
  417. /* this is an internal EPD glue routine */
  418.  
  419. /* check for a forced mate */
  420.  
  421. if (score >= (MATE - MAXPLY))
  422.     {
  423.     /* convert forced mate score */
  424.  
  425.     distance = (MATE - score) / 2;
  426.     cpev = synth_mate(distance);
  427.     }
  428. else
  429.     if (score <= (MAXPLY - MATE))
  430.         {
  431.         /* convert forced loss score */
  432.  
  433.         distance = (MATE + score) / 2;
  434.         cpev = synth_loss(distance);
  435.         }
  436.     else
  437.         {
  438.         /* convert regular score */
  439.  
  440.         cpev = score;
  441.         };
  442.  
  443. return (cpev);
  444. }
  445.  
  446. /*--> EGMapToHostScore: map score to host style */
  447. static
  448. liT
  449. EGMapToHostScore(cpevT cpev)
  450. {
  451. liT score;
  452.  
  453. /* this is an internal EPD glue routine */
  454.  
  455. /* check for a forced mate */
  456.  
  457. if (forced_mate(cpev))
  458.     {
  459.     /* convert forced mate score */
  460.  
  461.     score = MATE - (cpev_best-cpev+1);
  462.     }
  463. else
  464.     if (forced_loss(cpev))
  465.         {
  466.         /* convert forced loss score */
  467.  
  468.         score = -MATE + (cpev_best+cpev+1);
  469.         }
  470.     else
  471.         {
  472.         /* convert regular score */
  473.  
  474.         score = ((liT) cpev);
  475.         };
  476.  
  477. return (score);
  478. }
  479.  
  480. /*--> EGMapFromHostMove: map move from host style to EPD style */
  481. static
  482. mT
  483. EGMapFromHostMove(liT move)
  484. {
  485. mT m;
  486. siT flag;
  487.  
  488. /* this is an internal EPD glue routine */
  489.  
  490. /* the EPD current position must be properly set */
  491.  
  492. m.m_flag = 0;
  493. m.m_frsq = EGMapFromHostSq((siT)From(move));
  494. m.m_tosq = EGMapFromHostSq((siT)To(move));
  495. m.m_frcp = EPDFetchCP(m.m_frsq);
  496. m.m_tocp = EPDFetchCP(m.m_tosq);
  497.  
  498. /* determine special case move indication */
  499.  
  500. flag = 0;
  501.  
  502. if (!flag)
  503.     if ((m.m_frcp == cp_wk) &&
  504.         (m.m_frsq == sq_e1) && (m.m_tosq == sq_g1))
  505.         {
  506.         m.m_scmv = scmv_cks;
  507.         flag = 1;
  508.         };
  509.  
  510. if (!flag)
  511.     if ((m.m_frcp == cp_bk) &&
  512.         (m.m_frsq == sq_e8) && (m.m_tosq == sq_g8))
  513.         {
  514.         m.m_scmv = scmv_cks;
  515.         flag = 1;
  516.         };
  517.  
  518. if (!flag)
  519.     if ((m.m_frcp == cp_wk) &&
  520.         (m.m_frsq == sq_e1) && (m.m_tosq == sq_c1))
  521.         {
  522.         m.m_scmv = scmv_cqs;
  523.         flag = 1;
  524.         };
  525.  
  526. if (!flag)
  527.     if ((m.m_frcp == cp_bk) &&
  528.         (m.m_frsq == sq_e8) && (m.m_tosq == sq_c8))
  529.         {
  530.         m.m_scmv = scmv_cqs;
  531.         flag = 1;
  532.         };
  533.  
  534. if (!flag)
  535.     if ((m.m_frcp == cp_wp) && (m.m_tosq == EPDFetchEPSQ()))
  536.         {
  537.         m.m_scmv = scmv_epc;
  538.         flag = 1;
  539.         };
  540.  
  541. if (!flag)
  542.     if ((m.m_frcp == cp_bp) && (m.m_tosq == EPDFetchEPSQ()))
  543.         {
  544.         m.m_scmv = scmv_epc;
  545.         flag = 1;
  546.         };
  547.  
  548. if (!flag)
  549.     if (Promote(move) != 0)
  550.         {
  551.         switch (Promote(move))
  552.             {
  553.             case knight:
  554.                 m.m_scmv = scmv_ppn;
  555.                 break;
  556.             case bishop:
  557.                 m.m_scmv = scmv_ppb;
  558.                 break;
  559.             case rook:
  560.                 m.m_scmv = scmv_ppr;
  561.                 break;
  562.             case queen:
  563.                 m.m_scmv = scmv_ppq;
  564.                 break;
  565.             };
  566.         flag = 1;
  567.         };
  568.  
  569. if (!flag)
  570.     m.m_scmv = scmv_reg;
  571.  
  572. return (m);
  573. }
  574.  
  575. /*--> EGMapToHostMove: map move to host style from EPD style */
  576. static
  577. liT
  578. EGMapToHostMove(mT m)
  579. {
  580. liT move;
  581.  
  582. /* this is an internal EPD glue routine */
  583.  
  584. /* the EPD current position must be properly set */
  585.  
  586. move = 0;
  587.  
  588. move |= EGMapToHostSq(m.m_frsq);
  589. move |= EGMapToHostSq(m.m_tosq) << 6;
  590. move |= EGMapToHostPiece(EPDPieceFromCP(m.m_frcp)) << 12;
  591.  
  592. if (m.m_tocp != cp_v0)
  593.     move |= EGMapToHostPiece(EPDPieceFromCP(m.m_tocp)) << 15;
  594.  
  595. switch (m.m_scmv)
  596.     {
  597.     case scmv_epc:
  598.         move |= pawn << 15;
  599.         break;
  600.     case scmv_ppn:
  601.         move |= knight << 18;
  602.         break;
  603.     case scmv_ppb:
  604.         move |= bishop << 18;
  605.         break;
  606.     case scmv_ppr:
  607.         move |= rook << 18;
  608.         break;
  609.     case scmv_ppq:
  610.         move |= queen << 18;
  611.         break;
  612.     default:
  613.         break;
  614.     };
  615.  
  616. return (move);
  617. }
  618.  
  619. /*--> EGGetIndexedHostPosition: copy from indexed host position */
  620. static
  621. void
  622. EGGetIndexedHostPosition(TREE *tree, siT posdex, int active)
  623. {
  624. sqT sq;
  625. rbT rb;
  626. cT actc;
  627. castT cast;
  628. sqT epsq;
  629. siT hmvc;
  630. siT fmvn;
  631.  
  632. /* this is an internal EPD glue routine */
  633.  
  634. /*
  635. This routine is called from within the EPD glue to copy the host program's
  636. current position at the given dpeth into the EPD Kit.  Information about
  637. the previous EPD Kit current position is lost.
  638. */
  639.  
  640. /* read from the host piece placement */
  641.  
  642. for (sq = sq_a1; sq <= sq_h8; sq++)
  643.     rb.rbv[sq] =
  644.         EGMapFromHostCP(tree->pos.board[EGMapToHostSq(sq)]);
  645.  
  646. /* read from the host piece active color */
  647.  
  648. actc = EGMapFromHostColor((siT)active);
  649.  
  650. /* read from the host piece castling availability */
  651.  
  652. cast = 0;
  653.  
  654. switch (tree->position[posdex].w_castle)
  655.     {
  656.     case 0:
  657.         break;
  658.     case 1:
  659.         cast |= cf_wk;
  660.         break;
  661.     case 2:
  662.         cast |= cf_wq;
  663.         break;
  664.     case 3:
  665.         cast |= cf_wk | cf_wq;
  666.         break;
  667.     };
  668.  
  669. switch (tree->position[posdex].b_castle)
  670.     {
  671.     case 0:
  672.         break;
  673.     case 1:
  674.         cast |= cf_bk;
  675.         break;
  676.     case 2:
  677.         cast |= cf_bq;
  678.         break;
  679.     case 3:
  680.         cast |= cf_bk | cf_bq;
  681.         break;
  682.     };
  683.  
  684. /* read from the host piece en passant target square */
  685.  
  686. epsq = sq_nil;
  687. if (tree->position[posdex].enpassant_target != 0)
  688.     {
  689.     sq = sq_a1;
  690.     while ((epsq == sq_nil) && (sq <= sq_h8))
  691.         if (tree->position[posdex].enpassant_target == EGMapToHostSq(sq))
  692.             epsq = sq;
  693.         else
  694.             sq++;
  695.     };
  696.  
  697. /* read from the host halfmove clock */
  698.  
  699. hmvc = tree->position[posdex].rule_50_moves;
  700.  
  701. /* read from the host fullmove number */
  702.  
  703. fmvn = move_number;
  704.  
  705. /* set the EPD current position */
  706.  
  707. EPDSetCurrentPosition(&rb, actc, cast, epsq, hmvc, fmvn);
  708.  
  709. return;
  710. }
  711.  
  712. /*--> EGGetHostPosition: copy from host position to EPD Kit position */
  713. static
  714. void
  715. EGGetHostPosition(void)
  716. {
  717. /* this is an internal EPD glue routine */
  718.  
  719. /*
  720. This routine is called from within the EPD glue to copy the host program's
  721. current position into the EPD Kit.  Information about the previous EPD Kit
  722. current position is lost.
  723. */
  724.  
  725. /* transfer from ply zero host position */
  726.  
  727. EGGetIndexedHostPosition(local[0], 0, wtm);
  728.  
  729. return;
  730. }
  731.  
  732. /*--> EGPutHostPosition: copy from EPD Kit position to host position */
  733. static
  734. void
  735. EGPutHostPosition(void)
  736. {
  737. sqT sq;
  738. rbT rb;
  739. cT actc;
  740. castT cast;
  741. sqT epsq;
  742. siT hmvc;
  743. siT fmvn;
  744. siT index;
  745. TREE *tree=local[0];
  746.  
  747. /* this is an internal EPD glue routine */
  748.  
  749. /*
  750. This routine is called from within the EPD glue to copy the EPD Kit's current
  751. position into the host program.  If the previous host program current position
  752. is different from the new position, then information about the previous host
  753. program current position is lost.  This means that the host program preserves
  754. history information if and only if such preservation is appropriate.
  755.  
  756. Actually, the host position data is completely overwritten, so the above
  757. comment is temporarily false, but will be true as developement proceeds.
  758. */
  759.  
  760. /* fetch the EPD current position data items */
  761.  
  762. rb = *EPDFetchBoard();
  763. actc = EPDFetchACTC();
  764. cast = EPDFetchCAST();
  765. epsq = EPDFetchEPSQ();
  766. hmvc = EPDFetchHMVC();
  767. fmvn = EPDFetchFMVN();
  768.  
  769. /* copy the board into the host board */
  770.  
  771. for (sq = sq_a1; sq <= sq_h8; sq++)
  772.     tree->pos.board[EGMapToHostSq(sq)] = EGMapToHostCP(rb.rbv[sq]);
  773.  
  774. /* copy the active color */
  775.  
  776. wtm = EGMapToHostColor(actc);
  777.  
  778. /* copy the castling availibility */
  779.  
  780. tree->position[0].w_castle = 0;
  781. if (cast & cf_wk)
  782.     tree->position[0].w_castle += 1;
  783. if (cast & cf_wq)
  784.     tree->position[0].w_castle += 2;
  785.  
  786. tree->position[0].b_castle = 0;
  787. if (cast & cf_bk)
  788.     tree->position[0].b_castle += 1;
  789. if (cast & cf_bq)
  790.     tree->position[0].b_castle += 2;
  791.  
  792. /* copy the en passant target square */
  793.  
  794. if (epsq == sq_nil)
  795.     tree->position[0].enpassant_target = 0;
  796. else
  797.     tree->position[0].enpassant_target = EGMapToHostSq(epsq);
  798.  
  799. /* copy the halfmove clock */
  800.  
  801. tree->position[0].rule_50_moves = hmvc;
  802.  
  803. /* copy the fullmove number */
  804.  
  805. move_number = fmvn;
  806.  
  807. /* set secondary host data items */
  808.  
  809. SetChessBitBoards(&tree->position[0]);
  810.  
  811. tree->rephead_w=tree->replist_w;
  812. tree->rephead_b=tree->replist_b;
  813. moves_out_of_book = 0;
  814. last_mate_score = 0;
  815.  
  816. /* clear the host history */
  817.  
  818. for (index = 0; index < (sqL * sqL); index++)
  819.     history_w[index] = history_b[index] = 0;
  820.  
  821. /* clear the host killer information */
  822.  
  823. for (index = 0; index < MAXPLY; index++) {
  824.   tree->killer_move1[index] = 0;
  825.   tree->killer_move2[index] = 0;
  826. }
  827.  
  828. /* clear miscellaneous host items */
  829.  
  830. ponder_move = 0;
  831. last_pv.path_iteration_depth = 0;
  832. last_pv.path_length = 0;
  833. over = 0;
  834.  
  835. return;
  836. }
  837.  
  838. /*--> EGEncodeHostHistory: generate a string from host move history */
  839. static
  840. charptrT
  841. EGEncodeHostHistory(void)
  842. {
  843. charptrT sptr;
  844. gamptrT gamptr;
  845. pgnstrT pgnstr;
  846. mptrT mptr;
  847. siT flag;
  848. siT ch=0;
  849. charptrT s;
  850. mT m;
  851.  
  852. /* this works only for games starting form the initial position */
  853.  
  854. /* set default return value: failure */
  855.  
  856. sptr = NULL;
  857.  
  858. /* set okay  */
  859.  
  860. flag = 1;
  861.  
  862. /* reset the EPD current position */
  863.  
  864. EPDReset();
  865.  
  866. /* make sure the host history file exists */
  867.  
  868. if (history_file == NULL)
  869.     flag = 0;
  870. else
  871.     {
  872.     rewind(history_file);
  873.     ch = fgetc(history_file);
  874.     };
  875.  
  876. /* open a game structure */
  877.  
  878. gamptr = EPDGameOpen();
  879.  
  880. /* copy tag data from default game structure */
  881.  
  882. if (default_gamptr != NULL)
  883.     for (pgnstr = 0; pgnstr < pgnstrL; pgnstr++)
  884.         EPDPGNPutSTR(gamptr, pgnstr,
  885.             EPDPGNGetSTR(default_gamptr, pgnstr));
  886.  
  887. /* copy GTIM from default game structure */
  888.  
  889. if (default_gamptr != NULL)
  890.     EPDPutGTIM(gamptr, EPDGetGTIM(default_gamptr));
  891.  
  892. /* read the host history file */
  893.  
  894. while (flag && (ch != EOF))
  895.     {
  896.     /* skip whitespace */
  897.  
  898.     while ((ch != EOF) && isspace(ch))
  899.         ch = fgetc(history_file);
  900.  
  901.     /* if not EOF, then construct a move */
  902.  
  903.     if (ch != EOF)
  904.         {
  905.         /* attach the first character */
  906.  
  907.         s = EPDStringGrab("");
  908.         s = EPDStringAppendChar(s, (char)ch);
  909.         ch = fgetc(history_file);
  910.  
  911.         /* attach the remaining characters */
  912.  
  913.         while ((ch != EOF) && !isspace(ch))
  914.             {
  915.             s = EPDStringAppendChar(s, (char)ch);
  916.             ch = fgetc(history_file);
  917.             };
  918.  
  919.         /* match the move */
  920.  
  921.         EPDGenMoves();
  922.         mptr = EPDSANDecodeAux(s, 0);
  923.         if (mptr == NULL)
  924.             flag = 0;
  925.         else
  926.             {
  927.             /* execute the move */
  928.  
  929.             m = *mptr;
  930.             EPDGameAppendMove(gamptr, &m);
  931.             EPDExecuteUpdate(&m);
  932.             EPDCollapse();
  933.             };
  934.  
  935.         /* release move buffer storage */
  936.  
  937.         EPDMemoryFree(s);
  938.         };
  939.     };
  940.  
  941. /* construct the string representation of the game */
  942.  
  943. if (flag)
  944.     sptr = EPDPGNHistory(gamptr);
  945.  
  946. /* clean up if there was a problem */
  947.  
  948. if (!flag)
  949.     if (sptr != NULL)
  950.         {
  951.         EPDMemoryFree(sptr);
  952.         sptr = NULL;
  953.         };
  954.  
  955. /* close the game structure */
  956.  
  957. EPDGameClose(gamptr);
  958.  
  959. return (sptr);
  960. }
  961.  
  962. /*--> EGIterate: wrapper function for host Iterate() call */
  963. static
  964. int
  965. EGIterate(siT wtm_flag, siT think_flag)
  966. {
  967. int value;
  968. int move;
  969. mptrT mptr;
  970. mT m;
  971. epdptrT epdptr;
  972. TREE *tree=local[0];
  973.  
  974. /* if there is only one move, then select it without search */
  975.  
  976. EPDGenMoves();
  977. if (EPDFetchMoveCount() == 1)
  978.     {
  979.     /* only one move, bypass Iterate() */
  980.  
  981.     mptr = EPDFetchMove(0);
  982.     m = *mptr;
  983.     move = EGMapToHostMove(m);
  984.  
  985.     /* set Iterate() score result */
  986.  
  987.     if (m.m_flag & mf_chmt)
  988.         value = EGMapToHostScore(synth_mate(1));
  989.     else
  990.         value = EGMapToHostScore(cpev_draw);
  991.  
  992.     /* set Iterate() result variables */
  993.  
  994.     tree->pv[0].path_hashed = 0;
  995.     tree->pv[0].path_length = 1;
  996.     tree->pv[0].path_iteration_depth = 1;
  997.     tree->pv[0].path[1] = move;
  998.     }
  999. else
  1000.     {
  1001.     /* save current kit position */
  1002.  
  1003.     epdptr = EPDGetCurrentPosition();
  1004.  
  1005.     /* more than one move, execute regular search */
  1006.  
  1007.     value = Iterate(wtm_flag, think_flag, 0);
  1008.  
  1009.     /* restore kit position */
  1010.  
  1011.     EPDRealize(epdptr);
  1012.     EPDReleaseEPD(epdptr);
  1013.     EPDGenMoves();
  1014.     };
  1015.  
  1016. last_pv = tree->pv[0];
  1017. last_value = value;
  1018.  
  1019. return (value);
  1020. }
  1021.  
  1022. /*--> EGCommHandler: callback routine for handling Duplex events */
  1023. static
  1024. epdptrT
  1025. EGCommHandler(epdptrT epdptr0, siptrT flagptr)
  1026. {
  1027. epdptrT epdptr1;
  1028. eopptrT eopptr;
  1029. charptrT s;
  1030. fptrT fptr;
  1031. mptrT mptr;
  1032. mT m;
  1033. sanT san;
  1034. int move;
  1035. int value;
  1036. char tv[tL];
  1037. TREE *tree=local[0];
  1038.  
  1039. /* set flag: no errors (so far) */
  1040.  
  1041. *flagptr = 1;
  1042.  
  1043. /* clear result */
  1044.  
  1045. epdptr1 = NULL;
  1046.  
  1047. /* process according to input referee command */
  1048.  
  1049. switch (EPDExtractRefcomIndex(epdptr0))
  1050.     {
  1051.     case refcom_conclude:
  1052.  
  1053.         /* end of game */
  1054.  
  1055.         s = EPDPGNHistory(default_gamptr);
  1056.         if (s == NULL)
  1057.             *flagptr = 0;
  1058.         else
  1059.             {
  1060.             /* append game to PGN output file */
  1061.  
  1062.             sprintf(tv, "c%05hd.pgn", ((siT) getpid()));
  1063.             fptr = fopen(tv, "a");
  1064.             if (fptr == NULL)
  1065.                 *flagptr = 0;
  1066.             else
  1067.                 {
  1068.                 fprintf(fptr, "%s", s);
  1069.                 fclose(fptr);
  1070.                 };
  1071.             EPDMemoryFree(s);
  1072.             };
  1073.  
  1074.         /* clean up and remove the temporary history file */
  1075.  
  1076.         if (history_file != NULL)
  1077.             {
  1078.             fclose(history_file);
  1079.             history_file = NULL;
  1080.             };
  1081.         sprintf(tv, "h%05hd.pml", ((siT) getpid()));
  1082.         remove(tv);
  1083.  
  1084.         /* close the game structure */
  1085.  
  1086.         if (default_gamptr != NULL)
  1087.             {
  1088.             EPDGameClose(default_gamptr);
  1089.             default_gamptr = NULL;
  1090.             };
  1091.  
  1092.         break;
  1093.  
  1094.     case refcom_disconnect:
  1095.  
  1096.         /* channel shutdown */
  1097.  
  1098.         /* clean up and remove the temporary history file */
  1099.  
  1100.         if (history_file != NULL)
  1101.             {
  1102.             fclose(history_file);
  1103.             history_file = NULL;
  1104.             };
  1105.         sprintf(tv, "h%05hd.pml", ((siT) getpid()));
  1106.         remove(tv);
  1107.  
  1108.         /* ensure game structure is closed */
  1109.  
  1110.         if (default_gamptr != NULL)
  1111.             {
  1112.             EPDGameClose(default_gamptr);
  1113.             default_gamptr = NULL;
  1114.             };
  1115.  
  1116.         break;
  1117.  
  1118.     case refcom_execute:
  1119.  
  1120.         /* execute the supplied move */
  1121.  
  1122.         eopptr = EPDLocateEOPCode(epdptr0, epdso_sm);
  1123.         move = InputMove(tree,eopptr->eop_headeov->eov_str, 0, wtm, 0, 0);
  1124.         fseek(history_file,
  1125.             ((((move_number - 1) * 2) + 1 - wtm) * 10), SEEK_SET);
  1126.         fprintf(history_file, "%9s\n", eopptr->eop_headeov->eov_str);
  1127.         MakeMoveRoot(tree,move, wtm);
  1128.         wtm = ChangeSide(wtm);
  1129.         if (wtm)
  1130.             move_number++;
  1131.  
  1132.         /* execute the move in the EPD Kit */
  1133.  
  1134.         EPDGenMoves();
  1135.         mptr = EPDSANDecodeAux(eopptr->eop_headeov->eov_str, 0);
  1136.         m = *mptr;
  1137.         EPDGameAppendMove(default_gamptr, &m);
  1138.         EPDExecuteUpdate(&m);
  1139.         EPDCollapse();
  1140.  
  1141.         break;
  1142.  
  1143.     case refcom_fault:
  1144.  
  1145.         /* a problem occurred */
  1146.  
  1147.         EGPL("EPDCommHandler: refcom fault");
  1148.  
  1149.         *flagptr = 0;
  1150.  
  1151.         break;
  1152.  
  1153.     case refcom_inform:
  1154.  
  1155.         /* process incidental information */
  1156.  
  1157.         EPDCopyOutPTP(default_gamptr, epdptr0);
  1158.  
  1159.         /* update the current game termination marker */
  1160.  
  1161.         s = EPDPGNGetSTR(default_gamptr, pgnstr_result);
  1162.         if ((s == NULL) || (strcmp(s, "*") == 0))
  1163.             EPDPutGTIM(default_gamptr, gtim_u);
  1164.         else
  1165.             if (strcmp(s, "1-0") == 0)
  1166.                 EPDPutGTIM(default_gamptr, gtim_w);
  1167.             else
  1168.                 if (strcmp(s, "0-1") == 0)
  1169.                     EPDPutGTIM(default_gamptr, gtim_b);
  1170.                 else
  1171.                     if (strcmp(s, "1/2-1/2") == 0)
  1172.                         EPDPutGTIM(default_gamptr, gtim_d);
  1173.  
  1174.         break;
  1175.  
  1176.     case refcom_respond:
  1177.  
  1178.         /* execute the supplied move (if any) */
  1179.  
  1180.         eopptr = EPDLocateEOPCode(epdptr0, epdso_sm);
  1181.         if (eopptr != NULL)
  1182.             {
  1183.             move = InputMove(tree,eopptr->eop_headeov->eov_str, 0, wtm, 0, 0);
  1184.             fseek(history_file,
  1185.                 ((((move_number - 1) * 2) + 1 - wtm) * 10), SEEK_SET);
  1186.             fprintf(history_file, "%9s\n", eopptr->eop_headeov->eov_str);
  1187.             MakeMoveRoot(tree,move, wtm);
  1188.             wtm = ChangeSide(wtm);
  1189.             if (wtm)
  1190.                 move_number++;
  1191.  
  1192.             /* execute the move in the EPD Kit */
  1193.  
  1194.             EPDGenMoves();
  1195.             mptr = EPDSANDecodeAux(eopptr->eop_headeov->eov_str, 0);
  1196.             m = *mptr;
  1197.             EPDGameAppendMove(default_gamptr, &m);
  1198.             EPDExecuteUpdate(&m);
  1199.             EPDCollapse();
  1200.             };
  1201.  
  1202.         /* calculate move + respond */
  1203.  
  1204.         EPDGenMoves();
  1205.         if (EPDFetchMoveCount() > 0)
  1206.             {
  1207.             /* at least one move exists, set up for search */
  1208.  
  1209.             ponder_move = 0;
  1210.             thinking = 1;
  1211.             last_pv.path_iteration_depth = 0;
  1212.             last_pv.path_length = 0;
  1213.             tree->position[1] = tree->position[0];
  1214.  
  1215.             /* search */
  1216.  
  1217.             value = EGIterate((siT)wtm, (siT)think);
  1218.  
  1219.             /* process search result */
  1220.  
  1221.             strcpy(tv, OutputMove(tree,last_pv.path[1], 0, wtm));
  1222.             move = last_pv.path[1];
  1223.  
  1224.             /* locate SAN move */
  1225.  
  1226.             mptr = EPDSANDecodeAux(tv, 0);
  1227.             m = *mptr;
  1228.             EPDSANEncode(&m, san);
  1229.  
  1230.             /* output to temporary history file */
  1231.  
  1232.             fseek(history_file,
  1233.                 ((((move_number - 1) * 2) + 1 - wtm) * 10), SEEK_SET);
  1234.             fprintf(history_file, "%9s\n", san);
  1235.  
  1236.             /* update host position */
  1237.  
  1238.             MakeMoveRoot(tree,move, wtm);
  1239.             wtm = ChangeSide(wtm);
  1240.             if (wtm)
  1241.                 move_number++;
  1242.  
  1243.             /* create reply EPD structure */
  1244.  
  1245.             epdptr1 = EPDGetCurrentPosition();
  1246.  
  1247.             /* add in referee request */
  1248.  
  1249.             EPDAddOpSym(epdptr1, epdso_refreq, EPDFetchRefreqStr(refreq_reply));
  1250.  
  1251.             /* add in supplied move */
  1252.  
  1253.             EPDAddOpSym(epdptr1, epdso_sm, san);
  1254.  
  1255.             /* execute the move in the EPD Kit */
  1256.  
  1257.             mptr = EPDSANDecodeAux(san, 0);
  1258.             m = *mptr;
  1259.             EPDGameAppendMove(default_gamptr, &m);
  1260.             EPDExecuteUpdate(&m);
  1261.             EPDCollapse();
  1262.             }
  1263.         else
  1264.             {
  1265.             /* no moves exist, so no move response possible */
  1266.  
  1267.             epdptr1 = EPDGetCurrentPosition();
  1268.             eopptr = EPDCreateEOPCode(epdso_refreq);
  1269.             EPDAppendEOV(eopptr,
  1270.                 EPDCreateEOVSym(EPDFetchRefreqStr(refreq_reply)));
  1271.             EPDAppendEOP(epdptr1, eopptr);
  1272.             };
  1273.  
  1274.         break;
  1275.  
  1276.     case refcom_reset:
  1277.  
  1278.         /* reset EPD Kit */
  1279.  
  1280.         EPDReset();
  1281.  
  1282.         /* reset host for a new game */
  1283.  
  1284.         ponder = 0;
  1285.         ponder_move = 0;
  1286.  
  1287.         last_pv.path_iteration_depth = 0;
  1288.         last_pv.path_length = 0;
  1289.  
  1290.         InitializeChessBoard(&tree->position[0]);
  1291.         InitializeHashTables();
  1292.  
  1293.         wtm = 1;
  1294.         move_number = 1;
  1295.  
  1296.         /* open the temporary history file */
  1297.  
  1298.         if (history_file != NULL)
  1299.             {
  1300.             fclose(history_file);
  1301.             history_file = NULL;
  1302.             };
  1303.         sprintf(tv, "h%05hd.pml", ((siT) getpid()));
  1304.         remove(tv);
  1305.         history_file = fopen(tv, "w+");
  1306.  
  1307.         /* open the current game structure */
  1308.  
  1309.         if (default_gamptr != NULL)
  1310.             EPDGameClose(default_gamptr);
  1311.         default_gamptr = EPDGameOpen();
  1312.  
  1313.         break;
  1314.  
  1315.     case refcom_nil:
  1316.         *flagptr = 0;
  1317.         break;
  1318.     };
  1319.  
  1320. /* clean up if there was a problem */
  1321.  
  1322. if (!(*flagptr))
  1323.     if (epdptr1 != NULL)
  1324.         {
  1325.         EPDReleaseEPD(epdptr1);
  1326.         epdptr1 = NULL;
  1327.         };
  1328.  
  1329. return (epdptr1);
  1330. }
  1331.  
  1332. /*--> EGTBScore: fetch a tablebase score for the indicated position */
  1333. nonstatic
  1334. int
  1335. EGTBScore(TREE *tree, int posdex, int active, int *scoreptr)
  1336. {
  1337. siT flag;
  1338. cpevT cpev;
  1339.  
  1340. /* this routine is called from Crafty at various points in the search */
  1341.  
  1342. /* set default return value: score unfound */
  1343.  
  1344. flag = 0;
  1345. *scoreptr = 0;
  1346.  
  1347. /* copy the indexed host position as the EPD Kit new current position */
  1348.  
  1349. EGGetIndexedHostPosition(tree, (siT)posdex, active);
  1350.  
  1351. /* perform the probe */
  1352.  
  1353. cpev = EPDTBScore();
  1354. if (cpev != cpev_wrck)
  1355.     {
  1356.     /* set return value */
  1357.  
  1358.     flag = 1;
  1359.  
  1360.     /* convert and copy score */
  1361.  
  1362.     *scoreptr = EGMapToHostScore(cpev);
  1363.     };
  1364.  
  1365. return (flag);
  1366. }
  1367.  
  1368. /*--> EGProcessAPGN: process the EG command epdapgn */
  1369. static
  1370. siT
  1371. EGProcessAPGN(void)
  1372. {
  1373. siT flag;
  1374. charptrT s;
  1375. fptrT fptr;
  1376.  
  1377. /* this is an internal EPD glue routine */
  1378.  
  1379. /* set the default return value: success */
  1380.  
  1381. flag = 1;
  1382.  
  1383. /* parameter count check */
  1384.  
  1385. if (EPDTokenCount() != 2)
  1386.     {
  1387.     EGPL("This command takes one parameter.");
  1388.     flag = 0;
  1389.     };
  1390.  
  1391. /* process the epdapgn command */
  1392.  
  1393. if (flag)
  1394.     {
  1395.     s = EGEncodeHostHistory();
  1396.     if (s == NULL)
  1397.         flag = 0;
  1398.     else
  1399.         {
  1400.         fptr = fopen(EPDTokenFetch(1), "a");
  1401.         if (fptr == NULL)
  1402.             flag = 0;
  1403.         else
  1404.             {
  1405.             fprintf(fptr, "%s", s);
  1406.             fclose(fptr);
  1407.             };
  1408.         EPDMemoryFree(s);
  1409.         };
  1410.     };
  1411.  
  1412. return (flag);
  1413. }
  1414.  
  1415. /*--> EGProcessBFIX: process the EG command epdbfix */
  1416. static
  1417. siT
  1418. EGProcessBFIX(void)
  1419. {
  1420. siT flag;
  1421. fptrT fptr0, fptr1;
  1422. eopptrT eopptr;
  1423. epdptrT epdptr, nptr;
  1424. charptrT s;
  1425. char ev[epdL];
  1426.  
  1427. /* this is an internal EPD glue routine */
  1428.  
  1429. /* set the default return value: success */
  1430.  
  1431. flag = 1;
  1432.  
  1433. /* clear the file pointers */
  1434.  
  1435. fptr0 = fptr1 = NULL;
  1436.  
  1437. /* parameter count check */
  1438.  
  1439. if (EPDTokenCount() != 3)
  1440.     {
  1441.     EGPL("This command takes two parameters");
  1442.     flag = 0;
  1443.     };
  1444.  
  1445. /* set up the input file */
  1446.  
  1447. if (flag)
  1448.     {
  1449.     fptr0 = fopen(EPDTokenFetch(1), "r");
  1450.     if (fptr0 == NULL)
  1451.         {
  1452.         sprintf(tbufv, "Can't open %s for reading\n",
  1453.             EPDTokenFetch(1));
  1454.         EGPrintTB();
  1455.         flag = 0;
  1456.         };
  1457.     };
  1458.  
  1459. /* set up the output file */
  1460.  
  1461. if (flag)
  1462.     {
  1463.     fptr1 = fopen(EPDTokenFetch(2), "w");
  1464.     if (fptr1 == NULL)
  1465.         {
  1466.         sprintf(tbufv, "Can't open %s for writing\n",
  1467.             EPDTokenFetch(2));
  1468.         EGPrintTB();
  1469.         flag = 0;
  1470.         };
  1471.     };
  1472.  
  1473. /* scan the file */
  1474.  
  1475. if (flag)
  1476.     while (flag && (fgets(ev, (epdL - 1), fptr0) != NULL))
  1477.         {
  1478.         /* decode the record into an EPD structure */
  1479.  
  1480.         epdptr = EPDDecode(ev);
  1481.  
  1482.         /* check record decode validity */
  1483.  
  1484.         if (epdptr == NULL)
  1485.             flag = 0;
  1486.         else
  1487.             {
  1488.             /* clone the input EPD structure base */
  1489.  
  1490.             nptr = EPDCloneEPDBase(epdptr);
  1491.  
  1492.             /* copy the ce operation */
  1493.  
  1494.             eopptr = EPDLocateEOPCode(epdptr, epdso_ce);
  1495.             if (eopptr != NULL)
  1496.                 EPDAppendEOP(nptr, EPDCloneEOP(eopptr));
  1497.  
  1498.             /* copy the pv operation */
  1499.  
  1500.             eopptr = EPDLocateEOPCode(epdptr, epdso_pv);
  1501.             if (eopptr != NULL)
  1502.                 EPDAppendEOP(nptr, EPDCloneEOP(eopptr));
  1503.  
  1504.             /* output the new EPD strucutre */
  1505.  
  1506.             s = EPDEncode(nptr);
  1507.             fprintf(fptr1, "%s\n", s);
  1508.             EPDMemoryFree(s);
  1509.  
  1510.             /* deallocate both EPD structures */
  1511.  
  1512.             EPDReleaseEPD(epdptr);
  1513.             EPDReleaseEPD(nptr);
  1514.             };
  1515.         };
  1516.  
  1517. /* ensure file close */
  1518.  
  1519. if (fptr0 != NULL)
  1520.     fclose(fptr0);
  1521.  
  1522. if (fptr1 != NULL)
  1523.     fclose(fptr1);
  1524.  
  1525. return (flag);
  1526. }
  1527.  
  1528. /*--> EGProcessCERT: process the EG command epdcert */
  1529. static
  1530. siT
  1531. EGProcessCERT(void)
  1532. {
  1533. siT flag;
  1534. siT done;
  1535. cpevT cpev=0;
  1536. mptrT mptr;
  1537. mT m;
  1538. sanT san;
  1539.  
  1540. /* this is an internal EPD glue routine */
  1541.  
  1542. /* set the default return value: success */
  1543.  
  1544. flag = 1;
  1545.  
  1546. /* clear the completion flag */
  1547.  
  1548. done = 0;
  1549.  
  1550. /* parameter count check */
  1551.  
  1552. if (EPDTokenCount() != 1)
  1553.     {
  1554.     EGPL("This command takes no parameters.");
  1555.     flag = 0;
  1556.     };
  1557.  
  1558. /* process the epdcert command */
  1559.  
  1560. if (flag)
  1561.     {
  1562.     /* copy the host position into the EPD Kit */
  1563.  
  1564.     EGGetHostPosition();
  1565.  
  1566.     /* check for legality */
  1567.  
  1568.     if (!EPDIsLegal())
  1569.         {
  1570.         EGPL("This position is illegal.");
  1571.         done = 1;
  1572.         flag = 0;
  1573.         };
  1574.  
  1575.     /* check for checkmate */
  1576.  
  1577.     if (flag && !done)
  1578.         if (EPDIsCheckmate())
  1579.             {
  1580.             sprintf(tbufv, "%s is checkmated.\n",
  1581.                 EPDPlayerString(EPDFetchACTC()));
  1582.             EGPrintTB();
  1583.             cpev = synth_loss(0);
  1584.             done = 1;
  1585.             };
  1586.  
  1587.     /* check for stalemate */
  1588.  
  1589.     if (flag && !done)
  1590.         if (EPDIsStalemate())
  1591.             {
  1592.             sprintf(tbufv, "%s is stalemated.\n",
  1593.                 EPDPlayerString(EPDFetchACTC()));
  1594.             EGPrintTB();
  1595.             cpev = cpev_draw;
  1596.             done = 1;
  1597.             };
  1598.  
  1599.     /* check for insufficient material */
  1600.  
  1601.     if (flag && !done)
  1602.         if (EPDIsInsufficientMaterial())
  1603.             {
  1604.             EGPL("Position is drawn: insufficient mating material.");
  1605.             cpev = cpev_draw;
  1606.             done = 1;
  1607.             };
  1608.  
  1609.     /* check for mate in one */
  1610.  
  1611.     if (flag && !done)
  1612.         if ((mptr = EPDMateInOne()) != NULL)
  1613.             {
  1614.             m = *mptr;
  1615.             EPDSANEncode(&m, san);
  1616.             sprintf(tbufv, "%s can checkmate in one move with %s.\n",
  1617.                 EPDPlayerString(EPDFetchACTC()), san);
  1618.             EGPrintTB();
  1619.             cpev = synth_mate(1);
  1620.             done = 1;
  1621.             };
  1622.  
  1623.     /* probe the tablebases */
  1624.  
  1625.     if (flag && !done)
  1626.         {
  1627.         cpev = EPDTBScore();
  1628.         if (cpev != cpev_wrck)
  1629.             {
  1630.             EGPL("The position score was located in a tablebase file.");
  1631.             if (cpev == cpev_draw)
  1632.                 EGPL("The position is a draw with best play.");
  1633.             else
  1634.                 if (forced_mate(cpev))
  1635.                     {
  1636.                     sprintf(tbufv, "%s can mate in %hd move%s.\n",
  1637.                         EPDPlayerString(EPDFetchACTC()),
  1638.                         synth_distance_mate(cpev),
  1639.                         ((synth_distance_mate(cpev) == 1) ? "" : "s"));
  1640.                     EGPrintTB();
  1641.                     }
  1642.                 else
  1643.                     {
  1644.                     sprintf(tbufv, "%s can be mated in %hd move%s.\n",
  1645.                         EPDPlayerString(EPDFetchACTC()),
  1646.                         synth_distance_loss(cpev),
  1647.                         ((synth_distance_loss(cpev) == 1) ? "" : "s"));
  1648.                     EGPrintTB();
  1649.                     };
  1650.             done = 1;
  1651.             };
  1652.         };
  1653.  
  1654.     /* output score if available */
  1655.  
  1656.     if (flag && done)
  1657.         {
  1658.         /* output score */
  1659.  
  1660.         sprintf(tbufv, "Centipawn evaluation: %hd\n", cpev);
  1661.         EGPrintTB();
  1662.         }
  1663.     else
  1664.         {
  1665.         /* output diagnostic */
  1666.  
  1667.         EGPL("No certain evaluation is available.");
  1668.         };
  1669.     };
  1670.  
  1671. return (flag);
  1672. }
  1673.  
  1674. /*--> EGProcessCICS: process the EG command epdcics */
  1675. static
  1676. siT
  1677. EGProcessCICS(void)
  1678. {
  1679. siT flag;
  1680.  
  1681. /* this is an internal EPD glue routine */
  1682.  
  1683. /* set the default return value: success */
  1684.  
  1685. flag = 1;
  1686.  
  1687. /* parameter count check */
  1688.  
  1689. if (EPDTokenCount() != 3)
  1690.     {
  1691.     EGPL("This command takes two parameters");
  1692.     flag = 0;
  1693.     };
  1694.  
  1695. /* process the epdcics command */
  1696.  
  1697. if (flag)
  1698.     {
  1699.     EGPL("This command is not yet implemented.");
  1700.     flag = 0;
  1701.     };
  1702.  
  1703. return (flag);
  1704. }
  1705.  
  1706. /*--> EGProcessCOMM: process the EG command epdcomm */
  1707. static
  1708. siT
  1709. EGProcessCOMM(void)
  1710. {
  1711. siT flag;
  1712. fptrT save_history_file;
  1713. gamptrT save_default_gamptr;
  1714.  
  1715. /* this is an internal EPD glue routine */
  1716.  
  1717. /* set the default return value: success */
  1718.  
  1719. flag = 1;
  1720.  
  1721. /* parameter count check */
  1722.  
  1723. if (EPDTokenCount() != 2)
  1724.     {
  1725.     EGPL("This command takes one parameter.");
  1726.     flag = 0;
  1727.     };
  1728.  
  1729. /* process the epdcomm command */
  1730.  
  1731. if (flag)
  1732.     {
  1733.     /* save the history file pointer */
  1734.  
  1735.     save_history_file = history_file;
  1736.     history_file = NULL;
  1737.  
  1738.     /* save the game structure */
  1739.  
  1740.     save_default_gamptr = default_gamptr;
  1741.     default_gamptr = NULL;
  1742.  
  1743.     /* process via callback */
  1744.  
  1745.     EGPL("Duplex slave mode begin");
  1746.     flag = EPDComm(EGCommHandler, EPDTokenFetch(1));
  1747.     EGPL("Duplex slave mode end");
  1748.  
  1749.     /* restore the game structure */
  1750.  
  1751.     if (default_gamptr != NULL)
  1752.         {
  1753.         EPDGameClose(default_gamptr);
  1754.         default_gamptr = NULL;
  1755.         };
  1756.     default_gamptr = save_default_gamptr;
  1757.  
  1758.     /* restore the history file pointer */
  1759.  
  1760.     history_file = save_history_file;
  1761.     };
  1762.  
  1763. return (flag);
  1764. }
  1765.  
  1766. /*--> EGProcessDPGN: process the EG command epddpgn */
  1767. static
  1768. siT
  1769. EGProcessDPGN(void)
  1770. {
  1771. siT flag;
  1772. charptrT s;
  1773.  
  1774. /* this is an internal EPD glue routine */
  1775.  
  1776. /* set the default return value: success */
  1777.  
  1778. flag = 1;
  1779.  
  1780. /* parameter count check */
  1781.  
  1782. if (EPDTokenCount() != 1)
  1783.     {
  1784.     EGPL("This command takes no parameters.");
  1785.     flag = 0;
  1786.     };
  1787.  
  1788. /* process the epddpgn command */
  1789.  
  1790. if (flag)
  1791.     {
  1792.     s = EGEncodeHostHistory();
  1793.     if (s == NULL)
  1794.         flag = 0;
  1795.     else
  1796.         {
  1797.         EGPrint(s);
  1798.         EPDMemoryFree(s);
  1799.         };
  1800.     };
  1801.  
  1802. return (flag);
  1803. }
  1804.  
  1805. /*--> EGProcessDSML: process the EG command epddsml */
  1806. static
  1807. siT
  1808. EGProcessDSML(void)
  1809. {
  1810. siT flag;
  1811. siT count, index;
  1812. siT length, column;
  1813. mT m;
  1814. sanT san;
  1815.  
  1816. /* this is an internal EPD glue routine */
  1817.  
  1818. /* set the default return value: success */
  1819.  
  1820. flag = 1;
  1821.  
  1822. /* parameter count check */
  1823.  
  1824. if (EPDTokenCount() != 1)
  1825.     {
  1826.     EGPL("This command takes no parameters.");
  1827.     flag = 0;
  1828.     };
  1829.  
  1830. /* process the epddsml command */
  1831.  
  1832. if (flag)
  1833.     {
  1834.     /* copy the current host position into the EPD Kit */
  1835.  
  1836.     EGGetHostPosition();
  1837.  
  1838.     /* generate  and count */
  1839.  
  1840.     EPDGenMoves();
  1841.     count = EPDFetchMoveCount();
  1842.  
  1843.     switch (count)
  1844.         {
  1845.         case 0:
  1846.             EGPL("No moves are available.");
  1847.             break;
  1848.         case 1:
  1849.             EGPL("There is 1 move available.");
  1850.             break;
  1851.         default:
  1852.             sprintf(tbufv, "There are %hd moves available.\n", count);
  1853.             EGPrintTB();
  1854.             break;
  1855.         };
  1856.  
  1857.     /* list moves */
  1858.  
  1859.     if (count > 0)
  1860.         {
  1861.         column = 0;
  1862.         EPDSortSAN();
  1863.         for (index = 0; index < count; index++)
  1864.             {
  1865.             m = *EPDFetchMove(index);
  1866.             EPDSANEncode(&m, san);
  1867.             length = strlen(san);
  1868.             if ((column + 1 + length) < columnL)
  1869.                 {
  1870.                 sprintf(tbufv, " %s", san);
  1871.                 EGPrintTB();
  1872.                 column += 1 + length;
  1873.                 }
  1874.             else
  1875.                 {
  1876.                 EGPrint("\n");
  1877.                 EGPrint(san);
  1878.                 column = length;
  1879.                 };
  1880.             };
  1881.         if (column > 0)
  1882.             EGPrint("\n");
  1883.         };
  1884.     };
  1885.  
  1886. return (flag);
  1887. }
  1888.  
  1889. /*--> EGProcessDSTR: process the EG command epddstr */
  1890. static
  1891. siT
  1892. EGProcessDSTR(void)
  1893. {
  1894. siT flag;
  1895. charptrT s;
  1896.  
  1897. /* this is an internal EPD glue routine */
  1898.  
  1899. /* set the default return value: success */
  1900.  
  1901. flag = 1;
  1902.  
  1903. /* parameter count check */
  1904.  
  1905. if (EPDTokenCount() != 1)
  1906.     {
  1907.     EGPL("This command takes no parameters.");
  1908.     flag = 0;
  1909.     };
  1910.  
  1911. /* process the epddstr command */
  1912.  
  1913. if (flag)
  1914.     {
  1915.     s = EPDPGNGenSTR(default_gamptr);
  1916.     EGPrint(s);
  1917.     EPDMemoryFree(s);
  1918.     };
  1919.  
  1920. return (flag);
  1921. }
  1922.  
  1923. /*--> EGProcessDTPV: process the EG command epddtpv */
  1924. static
  1925. siT
  1926. EGProcessDTPV(void)
  1927. {
  1928. siT flag;
  1929. pgnstrT pgnstr;
  1930.  
  1931. /* this is an internal EPD glue routine */
  1932.  
  1933. /* set the default return value: success */
  1934.  
  1935. flag = 1;
  1936.  
  1937. /* parameter count check */
  1938.  
  1939. if (EPDTokenCount() != 2)
  1940.     {
  1941.     EGPL("This command takes one parameter.");
  1942.     flag = 0;
  1943.     };
  1944.  
  1945. /* process the epddtpv command */
  1946.  
  1947. if (flag)
  1948.     {
  1949.     pgnstr = EPDPGNFetchTagIndex(EPDTokenFetch(1));
  1950.     if (pgnstr == pgnstr_nil)
  1951.         {
  1952.         EGPL("Unknown tag name; available tag names are:");
  1953.         for (pgnstr = 0; pgnstr < pgnstrL; pgnstr++)
  1954.             {
  1955.             EGPrint("   ");
  1956.             EGPrint(EPDPGNFetchTagName(pgnstr));
  1957.             };
  1958.         EGPrint("\n");
  1959.         flag = 0;
  1960.         }
  1961.     else
  1962.         {
  1963.         sprintf(tbufv, "[%s \"%s\"]\n",
  1964.             EPDPGNFetchTagName(pgnstr),
  1965.             EPDPGNGetSTR(default_gamptr, pgnstr));
  1966.         EGPrintTB();
  1967.         };
  1968.     };
  1969.  
  1970. return (flag);
  1971. }
  1972.  
  1973. /*--> EGProcessENUM: process the EG command epdenum */
  1974. static
  1975. siT
  1976. EGProcessENUM(void)
  1977. {
  1978. siT flag;
  1979. liT total;
  1980.  
  1981. /* this is an internal EPD glue routine */
  1982.  
  1983. /* set the default return value: success */
  1984.  
  1985. flag = 1;
  1986.  
  1987. /* parameter count check */
  1988.  
  1989. if (EPDTokenCount() != 4)
  1990.     {
  1991.     EGPL("This command takes three parameters");
  1992.     flag = 0;
  1993.     };
  1994.  
  1995. /* process the epdenum command */
  1996.  
  1997. if (flag)
  1998.     {
  1999.     flag = EPDEnumerateFile(
  2000.         (siT)atol(EPDTokenFetch(1)), EPDTokenFetch(2), EPDTokenFetch(3), &total);
  2001.     if (flag)
  2002.         {
  2003.         sprintf(tbufv, "Enumeration to depth %ld totals %ld\n",
  2004.             atol(EPDTokenFetch(1)), total);
  2005.         EGPrintTB();
  2006.         };
  2007.     };
  2008.  
  2009. return (flag);
  2010. }
  2011.  
  2012. /*--> EGProcessHELP: process the EG command epdhelp */
  2013. static
  2014. siT
  2015. EGProcessHELP(void)
  2016. {
  2017. siT flag;
  2018. siT i;
  2019. egcommT egcomm;
  2020.  
  2021. /* this is an internal EPD glue routine */
  2022.  
  2023. /* set the default return value: success */
  2024.  
  2025. flag = 1;
  2026.  
  2027. /* parameter count check */
  2028.  
  2029. if (EPDTokenCount() != 1)
  2030.     {
  2031.     EGPL("This command takes no parameters.");
  2032.     flag = 0;
  2033.     };
  2034.  
  2035. /* process the epdhelp command */
  2036.  
  2037. if (flag)
  2038.     {
  2039.     /* it is not clear exactly why the next statment is needed */
  2040.  
  2041.     (void) getchar();
  2042.  
  2043.     /* list all the commands */
  2044.  
  2045.     egcomm = 0;
  2046.     while (egcomm < egcommL)
  2047.         {
  2048.         EGPL("Available EPD glue command list");
  2049.         EGPL("-------------------------------");
  2050.  
  2051.         i = 0;
  2052.         while ((egcomm < egcommL) && (i < 10))
  2053.             {
  2054.             sprintf(tbufv, "%s: %s\n",
  2055.                 egcommstrv[egcomm], eghelpstrv[egcomm]);
  2056.             EGPrintTB();
  2057.             i++;
  2058.             egcomm++;
  2059.             };
  2060.  
  2061.         if (egcomm < egcommL)
  2062.             {
  2063.             EGPL("");
  2064.             EGPL("Press <return> for more command help");
  2065.             (void) getchar();
  2066.             EGPL("");
  2067.             };
  2068.         };
  2069.     };
  2070.  
  2071. return (flag);
  2072. }
  2073.  
  2074. /*--> EGProcessLINK: process the EG command epdlink */
  2075. static
  2076. siT
  2077. EGProcessLINK(void)
  2078. {
  2079. siT flag;
  2080.  
  2081. /* this is an internal EPD glue routine */
  2082.  
  2083. /* set the default return value: success */
  2084.  
  2085. flag = 1;
  2086.  
  2087. /* parameter count check */
  2088.  
  2089. if (EPDTokenCount() != 3)
  2090.     {
  2091.     EGPL("This command takes two parameters");
  2092.     flag = 0;
  2093.     };
  2094.  
  2095. /* process the epdlink command */
  2096.  
  2097. if (flag)
  2098.     {
  2099.     EGPL("This command is not yet implemented.");
  2100.     flag = 0;
  2101.     };
  2102.  
  2103. return (flag);
  2104. }
  2105.  
  2106. /*--> EGProcessLPGN: process the EG command epdlpgn */
  2107. static
  2108. siT
  2109. EGProcessLPGN(void)
  2110. {
  2111. siT flag;
  2112.  
  2113. /* this is an internal EPD glue routine */
  2114.  
  2115. /* set the default return value: success */
  2116.  
  2117. flag = 1;
  2118.  
  2119. /* parameter count check */
  2120.  
  2121. if (EPDTokenCount() != 2)
  2122.     {
  2123.     EGPL("This command takes one parameter.");
  2124.     flag = 0;
  2125.     };
  2126.  
  2127. /* process the epdlpgn command */
  2128.  
  2129. if (flag)
  2130.     {
  2131.     EGPL("This command is not yet implemented.");
  2132.     flag = 0;
  2133.     };
  2134.  
  2135. return (flag);
  2136. }
  2137.  
  2138. /*--> EGProcessLREC: process the EG command epdlrec */
  2139. static
  2140. siT
  2141. EGProcessLREC(void)
  2142. {
  2143. siT flag;
  2144. fptrT fptr;
  2145. liT i, n;
  2146. epdptrT epdptr;
  2147. char ev[epdL];
  2148.  
  2149. /* this is an internal EPD glue routine */
  2150.  
  2151. /* set the default return value: success */
  2152.  
  2153. flag = 1;
  2154.  
  2155. /* parameter count check */
  2156.  
  2157. if (EPDTokenCount() != 3)
  2158.     {
  2159.     EGPL("This command takes two parameters");
  2160.     flag = 0;
  2161.     };
  2162.  
  2163. /* process the epdlrec command */
  2164.  
  2165. if (flag)
  2166.     {
  2167.     fptr = fopen(EPDTokenFetch(1), "r");
  2168.     if (fptr == NULL)
  2169.         flag = 0;
  2170.     else
  2171.         {
  2172.         /* read the indicated record */
  2173.  
  2174.         i = 0;
  2175.         n = atol(EPDTokenFetch(2));
  2176.         while (flag && (i < n))
  2177.             if (fgets(ev, (epdL - 1), fptr) == NULL)
  2178.                 flag = 0;
  2179.             else
  2180.                 i++;
  2181.         fclose(fptr);
  2182.  
  2183.         /* set the current position */
  2184.  
  2185.         if (flag)
  2186.             {
  2187.             epdptr = EPDDecode(ev);
  2188.             if (epdptr == NULL)
  2189.                 flag = 0;
  2190.             else
  2191.                 {
  2192.                 EPDRealize(epdptr);
  2193.                 EPDReleaseEPD(epdptr);
  2194.                 EGPutHostPosition();
  2195.                 };
  2196.             };
  2197.         };
  2198.     };
  2199.  
  2200. return (flag);
  2201. }
  2202.  
  2203. /*--> EGProcessMORE: process the EG command epdmore */
  2204. static
  2205. siT
  2206. EGProcessMORE(void)
  2207. {
  2208. siT flag;
  2209.  
  2210. /* this is an internal EPD glue routine */
  2211.  
  2212. /* set the default return value: success */
  2213.  
  2214. flag = 1;
  2215.  
  2216. /* parameter count check */
  2217.  
  2218. if (EPDTokenCount() != 2)
  2219.     {
  2220.     EGPL("This command takes one parameter.");
  2221.     flag = 0;
  2222.     };
  2223.  
  2224. /* process the epdmore command */
  2225.  
  2226. if (flag)
  2227.     switch (EGLocateCommand(EPDTokenFetch(1)))
  2228.         {
  2229.         case egcomm_epdapgn:
  2230.             EGPL("epdapgn: Append the game to a PGN file");
  2231.             EGPL("");
  2232.             EGPL("This command is used to append the current game to a file");
  2233.             EGPL("using Portable Game Notation (PGN) format.  It takes one");
  2234.             EGPL("parameter which is the file name of interest.");
  2235.             break;
  2236.  
  2237.         case egcomm_epdbfix:
  2238.             EGPL("epdbfix: Fix an EPD file for import into Bookup");
  2239.             EGPL("");
  2240.             EGPL("This command takes two parameters.  Both parameters are");
  2241.             EGPL("names of EPD files.  The first is an existing EPD file with");
  2242.             EGPL("analysis data.  The second is the EPD file to be created");
  2243.             EGPL("from the first by removing all operations except the ce and");
  2244.             EGPL("pv operations.  This second file can then be imported into");
  2245.             EGPL("the Bookup program.");
  2246.             break;
  2247.  
  2248.         case egcomm_epdcert:
  2249.             EGPL("epdcert: Try to display a certain evaluation");
  2250.             EGPL("");
  2251.             EGPL("This command takes no parameters.  The current position is");
  2252.             EGPL("examined for legality, and if legal, an attempt is made to");
  2253.             EGPL("return an absolute certain evaluation.  An absolute certain");
  2254.             EGPL("evaluation is available for checkmates, stalemates, draws by");
  2255.             EGPL("insufficient material, and mate in one positions.  Also,");
  2256.             EGPL("if there are only a few chessmen on the board, then the");
  2257.             EGPL("current position is used as an index into an external file");
  2258.             EGPL("corresponding to the active color and the distribution of");
  2259.             EGPL("pieces.  If the appropriate external file is available, the");
  2260.             EGPL("position is evaluated by a single file look-up operation.");
  2261.             EGPL("These files are called tablebases and they should appear in");
  2262.             EGPL("the TB subdirectory of the current working directory.  These");
  2263.             EGPL("files may be obtained via ftp from the chess.onenet.net site");
  2264.             EGPL("in the pub/chess/TB directory.");
  2265.             break;
  2266.  
  2267.         case egcomm_epdcics:
  2268.             EGPL("epdcics: Slave to an Internet Chess Server");
  2269.             EGPL("");
  2270.             EGPL("This command causes the host program Crafty to becomed slaved");
  2271.             EGPL("to an Internet Chess Server (ICS).  This means that the host");
  2272.             EGPL("program will follow directions from the indicated Internet");
  2273.             EGPL("Chess Server until either the ICS tells the program to exit");
  2274.             EGPL("slave mode or the program is interrupted by the user.  This");
  2275.             EGPL("command takes two parameters.  The first is the name of the");
  2276.             EGPL("machine running the ICS and the second is the port number in");
  2277.             EGPL("use by the ICS.");
  2278.             break;
  2279.  
  2280.         case egcomm_epdcomm:
  2281.             EGPL("epdcomm: Slave to the Duplex referee program");
  2282.             EGPL("");
  2283.             EGPL("This command causes the host program Crafty to becomed slaved");
  2284.             EGPL("to the simple referee program Duplex.  Duplex must be started");
  2285.             EGPL("prior to entering this command.  Once the host program is");
  2286.             EGPL("slaved to Duplex, it will remain so until it is instructed");
  2287.             EGPL("by Duplex to terminate or is interrupted by the user.  This");
  2288.             EGPL("command is used to support the Duplex function of controlling");
  2289.             EGPL("automatic play between two host programs on the same Unix");
  2290.             EGPL("system.  The communication used is based on named pipes which");
  2291.             EGPL("are special files that support FIFO data operation.  This");
  2292.             EGPL("command takes one parameter which is a base name for a pair");
  2293.             EGPL("of named pipes.  The host output pipe name is generated by");
  2294.             EGPL("adding a \".pc0\" suffix to the base name and the host input");
  2295.             EGPL("pipe name is generated by addint a \".pc1\" suffix to the");
  2296.             EGPL("base name.  (Both pipe files are created and later removed");
  2297.             EGPL("automatically by the Duplex program.)  The Duplex program is");
  2298.             EGPL("given three parameters to run a series of games between two");
  2299.             EGPL("host programs: the first is the base name given to the first");
  2300.             EGPL("host program, the second is the base name given to the second");
  2301.             EGPL("host program, and the third is the count of the number of");
  2302.             EGPL("games to be played.");
  2303.             break;
  2304.  
  2305.         case egcomm_epddpgn:
  2306.             EGPL("epddpgn: Display the game using PGN");
  2307.             EGPL("");
  2308.             EGPL("This command displays the current game using Portable Game");
  2309.             EGPL("Notation (PGN).  It takes no parameters.");
  2310.             break;
  2311.  
  2312.         case egcomm_epddsml:
  2313.             EGPL("epddsml: Display SAN move list");
  2314.             EGPL("");
  2315.             EGPL("This command displays the ASCII sorted list of available");
  2316.             EGPL("moves using SAN (Standard Algebraic Notation).  The count");
  2317.             EGPL("of moves is also displayed.  This command takes no");
  2318.             EGPL("parameters.");
  2319.             break;
  2320.  
  2321.         case egcomm_epddstr:
  2322.             EGPL("epddstr: Display the PGN Seven Tag Roster");
  2323.             EGPL("");
  2324.             EGPL("This command displays the current values of each of the tag");
  2325.             EGPL("pairs of the PGN Seven Tag Roster.  These tags are: Event, ");
  2326.             EGPL("Site, Date, Round, White, Black, and Result.  This command");
  2327.             EGPL("takes no parameters.");
  2328.             break;
  2329.  
  2330.         case egcomm_epddtpv:
  2331.             EGPL("epddtpv: Display a PGN tag pair value");
  2332.             EGPL("");
  2333.             EGPL("This command displays the current value for the indicated");
  2334.             EGPL("PGN tag pair.  These available tag pair names are: Event, ");
  2335.             EGPL("Site, Date, Round, White, Black, and Result.  This command");
  2336.             EGPL("takes a single parameter which is the name of the tag pair");
  2337.             EGPL("to be displayed.");
  2338.             break;
  2339.  
  2340.         case egcomm_epdenum:
  2341.             EGPL("epdenum: Enumerate positions in an EPD file");
  2342.             EGPL("");
  2343.             EGPL("This command takes three parameters.  The first is a non-");
  2344.             EGPL("negative integer that gives a ply depth limit.  The second");
  2345.             EGPL("is an input EPD file with positions to be enumerated to the");
  2346.             EGPL("given depth.  The third parameter is the result EPD file");
  2347.             EGPL("with enumeration data given with the acd, acn, and acs");
  2348.             EGPL("operations.  The grand total of all enumerations is printed");
  2349.             EGPL("to the standard output.");
  2350.             break;
  2351.  
  2352.         case egcomm_epdhelp:
  2353.             EGPL("epdhelp: Display available epdglue commands");
  2354.             EGPL("");
  2355.             EGPL("This command takes no parameters.  It displays a list");
  2356.             EGPL("of all the epdglue commands with a single line description");
  2357.             EGPL("of each command.  The epdmore command gives a detailed");
  2358.             EGPL("description of a specified command.");
  2359.             break;
  2360.  
  2361.         case egcomm_epdlink:
  2362.             EGPL("epdlink: Slave to the Argus moderator program");
  2363.             EGPL("");
  2364.             EGPL("This command used to slave the host program to the Argus");
  2365.             EGPL("tournament referee program.  It takes two parameters.  The");
  2366.             EGPL("first is the name of the machine running the Argus referee");
  2367.             EGPL("and the second is the port number in use by Argus on the");
  2368.             EGPL("indicated machine.  The Argus program must be started prior");
  2369.             EGPL("to using this command.  Argus acts as a general tournament");
  2370.             EGPL("supervisor and mediator for any number of chessplaying");
  2371.             EGPL("programs competing in a compuer chess event.  It supplies");
  2372.             EGPL("the participating program entrants with everything needed");
  2373.             EGPL("for an entire tournament.");
  2374.             break;
  2375.  
  2376.         case egcomm_epdlpgn:
  2377.             EGPL("epdlpgn: Load the game from a PGN file");
  2378.             EGPL("");
  2379.             EGPL("This command loads a single game from a Portable Game");
  2380.             EGPL("Notation (PGN) file.  If there is more than one game in the");
  2381.             EGPL("file, then only the first one is loaded.  This command tales");
  2382.             EGPL("a single parameter which is the name of the file containing");
  2383.             EGPL("the PGN data of interest.");
  2384.             break;
  2385.  
  2386.         case egcomm_epdlrec:
  2387.             EGPL("epdlpgn: Load a selected EPD record from a file");
  2388.             EGPL("");
  2389.             EGPL("This command loads an EPD record from a file and causes it");
  2390.             EGPL("to become the current position in the host program.  This");
  2391.             EGPL("command takes two parameters.  The first is the name of the");
  2392.             EGPL("file with EPD records and the second is the record number");
  2393.             EGPL("of interest.  The epdlrec command is intended to assist with");
  2394.             EGPL("benchmark analysis by making it easy to select and load the");
  2395.             EGPL("Nth record of a benchmark file.");
  2396.             break;
  2397.  
  2398.         case egcomm_epdmore:
  2399.             EGPL("epdmore: Display detailed help for a given command");
  2400.             EGPL("");
  2401.             EGPL("This command takes a single parameter which is the name");
  2402.             EGPL("of one of the available epdglue commands.  A brief paragraph");
  2403.             EGPL("of helpful assistance is displayed.");
  2404.             break;
  2405.  
  2406.         case egcomm_epdnoop:
  2407.             EGPL("epdnoop: No operation");
  2408.             EGPL("");
  2409.             EGPL("This command performs no operation.  It is provided for");
  2410.             EGPL("development purposes.");
  2411.             break;
  2412.  
  2413.         case egcomm_epdpfdn:
  2414.             EGPL("epdpfdn:  Process file: data normalization");
  2415.             EGPL("");
  2416.             EGPL("This command takes two parameters.  The first is the name of");
  2417.             EGPL("an input EPD data file.  The second is the name of the EPD");
  2418.             EGPL("output file to be produced from normalizing the input.  The");
  2419.             EGPL("normalization process produces a canonical external");
  2420.             EGPL("representation for each EPD input record.");
  2421.             break;
  2422.  
  2423.         case egcomm_epdpfdr:
  2424.             EGPL("epdpfdr:  Process file: data repair");
  2425.             EGPL("");
  2426.             EGPL("This command takes two parameters.  The first is the name of");
  2427.             EGPL("an input EPD data file.  The second is the name of the EPD");
  2428.             EGPL("output file to be produced from repairing the input.  The");
  2429.             EGPL("repair process attempts to map all chess move data present");
  2430.             EGPL("in the input into Standard Algebraic Notation.  This repair");
  2431.             EGPL("effort affects the am, bm, pm, pv, sm, and sv operations.");
  2432.             break;
  2433.  
  2434.         case egcomm_epdpfga:
  2435.             EGPL("epdpfga:  Process file: general analysis");
  2436.             EGPL("");
  2437.             EGPL("This command takes two parameters.  The first is the name of");
  2438.             EGPL("an input EPD data file.  The second is the name of the EPD");
  2439.             EGPL("output file to be produced from applying general analysis");
  2440.             EGPL("to each position in the input file.  The output analysis is");
  2441.             EGPL("contained in the acd, acn, acs, ce, and pv operations.");
  2442.             break;
  2443.  
  2444.         case egcomm_epdpflc:
  2445.             EGPL("epdpflc:  Process file: locate cooks");
  2446.             EGPL("");
  2447.             EGPL("This command is used to scan an EPD file and report on any");
  2448.             EGPL("checkmating cooks.  The signle parameter is the name of the");
  2449.             EGPL("EPD file to be scanned.  Each record is scanned and if the");
  2450.             EGPL("centipawn evaluation indicates a forced mate, then the move");
  2451.             EGPL("appearing as the result of a search is checked against the");
  2452.             EGPL("moves appearing in the bm (best moves) operation on the same");
  2453.             EGPL("record.  If the result move does not appear in the bm list,");
  2454.             EGPL("then the record is reported as a cook.");
  2455.             break;
  2456.  
  2457.         case egcomm_epdpfop:
  2458.             EGPL("epdpfop:  Process file: operation purge");
  2459.             EGPL("");
  2460.             EGPL("This command takes threee parameters.  The first is the name");
  2461.             EGPL("of an EPD operation mnemonic to be purged.  The second is the");
  2462.             EGPL("name fo the input EPD file, and the third is the name of the");
  2463.             EGPL("EPD output to be produced by purging the specified operation");
  2464.             EGPL("from the input file.");
  2465.             break;
  2466.  
  2467.         case egcomm_epdscor:
  2468.             EGPL("epdscor:  Score EPD analysis file");
  2469.             EGPL("");
  2470.             EGPL("This command takes one parameter.  It is the name of an input");
  2471.             EGPL("EPD data file containing analysis result data.  The input");
  2472.             EGPL("data analysis is scanned and a brief statistical report is");
  2473.             EGPL("displayed.");
  2474.             break;
  2475.  
  2476.         case egcomm_epdshow:
  2477.             EGPL("epdshow:  Show EPD four fields for the current position");
  2478.             EGPL("");
  2479.             EGPL("This command takes no parameters.  It causes the EPD four");
  2480.             EGPL("data fields for the current position to be displayed.");
  2481.             break;
  2482.  
  2483.         case egcomm_epdspgn:
  2484.             EGPL("epdspgn: Save the game to a PGN file");
  2485.             EGPL("");
  2486.             EGPL("This command is used to save the current game to a file");
  2487.             EGPL("using Portable Game Notation (PGN) format.  It takes one");
  2488.             EGPL("parameter which is the file name of interest.  The previous");
  2489.             EGPL("copy of the file, if any, is overwritten.");
  2490.             break;
  2491.  
  2492.         case egcomm_epdstpv:
  2493.             EGPL("epdstpv: Set a PGN tag pair value");
  2494.             EGPL("");
  2495.             EGPL("This command sets the current value for the indicated");
  2496.             EGPL("PGN tag pair.  These available tag pair names are: Event, ");
  2497.             EGPL("Site, Date, Round, White, Black, and Result.  This command");
  2498.             EGPL("takes two parameters.  The first which is the name of the");
  2499.             EGPL("tag pair of interest and the second is the value to be");
  2500.             EGPL("assigned.  Underscore characters in the value are mapped");
  2501.             EGPL("to blanks; this allows embedded spaces to appear in the");
  2502.             EGPL("received value.");
  2503.             break;
  2504.  
  2505.         case egcomm_epdtest:
  2506.             EGPL("epdtest:  Developer testing");
  2507.             EGPL("");
  2508.             EGPL("This command takes no parameters.  It is used for developer");
  2509.             EGPL("testing purposes.");
  2510.             break;
  2511.  
  2512.         case egcomm_nil:
  2513.             sprintf(tbufv, "Unknown command: %s\n", EPDTokenFetch(1));
  2514.             EGPrintTB();
  2515.             flag = 0;
  2516.             break;
  2517.         };
  2518.  
  2519. return (flag);
  2520. }
  2521.  
  2522. /*--> EGProcessNOOP: process the EG command epdnoop */
  2523. static
  2524. siT
  2525. EGProcessNOOP(void)
  2526. {
  2527. siT flag;
  2528.  
  2529. /* this is an internal EPD glue routine */
  2530.  
  2531. /* set the default return value: success */
  2532.  
  2533. flag = 1;
  2534.  
  2535. /* process the epdnoop command */
  2536.  
  2537. return (flag);
  2538. }
  2539.  
  2540. /*--> EGProcessPFDN: process the EG command epdpfdn */
  2541. static
  2542. siT
  2543. EGProcessPFDN(void)
  2544. {
  2545. siT flag;
  2546.  
  2547. /* this is an internal EPD glue routine */
  2548.  
  2549. /* set the default return value: success */
  2550.  
  2551. flag = 1;
  2552.  
  2553. /* parameter count check */
  2554.  
  2555. if (EPDTokenCount() != 3)
  2556.     {
  2557.     EGPL("This command takes two parameters");
  2558.     flag = 0;
  2559.     };
  2560.  
  2561. /* process the epdpfdn command */
  2562.  
  2563. if (flag)
  2564.     flag = EPDNormalizeFile(EPDTokenFetch(1), EPDTokenFetch(2));
  2565.  
  2566. return (flag);
  2567. }
  2568.  
  2569. /*--> EGProcessPFDR: process the EG command epdpfdr */
  2570. static
  2571. siT
  2572. EGProcessPFDR(void)
  2573. {
  2574. siT flag;
  2575.  
  2576. /* this is an internal EPD glue routine */
  2577.  
  2578. /* set the default return value: success */
  2579.  
  2580. flag = 1;
  2581.  
  2582. /* parameter count check */
  2583.  
  2584. if (EPDTokenCount() != 3)
  2585.     {
  2586.     EGPL("This command takes two parameters");
  2587.     flag = 0;
  2588.     };
  2589.  
  2590. /* process the epdpfdr command */
  2591.  
  2592. if (flag)
  2593.     flag = EPDRepairFile(EPDTokenFetch(1), EPDTokenFetch(2));
  2594.  
  2595. return (flag);
  2596. }
  2597.  
  2598. /*--> EGProcessPFGA: process the EG command epdpfga */
  2599. static
  2600. siT
  2601. EGProcessPFGA(void)
  2602. {
  2603. siT flag;
  2604. fptrT fptr0, fptr1;
  2605. liT record;
  2606. time_t start_time;
  2607. liT result;
  2608. siT index;
  2609. liT host_acd, host_acn, host_acs;
  2610. cpevT host_ce;
  2611. charptrT s;
  2612. liT move;
  2613. mT m;
  2614. sanT san;
  2615. eovptrT eovptr;
  2616. eopptrT eopptr;
  2617. epdptrT epdptr;
  2618. char ev[epdL];
  2619. TREE *tree=local[0];
  2620.  
  2621. /* this is an internal EPD glue routine */
  2622.  
  2623. /* set the default return value: success */
  2624.  
  2625. flag = 1;
  2626.  
  2627. /* clear the file pointers */
  2628.  
  2629. fptr0 = fptr1 = NULL;
  2630.  
  2631. /* parameter count check */
  2632.  
  2633. if (EPDTokenCount() != 3)
  2634.     {
  2635.     EGPL("This command takes two parameters");
  2636.     flag = 0;
  2637.     };
  2638.  
  2639. /* set up the input file */
  2640.  
  2641. if (flag)
  2642.     {
  2643.     fptr0 = fopen(EPDTokenFetch(1), "r");
  2644.     if (fptr0 == NULL)
  2645.         {
  2646.         sprintf(tbufv, "Can't open %s for reading\n",
  2647.             EPDTokenFetch(1));
  2648.         EGPrintTB();
  2649.         flag = 0;
  2650.         };
  2651.     };
  2652.  
  2653. /* set up the output file */
  2654.  
  2655. if (flag)
  2656.     {
  2657.     fptr1 = fopen(EPDTokenFetch(2), "w");
  2658.     if (fptr1 == NULL)
  2659.         {
  2660.         sprintf(tbufv, "Can't open %s for writing\n",
  2661.             EPDTokenFetch(2));
  2662.         EGPrintTB();
  2663.         flag = 0;
  2664.         };
  2665.     };
  2666.  
  2667. /* scan the file */
  2668.  
  2669. if (flag)
  2670.     {
  2671.     /* initialize the record count */
  2672.  
  2673.     record = 0;
  2674.  
  2675.     /* read one record per loop */
  2676.  
  2677.     while (flag && (fgets(ev, (epdL - 1), fptr0) != NULL))
  2678.         {
  2679.         /* decode the record into an EPD structure */
  2680.  
  2681.         epdptr = EPDDecode(ev);
  2682.  
  2683.         /* check record decode validity */
  2684.  
  2685.         if (epdptr == NULL)
  2686.             flag = 0;
  2687.         else
  2688.             {
  2689.             /* set up the position in the EPD Kit */
  2690.  
  2691.             EPDRealize(epdptr);
  2692.  
  2693.             /* legality test */
  2694.  
  2695.             if (!EPDIsLegal())
  2696.                 flag = 0;
  2697.             else
  2698.                 {
  2699.                 /* output record information to the display */
  2700.  
  2701.                 sprintf(tbufv, "PFGA: EPD record: %ld", (record + 1));
  2702.                 EGPrintTB();
  2703.                 if (((eopptr = EPDLocateEOPCode(epdptr, epdso_id)) != NULL) &&
  2704.                     ((eovptr = eopptr->eop_headeov) != NULL) &&
  2705.                     ((s = eovptr->eov_str) != NULL))
  2706.                     {
  2707.                     EGPrint("   ID: ");
  2708.                     EGPrint(s);
  2709.                     };
  2710.                 EGPrint("\n");
  2711.  
  2712.                 /* output record information to the log file */
  2713.  
  2714.                 if (log_file != NULL)
  2715.                     {
  2716.                     fprintf(log_file, "PFGA: EPD record: %ld", (record + 1));
  2717.                     if (((eopptr = EPDLocateEOPCode(epdptr, epdso_id)) != NULL) &&
  2718.                         ((eovptr = eopptr->eop_headeov) != NULL) &&
  2719.                         ((s = eovptr->eov_str) != NULL))
  2720.                         fprintf(log_file, "   ID: %s", s);
  2721.                       fprintf(log_file, "\n");
  2722.                     };
  2723.  
  2724.                 /* set up the host current position */
  2725.  
  2726.                 EGPutHostPosition();
  2727.  
  2728.                 /* set host search parameters */
  2729.  
  2730.                 tree->position[1] = tree->position[0];
  2731.                 iteration_depth = 0;
  2732.                 ponder = 0;
  2733.  
  2734.                 /* get the starting time */
  2735.  
  2736.                 start_time = time(NULL);
  2737.  
  2738.                 /* run host search; EPD Kit position may be changed */
  2739.  
  2740.                 result =
  2741.                     EGIterate(EGMapToHostColor(EPDFetchACTC()), think);
  2742.  
  2743.                 /* refresh the EPD Kit current position */
  2744.  
  2745.                 EGGetHostPosition();
  2746.  
  2747.                 /* extract analysis count: depth */
  2748.  
  2749.                 host_acd = iteration_depth;
  2750.                 if (host_acd == 0)
  2751.                     host_acd = 1;
  2752.  
  2753.                 /* insert analysis count: depth */
  2754.  
  2755.                 EPDAddOpInt(epdptr, epdso_acd, host_acd);
  2756.  
  2757.                 /* extract analysis count: nodes */
  2758.  
  2759.                 host_acn = tree->nodes_searched;
  2760.                 if (host_acn == 0)
  2761.                     host_acn = 1;
  2762.  
  2763.                 /* insert analysis count: nodes */
  2764.  
  2765.                 EPDAddOpInt(epdptr, epdso_acn, host_acn);
  2766.  
  2767.                 /* extract analysis count: seconds */
  2768.  
  2769.                 host_acs = time(NULL) - start_time;
  2770.                 if (host_acs == 0)
  2771.                     host_acs = 1;
  2772.  
  2773.                 /* insert analysis count: seconds */
  2774.  
  2775.                 EPDAddOpInt(epdptr, epdso_acs, host_acs);
  2776.  
  2777.                 /* extract centipawn evaluation */
  2778.  
  2779.                 host_ce = EGMapFromHostScore(result);
  2780.  
  2781.                 /* insert centipawn evaluation */
  2782.  
  2783.                 EPDAddOpInt(epdptr, epdso_ce, host_ce);
  2784.  
  2785.                 /* delete predicted move */
  2786.  
  2787.                 EPDDropIfLocEOPCode(epdptr, epdso_pm);
  2788.  
  2789.                 /* extract/insert predicted variation */
  2790.  
  2791.                 EPDDropIfLocEOPCode(epdptr, epdso_pv);
  2792.                 eopptr = EPDCreateEOPCode(epdso_pv);
  2793.  
  2794.                 for (index = 1; index <= (int) tree->pv[0].path_length; index++)
  2795.                     {
  2796.                     /* generate moves for the current position */
  2797.  
  2798.                     EPDGenMoves();
  2799.  
  2800.                     /* fetch the predicted move at this ply */
  2801.  
  2802.                     move = tree->pv[0].path[index];
  2803.  
  2804.                     /* map the host move to EPD style */
  2805.  
  2806.                     m = EGMapFromHostMove(move);
  2807.  
  2808.                     /* set the flag bits in the EPD move */
  2809.  
  2810.                     EPDSetMoveFlags(&m);
  2811.  
  2812.                     /* construct the SAN for the move */
  2813.  
  2814.                     EPDSANEncode(&m, san);
  2815.  
  2816.                     /* create and append the SAN move */
  2817.  
  2818.                     eovptr = EPDCreateEOVSym(san);
  2819.                     EPDAppendEOV(eopptr, eovptr);
  2820.  
  2821.                     /* execute the move to update the EPD position */
  2822.  
  2823.                     EPDExecuteUpdate(&m);
  2824.                     };
  2825.  
  2826.                 /* retract predicted variation moves */
  2827.  
  2828.                 EPDRetractAll();
  2829.  
  2830.                 /* append the pv operation to the EPD structure */
  2831.  
  2832.                 EPDAppendEOP(epdptr, eopptr);
  2833.  
  2834.                 /* encode the EPD into a string, write, and release */
  2835.  
  2836.                 s = EPDEncode(epdptr);
  2837.                 fprintf(fptr1, "%s\n", s);
  2838.                 EPDMemoryFree(s);
  2839.                 };
  2840.  
  2841.             /* deallocate the EPD structure */
  2842.  
  2843.             EPDReleaseEPD(epdptr);
  2844.             };
  2845.  
  2846.         /* increment EPD record count */
  2847.  
  2848.         record++;
  2849.         };
  2850.     };
  2851.  
  2852. /* ensure file close */
  2853.  
  2854. if (fptr0 != NULL)
  2855.     fclose(fptr0);
  2856.  
  2857. if (fptr1 != NULL)
  2858.     fclose(fptr1);
  2859.  
  2860. return (flag);
  2861. }
  2862.  
  2863. /*--> EGProcessPFLC: process the EG command epdpflc */
  2864. static
  2865. siT
  2866. EGProcessPFLC(void)
  2867. {
  2868. siT flag;
  2869. fptrT fptr;
  2870. epdptrT epdptr;
  2871. eopptrT eopptr;
  2872. eovptrT eovptr;
  2873. liT record;
  2874. charptrT s;
  2875. char ev[epdL];
  2876.  
  2877. /* this is an internal EPD glue routine */
  2878.  
  2879. /* set the default return value: success */
  2880.  
  2881. flag = 1;
  2882.  
  2883. /* parameter count check */
  2884.  
  2885. if (EPDTokenCount() != 2)
  2886.     {
  2887.     EGPL("This command takes one parameter.");
  2888.     flag = 0;
  2889.     };
  2890.  
  2891. /* clear the file pointer */
  2892.  
  2893. fptr = NULL;
  2894.  
  2895. /* set up the input file */
  2896.  
  2897. if (flag)
  2898.     {
  2899.     fptr = fopen(EPDTokenFetch(1), "r");
  2900.     if (fptr == NULL)
  2901.         {
  2902.         sprintf(tbufv, "Can't open %s for reading\n",
  2903.             EPDTokenFetch(1));
  2904.         EGPrintTB();
  2905.         flag = 0;
  2906.         };
  2907.     };
  2908.  
  2909. /* scan the file */
  2910.  
  2911. if (flag)
  2912.     {
  2913.     /* clear record count */
  2914.  
  2915.     record = 0;
  2916.  
  2917.     /* scan each record */
  2918.  
  2919.     while (flag && (fgets(ev, (epdL - 1), fptr) != NULL))
  2920.         {
  2921.         /* decode the record into an EPD structure */
  2922.  
  2923.         epdptr = EPDDecode(ev);
  2924.  
  2925.         /* check record decode validity */
  2926.  
  2927.         if (epdptr == NULL)
  2928.             flag = 0;
  2929.         else
  2930.             {
  2931.             /* did the expectation indicate a forced mate? */
  2932.  
  2933.             if (((eopptr = EPDLocateEOPCode(epdptr, epdso_ce)) != NULL) &&
  2934.                 ((eovptr = eopptr->eop_headeov) != NULL) &&
  2935.                 forced_mate(atol(eovptr->eov_str)))
  2936.                 {
  2937.                 /* get the analysis result move from the pv */
  2938.  
  2939.                 eopptr = EPDLocateEOPCode(epdptr, epdso_pv);
  2940.                 if ((eopptr != NULL) &&
  2941.                     ((eovptr = eopptr->eop_headeov) != NULL))
  2942.                     {
  2943.                     /* get a pointer to the result move */
  2944.  
  2945.                     s = eovptr->eov_str;
  2946.  
  2947.                     /* get the best move operation */
  2948.  
  2949.                     eopptr = EPDLocateEOPCode(epdptr, epdso_bm);
  2950.                     if (eopptr != NULL)
  2951.                         {
  2952.                         /* check for a matching best move */
  2953.  
  2954.                         eovptr = EPDLocateEOV(eopptr, s);
  2955.  
  2956.                         /* if not found, then it's a cook */
  2957.  
  2958.                         if (eovptr == NULL)
  2959.                             {
  2960.                             /* issue report */
  2961.  
  2962.                             sprintf(tbufv, "PFLC: record %ld:   cook: %s",
  2963.                                 (record + 1), s);
  2964.                             EGPrintTB();
  2965.                             eopptr = EPDLocateEOPCode(epdptr, epdso_id);
  2966.                             if ((eopptr != NULL) &&
  2967.                                 ((eovptr = eopptr->eop_headeov) != NULL))
  2968.                                 {
  2969.                                 EGPrint("   ID: ");
  2970.                                 EGPrint(eovptr->eov_str);
  2971.                                 };
  2972.                             EGPrint("\n");
  2973.                             };
  2974.                         };
  2975.                     };
  2976.                 };
  2977.  
  2978.             /* deallocate the EPD structure */
  2979.  
  2980.             EPDReleaseEPD(epdptr);
  2981.             };
  2982.  
  2983.         /* next record */
  2984.  
  2985.         record++;
  2986.         };
  2987.     };
  2988.  
  2989. /* ensure input file closed */
  2990.  
  2991. if (fptr != NULL)
  2992.     fclose(fptr);
  2993.  
  2994. return (flag);
  2995. }
  2996.  
  2997. /*--> EGProcessPFOP: process the EG command epdpfop */
  2998. static
  2999. siT
  3000. EGProcessPFOP(void)
  3001. {
  3002. siT flag;
  3003.  
  3004. /* this is an internal EPD glue routine */
  3005.  
  3006. /* set the default return value: success */
  3007.  
  3008. flag = 1;
  3009.  
  3010. /* parameter count check */
  3011.  
  3012. if (EPDTokenCount() != 4)
  3013.     {
  3014.     EGPL("This command takes three parameters");
  3015.     flag = 0;
  3016.     };
  3017.  
  3018. /* process the epdpfop command */
  3019.  
  3020. if (flag)
  3021.     flag = EPDPurgeOpFile(
  3022.         EPDTokenFetch(1), EPDTokenFetch(2), EPDTokenFetch(3));
  3023.  
  3024. return (flag);
  3025. }
  3026.  
  3027. /*--> EGProcessSCOR: process the EG command epdscor */
  3028. static
  3029. siT
  3030. EGProcessSCOR(void)
  3031. {
  3032. siT flag;
  3033. bmsT bms;
  3034.  
  3035. /* this is an internal EPD glue routine */
  3036.  
  3037. /* set the default return value: success */
  3038.  
  3039. flag = 1;
  3040.  
  3041. /* parameter count check */
  3042.  
  3043. if (EPDTokenCount() != 2)
  3044.     {
  3045.     EGPL("This command takes one parameter.");
  3046.     flag = 0;
  3047.     };
  3048.  
  3049. /* process the epdscor command */
  3050.  
  3051. if (flag)
  3052.     {
  3053.     flag = EPDScoreFile(EPDTokenFetch(1), &bms);
  3054.     if (flag)
  3055.         {
  3056.         sprintf(tbufv, "total: %ld\n", bms.bms_total);
  3057.         EGPrintTB();
  3058.         if (bms.bms_total != 0)
  3059.             {
  3060.             if (bms.bms_acdflag)
  3061.                 {
  3062.                 sprintf(tbufv, "total acd: %ld   mean total acd: %.2f\n",
  3063.                     bms.bms_total_acd,
  3064.                     ((lrT) bms.bms_total_acd / bms.bms_total));
  3065.                 EGPrintTB();
  3066.                 };
  3067.  
  3068.             if (bms.bms_acnflag)
  3069.                 {
  3070.                 sprintf(tbufv, "total acn: %ld   mean total acn: %.2f\n",
  3071.                     bms.bms_total_acn,
  3072.                     ((lrT) bms.bms_total_acn / bms.bms_total));
  3073.                 EGPrintTB();
  3074.                 };
  3075.  
  3076.             if (bms.bms_acsflag)
  3077.                 {
  3078.                 sprintf(tbufv, "total acs: %ld   mean total acs: %.2f\n",
  3079.                     bms.bms_total_acs,
  3080.                     ((lrT) bms.bms_total_acs / bms.bms_total));
  3081.                 EGPrintTB();
  3082.                 };
  3083.  
  3084.             if (bms.bms_acnflag && bms.bms_acsflag)
  3085.                 if (bms.bms_total_acs != 0)
  3086.                     {
  3087.                     sprintf(tbufv, "total mean node frequency: %.2f Hz\n",
  3088.                         ((lrT) bms.bms_total_acn / bms.bms_total_acs));
  3089.                     EGPrintTB();
  3090.                     };
  3091.  
  3092.             sprintf(tbufv, "solve: %ld   solve percent: %.2f\n",
  3093.                 bms.bms_solve,
  3094.                 (((lrT) bms.bms_solve * 100.0) / bms.bms_total));
  3095.             EGPrintTB();
  3096.             if (bms.bms_solve != 0)
  3097.                 {
  3098.                 if (bms.bms_acdflag)
  3099.                     {
  3100.                     sprintf(tbufv, "solve acd: %ld   mean solve acd: %.2f\n",
  3101.                         bms.bms_solve_acd,
  3102.                         ((lrT) bms.bms_solve_acd / bms.bms_solve));
  3103.                     EGPrintTB();
  3104.                     };
  3105.  
  3106.                 if (bms.bms_acnflag)
  3107.                     {
  3108.                     sprintf(tbufv, "solve acn: %ld   mean solve acn: %.2f\n",
  3109.                         bms.bms_solve_acn,
  3110.                         ((lrT) bms.bms_solve_acn / bms.bms_solve));
  3111.                     EGPrintTB();
  3112.                     };
  3113.  
  3114.                 if (bms.bms_acsflag)
  3115.                     {
  3116.                     sprintf(tbufv, "solve acs: %ld   mean solve acs: %.2f\n",
  3117.                         bms.bms_solve_acs,
  3118.                         ((lrT) bms.bms_solve_acs / bms.bms_solve));
  3119.                     EGPrintTB();
  3120.                     };
  3121.  
  3122.                 if (bms.bms_acnflag && bms.bms_acsflag)
  3123.                     if (bms.bms_solve_acs != 0)
  3124.                         {
  3125.                         sprintf(tbufv, "solve mean node frequency: %.2f Hz\n",
  3126.                             ((lrT) bms.bms_solve_acn / bms.bms_solve_acs));
  3127.                         EGPrintTB();
  3128.                         };
  3129.                 };
  3130.  
  3131.             sprintf(tbufv, "unsol: %ld   unsol percent: %.2f\n",
  3132.                 bms.bms_unsol,
  3133.                 (((lrT) bms.bms_unsol * 100.0) / bms.bms_total));
  3134.             EGPrintTB();
  3135.             if (bms.bms_unsol != 0)
  3136.                 {
  3137.                 if (bms.bms_acdflag)
  3138.                     {
  3139.                     sprintf(tbufv, "unsol acd: %ld   mean unsol acd: %.2f\n",
  3140.                         bms.bms_unsol_acd,
  3141.                         ((lrT) bms.bms_unsol_acd / bms.bms_unsol));
  3142.                     EGPrintTB();
  3143.                     };
  3144.  
  3145.                 if (bms.bms_acnflag)
  3146.                     {
  3147.                     sprintf(tbufv, "unsol acn: %ld   mean unsol acn: %.2f\n",
  3148.                         bms.bms_unsol_acn,
  3149.                         ((lrT) bms.bms_unsol_acn / bms.bms_unsol));
  3150.                     EGPrintTB();
  3151.                     };
  3152.  
  3153.                 if (bms.bms_acsflag)
  3154.                     {
  3155.                     sprintf(tbufv, "unsol acs: %ld   mean unsol acs: %.2f\n",
  3156.                         bms.bms_unsol_acs,
  3157.                         ((lrT) bms.bms_unsol_acs / bms.bms_unsol));
  3158.                     EGPrintTB();
  3159.                     };
  3160.  
  3161.                 if (bms.bms_acnflag && bms.bms_acsflag)
  3162.                     if (bms.bms_unsol_acs != 0)
  3163.                         {
  3164.                         sprintf(tbufv, "unsol mean node frequency: %.2f Hz\n",
  3165.                             ((lrT) bms.bms_unsol_acn / bms.bms_unsol_acs));
  3166.                         EGPrintTB();
  3167.                         };
  3168.                 };
  3169.             };
  3170.         };
  3171.     };
  3172.  
  3173. return (flag);
  3174. }
  3175.  
  3176. /*--> EGProcessSHOW: process the EG command epdshow */
  3177. static
  3178. siT
  3179. EGProcessSHOW(void)
  3180. {
  3181. siT flag;
  3182. charptrT s;
  3183.  
  3184. /* this is an internal EPD glue routine */
  3185.  
  3186. /* set the default return value: success */
  3187.  
  3188. flag = 1;
  3189.  
  3190. /* parameter count check */
  3191.  
  3192. if (EPDTokenCount() != 1)
  3193.     {
  3194.     EGPL("This command takes no parameters.");
  3195.     flag = 0;
  3196.     };
  3197.  
  3198. /* process the epdshow command */
  3199.  
  3200. if (flag)
  3201.     {
  3202.     /* load the host pointion into the EPD Kit */
  3203.  
  3204.     EGGetHostPosition();
  3205.  
  3206.     /* get the EPD string for the current position */
  3207.  
  3208.     s = EPDGenBasicCurrent();
  3209.  
  3210.     /* print and release */
  3211.  
  3212.     sprintf(tbufv, "%s\n", s);
  3213.     EGPrintTB();
  3214.     EPDMemoryFree(s);
  3215.     };
  3216.  
  3217. return (flag);
  3218. }
  3219.  
  3220. /*--> EGProcessSPGN: process the EG command epdspgn */
  3221. static
  3222. siT
  3223. EGProcessSPGN(void)
  3224. {
  3225. siT flag;
  3226. charptrT s;
  3227. fptrT fptr;
  3228.  
  3229. /* this is an internal EPD glue routine */
  3230.  
  3231. /* set the default return value: success */
  3232.  
  3233. flag = 1;
  3234.  
  3235. /* parameter count check */
  3236.  
  3237. if (EPDTokenCount() != 2)
  3238.     {
  3239.     EGPL("This command takes one parameter.");
  3240.     flag = 0;
  3241.     };
  3242.  
  3243. /* process the epdspgn command */
  3244.  
  3245. if (flag)
  3246.     {
  3247.     s = EGEncodeHostHistory();
  3248.     if (s == NULL)
  3249.         flag = 0;
  3250.     else
  3251.         {
  3252.         fptr = fopen(EPDTokenFetch(1), "w");
  3253.         if (fptr == NULL)
  3254.             flag = 0;
  3255.         else
  3256.             {
  3257.             fprintf(fptr, "%s", s);
  3258.             fclose(fptr);
  3259.             };
  3260.         EPDMemoryFree(s);
  3261.         };
  3262.     };
  3263.  
  3264. return (flag);
  3265. }
  3266.  
  3267. /*--> EGProcessSTPV: process the EG command epdstpv */
  3268. static
  3269. siT
  3270. EGProcessSTPV(void)
  3271. {
  3272. siT flag;
  3273. pgnstrT pgnstr;
  3274. charptrT s;
  3275. liT i, length;
  3276.  
  3277. /* this is an internal EPD glue routine */
  3278.  
  3279. /* set the default return value: success */
  3280.  
  3281. flag = 1;
  3282.  
  3283. /* parameter count check */
  3284.  
  3285. if (EPDTokenCount() != 3)
  3286.     {
  3287.     EGPL("This command takes two parameters");
  3288.     flag = 0;
  3289.     };
  3290.  
  3291. /* process the epdstpv command */
  3292.  
  3293. if (flag)
  3294.     {
  3295.     pgnstr = EPDPGNFetchTagIndex(EPDTokenFetch(1));
  3296.     if (pgnstr == pgnstr_nil)
  3297.         {
  3298.         EGPL("Unknown tag name; available tag names are:");
  3299.         for (pgnstr = 0; pgnstr < pgnstrL; pgnstr++)
  3300.             {
  3301.             EGPrint("   ");
  3302.             EGPrint(EPDPGNFetchTagName(pgnstr));
  3303.             };
  3304.         EGPrint("\n");
  3305.         flag = 0;
  3306.         }
  3307.     else
  3308.         {
  3309.         /* change underscore characters to blanks */
  3310.  
  3311.         s = EPDStringGrab(EPDTokenFetch(2));
  3312.         length = strlen(s);
  3313.  
  3314.         for (i = 0; i < length; i++)
  3315.             if (*(s + i) == '_')
  3316.                 *(s + i) = ' ';
  3317.  
  3318.         EPDPGNPutSTR(default_gamptr, pgnstr, s);
  3319.         EPDMemoryFree(s);
  3320.         };
  3321.     };
  3322.  
  3323. return (flag);
  3324. }
  3325.  
  3326. /*--> EGProcessTEST: process the EG command epdtest */
  3327. static
  3328. siT
  3329. EGProcessTEST(void)
  3330. {
  3331. siT flag;
  3332.  
  3333. /* this is an internal EPD glue routine */
  3334.  
  3335. /* set the default return value: success */
  3336.  
  3337. flag = 1;
  3338.  
  3339. /* parameter count check */
  3340.  
  3341. if (EPDTokenCount() != 1)
  3342.     {
  3343.     EGPL("This command takes no parameters.");
  3344.     flag = 0;
  3345.     };
  3346.  
  3347. /* process the epdtest command */
  3348.  
  3349. if (flag)
  3350.     {
  3351.     EGPL("This command is not yet implemented.");
  3352.     flag = 0;
  3353.     };
  3354.  
  3355. return (flag);
  3356. }
  3357.  
  3358. /*--> EGCommandParmCount: return parameter count for a command */
  3359. nonstatic
  3360. int
  3361. EGCommandParmCount(char *s)
  3362. {
  3363. siT count;
  3364. egcommT egcomm;
  3365.  
  3366. /* this is called by Option() in option.c */
  3367.  
  3368. /*
  3369. This routine is required for interfacing with Crafty to support EPD glue
  3370. command line construction.  Because Crafty only distributes command input
  3371. one token at a time, it is necessary to have input processor code in
  3372. Option() assemble an EPD glue command line complete with parameter tokens.
  3373. To assist with this task, the code in Option has to have a way of knowing
  3374. how many parameters are associated with a given EPD glue command.
  3375.  
  3376. Note that the Crafty is unable to uniformly process commands that have a
  3377. variable number of parameters.  This is why every EPD glue command
  3378. parameter count in this integration is fixed for the corresponding command.
  3379.  
  3380. Other implementations may send an entire command text line.  This is a
  3381. simpler approach and also easily supports having a variable number of
  3382. parameters for EPD glue commands.  For these other implementations, the
  3383. driver code in the host program need only call the EGCommand() routine
  3384. with the whole command input string as the single EGCommand() parameter.
  3385. */
  3386.  
  3387. /* get command index */
  3388.  
  3389. egcomm = EGLocateCommand(s);
  3390.  
  3391. if (egcomm == egcomm_nil)
  3392.     count = 0;
  3393. else
  3394.     count = egparmcountv[egcomm];
  3395.  
  3396. return (count);
  3397. }
  3398.  
  3399. /*--> EGCommandCheck: check if a string starts with an EPD command token */
  3400. nonstatic
  3401. int
  3402. EGCommandCheck(char *s)
  3403. {
  3404. siT flag;
  3405. charptrT tokenptr;
  3406. egcommT egcomm;
  3407.  
  3408. /* this routine is called from Option() in option.c */
  3409.  
  3410. /*
  3411. This routine is used to quickly check if an input command line starts with
  3412. one of the available EPD glue command tokens.  The idea is that EPD action
  3413. can be quickly selected (or deselected) for any command input text string.
  3414.  
  3415. Because Crafty distributes command input one token at a time, the calls to
  3416. this routine in this implementation will only have a single token for input.
  3417. Other implementations that use an entire input command line will use the
  3418. full power of this routine which includes token scanning and recording
  3419. which is handled by the EPD Kit routines in the epd.c file.
  3420. */
  3421.  
  3422. /* set default return value: no match */
  3423.  
  3424. flag = 0;
  3425.  
  3426. /* tokenize the input string */
  3427.  
  3428. EPDTokenize(s);
  3429.  
  3430. /* was there at least one token? */
  3431.  
  3432. if (EPDTokenCount() > 0)
  3433.     {
  3434.     /* get a pointer to the first token (origin zero) */
  3435.  
  3436.     tokenptr = EPDTokenFetch(0);
  3437.  
  3438.     /* get the glue command indicator */
  3439.  
  3440.     egcomm = EGLocateCommand(tokenptr);
  3441.  
  3442.     /* was there a command match? */
  3443.  
  3444.     if (egcomm != egcomm_nil)
  3445.         flag = 1;
  3446.     };
  3447.  
  3448. return (flag);
  3449. }
  3450.  
  3451. /*--> EGCommand: process an EPD command string */
  3452. nonstatic
  3453. int
  3454. EGCommand(char *s)
  3455. {
  3456. siT flag;
  3457. egcommT egcomm;
  3458.  
  3459. /* this routine is called from Option() in option.c */
  3460.  
  3461. /*
  3462. This routine actviates EPD glue command processing.  it is called with a
  3463. string that represents an entire EPD glue command input, including any
  3464. parameters following the command.
  3465.  
  3466. Because Crafty distributes command input one token at a time, it is
  3467. necessary for the host calling code to assemble a command line from the
  3468. input token stream.  See the code in Option() for details.
  3469. */
  3470.  
  3471. /* set the default return value: success */
  3472.  
  3473. flag = 1;
  3474.  
  3475. /* check the command string (this also tokenizes it) */
  3476.  
  3477. if (EGCommandCheck(s))
  3478.     egcomm = EGLocateCommand(EPDTokenFetch(0));
  3479. else
  3480.     egcomm = egcomm_nil;
  3481.  
  3482. /* was a valid EPD glue command located? */
  3483.  
  3484. if (egcomm == egcomm_nil)
  3485.     {
  3486.     EGPL("EG fault: can't locate valid EG command");
  3487.     flag = 0;
  3488.     }
  3489. else
  3490.     {
  3491.     /* a valid command token was found; perform command dispatch */
  3492.  
  3493.     switch (egcomm)
  3494.         {
  3495.         case egcomm_epdapgn:
  3496.             flag = EGProcessAPGN();
  3497.             break;
  3498.  
  3499.         case egcomm_epdbfix:
  3500.             flag = EGProcessBFIX();
  3501.             break;
  3502.  
  3503.         case egcomm_epdcert:
  3504.             flag = EGProcessCERT();
  3505.             break;
  3506.  
  3507.         case egcomm_epdcics:
  3508.             flag = EGProcessCICS();
  3509.             break;
  3510.  
  3511.         case egcomm_epdcomm:
  3512.             flag = EGProcessCOMM();
  3513.             break;
  3514.  
  3515.         case egcomm_epddpgn:
  3516.             flag = EGProcessDPGN();
  3517.             break;
  3518.  
  3519.         case egcomm_epddsml:
  3520.             flag = EGProcessDSML();
  3521.             break;
  3522.  
  3523.         case egcomm_epddstr:
  3524.             flag = EGProcessDSTR();
  3525.             break;
  3526.  
  3527.         case egcomm_epddtpv:
  3528.             flag = EGProcessDTPV();
  3529.             break;
  3530.  
  3531.         case egcomm_epdenum:
  3532.             flag = EGProcessENUM();
  3533.             break;
  3534.  
  3535.         case egcomm_epdhelp:
  3536.             flag = EGProcessHELP();
  3537.             break;
  3538.  
  3539.         case egcomm_epdlink:
  3540.             flag = EGProcessLINK();
  3541.             break;
  3542.  
  3543.         case egcomm_epdlpgn:
  3544.             flag = EGProcessLPGN();
  3545.             break;
  3546.  
  3547.         case egcomm_epdlrec:
  3548.             flag = EGProcessLREC();
  3549.             break;
  3550.  
  3551.         case egcomm_epdmore:
  3552.             flag = EGProcessMORE();
  3553.             break;
  3554.  
  3555.         case egcomm_epdnoop:
  3556.             flag = EGProcessNOOP();
  3557.             break;
  3558.  
  3559.         case egcomm_epdpfdn:
  3560.             flag = EGProcessPFDN();
  3561.             break;
  3562.  
  3563.         case egcomm_epdpfdr:
  3564.             flag = EGProcessPFDR();
  3565.             break;
  3566.  
  3567.         case egcomm_epdpfga:
  3568.             flag = EGProcessPFGA();
  3569.             break;
  3570.  
  3571.         case egcomm_epdpflc:
  3572.             flag = EGProcessPFLC();
  3573.             break;
  3574.  
  3575.         case egcomm_epdpfop:
  3576.             flag = EGProcessPFOP();
  3577.             break;
  3578.  
  3579.         case egcomm_epdscor:
  3580.             flag = EGProcessSCOR();
  3581.             break;
  3582.  
  3583.         case egcomm_epdshow:
  3584.             flag = EGProcessSHOW();
  3585.             break;
  3586.  
  3587.         case egcomm_epdspgn:
  3588.             flag = EGProcessSPGN();
  3589.             break;
  3590.  
  3591.         case egcomm_epdstpv:
  3592.             flag = EGProcessSTPV();
  3593.             break;
  3594.  
  3595.         case egcomm_epdtest:
  3596.             flag = EGProcessTEST();
  3597.             break;
  3598.         };
  3599.  
  3600.     /* check result */
  3601.  
  3602.     if (!flag)
  3603.         {
  3604.         sprintf(tbufv,
  3605.             "EG fault: a problem occurred during %s processing\n",
  3606.             EPDTokenFetch(0));
  3607.         EGPrintTB();
  3608.         };
  3609.     };
  3610.  
  3611. return (flag);
  3612. }
  3613.  
  3614. /*--> EGInit: one time EPD glue initialization */
  3615. nonstatic
  3616. void
  3617. EGInit(void)
  3618. {
  3619. tbidT tbid;
  3620. cT c;
  3621. siT count;
  3622.  
  3623. /* this is called by Initialize() in init.c */
  3624.  
  3625. EGPL("EPD Kit revision date: 1996.04.21");
  3626.  
  3627. /* call the EPD one time set up code */
  3628.  
  3629. EPDInit();
  3630.  
  3631. /* initialize the EPD glue command strings vector */
  3632.  
  3633. egcommstrv[egcomm_epdapgn] = "epdapgn";
  3634. egcommstrv[egcomm_epdbfix] = "epdbfix";
  3635. egcommstrv[egcomm_epdcert] = "epdcert";
  3636. egcommstrv[egcomm_epdcics] = "epdcics";
  3637. egcommstrv[egcomm_epdcomm] = "epdcomm";
  3638. egcommstrv[egcomm_epddpgn] = "epddpgn";
  3639. egcommstrv[egcomm_epddsml] = "epddsml";
  3640. egcommstrv[egcomm_epddstr] = "epddstr";
  3641. egcommstrv[egcomm_epddtpv] = "epddtpv";
  3642. egcommstrv[egcomm_epdenum] = "epdenum";
  3643. egcommstrv[egcomm_epdhelp] = "epdhelp";
  3644. egcommstrv[egcomm_epdlink] = "epdlink";
  3645. egcommstrv[egcomm_epdlpgn] = "epdlpgn";
  3646. egcommstrv[egcomm_epdlrec] = "epdlrec";
  3647. egcommstrv[egcomm_epdmore] = "epdmore";
  3648. egcommstrv[egcomm_epdnoop] = "epdnoop";
  3649. egcommstrv[egcomm_epdpfdn] = "epdpfdn";
  3650. egcommstrv[egcomm_epdpfdr] = "epdpfdr";
  3651. egcommstrv[egcomm_epdpfga] = "epdpfga";
  3652. egcommstrv[egcomm_epdpflc] = "epdpflc";
  3653. egcommstrv[egcomm_epdpfop] = "epdpfop";
  3654. egcommstrv[egcomm_epdscor] = "epdscor";
  3655. egcommstrv[egcomm_epdshow] = "epdshow";
  3656. egcommstrv[egcomm_epdspgn] = "epdspgn";
  3657. egcommstrv[egcomm_epdstpv] = "epdstpv";
  3658. egcommstrv[egcomm_epdtest] = "epdtest";
  3659.  
  3660. /* initialize the EPD glue command string descriptions vector */
  3661.  
  3662. eghelpstrv[egcomm_epdapgn] = "Append PGN game to <file>";
  3663. eghelpstrv[egcomm_epdbfix] = "Fix <file1> data for Bookup input <file2>";
  3664. eghelpstrv[egcomm_epdcert] = "Display certain score for the current position";
  3665. eghelpstrv[egcomm_epdcics] = "Slave to ICS at <hostname> and <portnumber>";
  3666. eghelpstrv[egcomm_epdcomm] = "Slave to Duplex using <pipefile-basename>";
  3667. eghelpstrv[egcomm_epddpgn] = "Display game using PGN";
  3668. eghelpstrv[egcomm_epddsml] = "Display SAN move list";
  3669. eghelpstrv[egcomm_epddstr] = "Display PGN Seven Tag Roster";
  3670. eghelpstrv[egcomm_epddtpv] = "Display PGN tag pair <tag-name> value";
  3671. eghelpstrv[egcomm_epdenum] = "Enumerate to <depth> from <file1> to <file2>";
  3672. eghelpstrv[egcomm_epdhelp] = "Display EPD glue command descriptions";
  3673. eghelpstrv[egcomm_epdlink] = "Slave to Argus at <hostname> and <portnumber>";
  3674. eghelpstrv[egcomm_epdlpgn] = "Load PGN game from <file>";
  3675. eghelpstrv[egcomm_epdlrec] = "Load EPD record from <file> <line-number>";
  3676. eghelpstrv[egcomm_epdmore] = "Display more help for <command>";
  3677. eghelpstrv[egcomm_epdnoop] = "No operation";
  3678. eghelpstrv[egcomm_epdpfdn] = "Normalize EPD data from <file1> to <file2>";
  3679. eghelpstrv[egcomm_epdpfdr] = "Repair EPD data from <file1> to <file2>";
  3680. eghelpstrv[egcomm_epdpfga] = "Analyze EPD data from <file1> to <file2>";
  3681. eghelpstrv[egcomm_epdpflc] = "Locate mating cooks in result <file>";
  3682. eghelpstrv[egcomm_epdpfop] = "Purge EPD <opcode> from <file1> to <file2>";
  3683. eghelpstrv[egcomm_epdscor] = "Score benchmark EPD results from <file>";
  3684. eghelpstrv[egcomm_epdshow] = "Show EPD four fields for the current position";
  3685. eghelpstrv[egcomm_epdspgn] = "Save PGN game to <file>";
  3686. eghelpstrv[egcomm_epdstpv] = "Set PGN tag pair <tag-name> to <value>";
  3687. eghelpstrv[egcomm_epdtest] = "EPD glue developer testing";
  3688.  
  3689. /* initialize the EPD glue command parameter counts vector */
  3690.  
  3691. egparmcountv[egcomm_epdapgn] = 2;
  3692. egparmcountv[egcomm_epdbfix] = 3;
  3693. egparmcountv[egcomm_epdcert] = 1;
  3694. egparmcountv[egcomm_epdcics] = 3;
  3695. egparmcountv[egcomm_epdcomm] = 2;
  3696. egparmcountv[egcomm_epddpgn] = 1;
  3697. egparmcountv[egcomm_epddsml] = 1;
  3698. egparmcountv[egcomm_epddstr] = 1;
  3699. egparmcountv[egcomm_epddtpv] = 2;
  3700. egparmcountv[egcomm_epdenum] = 4;
  3701. egparmcountv[egcomm_epdhelp] = 1;
  3702. egparmcountv[egcomm_epdlink] = 3;
  3703. egparmcountv[egcomm_epdlpgn] = 2;
  3704. egparmcountv[egcomm_epdlrec] = 3;
  3705. egparmcountv[egcomm_epdmore] = 2;
  3706. egparmcountv[egcomm_epdnoop] = 1;
  3707. egparmcountv[egcomm_epdpfdn] = 3;
  3708. egparmcountv[egcomm_epdpfdr] = 3;
  3709. egparmcountv[egcomm_epdpfga] = 3;
  3710. egparmcountv[egcomm_epdpflc] = 2;
  3711. egparmcountv[egcomm_epdpfop] = 4;
  3712. egparmcountv[egcomm_epdscor] = 2;
  3713. egparmcountv[egcomm_epdshow] = 1;
  3714. egparmcountv[egcomm_epdspgn] = 2;
  3715. egparmcountv[egcomm_epdstpv] = 3;
  3716. egparmcountv[egcomm_epdtest] = 1;
  3717.  
  3718. /* set up the default game structure */
  3719.  
  3720. default_gamptr = EPDGameOpen();
  3721.  
  3722. /* tablebase survey */
  3723.  
  3724. count = 0;
  3725. for (tbid = 0; tbid < tbidL; tbid++)
  3726.     for (c = c_w; c <= c_b; c++)
  3727.         if (EPDTBIsFilePresent(tbid, c))
  3728.             count++;
  3729.  
  3730. if (count == 0)
  3731.     {
  3732.     sprintf(tbufv,
  3733.         "No tablebase files found in the %s directory.\n",
  3734.         tb_path);
  3735.     EGPrintTB();
  3736.     }
  3737. else
  3738.     {
  3739.     sprintf(tbufv,
  3740.         "%hd tablebase file(s) found in the %s directory.\n",
  3741.         count, tb_path);
  3742.     EGPrintTB();
  3743.     };
  3744.  
  3745. return;
  3746. }
  3747.  
  3748. /*--> EGTerm: one time EPD glue termination */
  3749. nonstatic
  3750. void
  3751. EGTerm(void)
  3752. {
  3753. /* this is called by Option() in option.c */
  3754.  
  3755. /* release the default game structure */
  3756.  
  3757. if (default_gamptr != NULL)
  3758.     EPDGameClose(default_gamptr);
  3759.  
  3760. /* call the EPD one time close down code */
  3761.  
  3762. EPDTerm();
  3763.  
  3764. return;
  3765. }
  3766.  
  3767. /*<<< epdglue.c: EOF */
  3768.