home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / gnuch40.zip / gnuchess-4.0.pl79 / src / eco.c < prev    next >
C/C++ Source or Header  |  1999-01-15  |  17KB  |  690 lines

  1. /*
  2.  * eco.c - C source for GNU CHESS
  3.  *
  4.  * Copyright (c) 1985-1996 Stuart Cracraft, John Stanback,
  5.  *                         Daryl Baker, Conor McCarthy,
  6.  *                         Mike McGann, Chua Kong Sian
  7.  * Copyright (c) 1985-1996 Free Software Foundation
  8.  *
  9.  * This file is part of GNU CHESS.
  10.  *
  11.  * GNU Chess is free software; you can redistribute it and/or modify it under
  12.  * the terms of the GNU General Public License as published by the Free
  13.  * Software Foundation; either version 2, or (at your option) any later
  14.  * version.
  15.  *
  16.  * GNU Chess is distributed in the hope that it will be useful, but WITHOUT ANY
  17.  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  18.  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  19.  * details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License along with
  22.  * GNU Chess; see the file COPYING.  If not, write to the Free Software
  23.  * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  */
  25. #include "gnuchess.h"
  26. #include "ttable.h" /* uses hashbd, hashkey */
  27. #include "ataks.h"
  28. #if !defined(AMIGADOS) && !defined(Think_C)
  29. #include <unistd.h>
  30. #endif
  31. #ifdef Think_C
  32. #include <unix.h>
  33. #endif
  34.  
  35. #ifdef MSDOS
  36. #include <io.h>
  37. #endif
  38. #if !defined MSDOS && !defined(Think_C) && !defined(__EMX__)
  39. #define O_BINARY 0
  40. #endif
  41. #include <fcntl.h>
  42. unsigned long booksize = BOOKSIZE;
  43. unsigned long int BKTBLSIZE;
  44. unsigned long BOOKMASK;
  45. unsigned long bookcount = 0;
  46. unsigned bookpocket = BOOKPOCKET;
  47. unsigned int curecoptr;
  48.  
  49. UTSHORT bookmaxply = BOOKMAXPLY;
  50.  
  51. CHAR *bookfile = NULL;
  52. CHAR *binbookfile = BINBOOK;
  53.  
  54. int GotBook = false;
  55. static CHAR bmvstr[5][6];
  56. unsigned long bhashbd, bhashkey;
  57.  
  58.  
  59. void
  60. Balgbr (SHORT f, SHORT t, SHORT flag)
  61.  
  62.  
  63.      /*
  64.       * Generate move strings in different formats.
  65.       */
  66.  
  67. {
  68.     int m3p;
  69.     bmvstr[0][0] = bmvstr[1][0] = bmvstr[2][0] = bmvstr[3][0] = bmvstr[4][0] = '\0';
  70.  
  71.     if (f != t)
  72.       {
  73.       /* algebraic notation */
  74.       bmvstr[0][0] = cxx[column (f)];
  75.       bmvstr[0][1] = rxx[row (f)];
  76.       bmvstr[0][2] = cxx[column (t)];
  77.       bmvstr[0][3] = rxx[row (t)];
  78.       bmvstr[0][4] = bmvstr[3][0] = '\0';
  79.       if (((bmvstr[1][0] = pxx[board[f]]) == 'P') || (flag & promote))
  80.         {
  81.         if (bmvstr[0][0] == bmvstr[0][2])    /* pawn did not eat */
  82.           {
  83.               bmvstr[2][0] = bmvstr[1][0] = bmvstr[0][2];    /* to column */
  84.               bmvstr[2][1] = bmvstr[1][1] = bmvstr[0][3];    /* to row */
  85.               m3p = 2;
  86.           }
  87.         else
  88.             /* pawn ate */
  89.           {
  90.               bmvstr[2][0] = bmvstr[1][0] = bmvstr[0][0];    /* column */
  91.               bmvstr[2][1] = bmvstr[1][1] = bmvstr[0][2];    /* to column */
  92.               bmvstr[2][2] = bmvstr[0][3];
  93.               m3p = 3;    /* to row */
  94.           }
  95.         if (flag & promote)
  96.           {
  97.               bmvstr[0][4] = bmvstr[1][2] = bmvstr[2][m3p] = qxx[flag & pmask];
  98.               bmvstr[0][5] = bmvstr[1][3] = bmvstr[2][m3p + 1] = bmvstr[3][0] = '\0';
  99.           }
  100.         else
  101.             bmvstr[2][m3p] = bmvstr[1][2] = '\0';
  102.                 if(flag & epmask){
  103.             bmvstr[3][0] = bmvstr[0][2];
  104.             bmvstr[3][1] = bmvstr[0][3];
  105.             bmvstr[3][2] = '\0';
  106.         }
  107.         }
  108.       else
  109.           /* not a pawn */
  110.         {
  111.         bmvstr[2][0] = bmvstr[1][0];
  112.         bmvstr[2][1] = bmvstr[0][1];
  113.         bmvstr[2][2] = bmvstr[1][1] = bmvstr[0][2];    /* to column */
  114.         bmvstr[2][3] = bmvstr[1][2] = bmvstr[0][3];    /* to row */
  115.         bmvstr[2][4] = bmvstr[1][3] = '\0';
  116.         strcpy (bmvstr[3], bmvstr[2]);
  117.         bmvstr[3][1] = bmvstr[0][0];
  118.         bmvstr[4][0] = bmvstr[1][0]; strcpy(&bmvstr[4][1],bmvstr[0]);
  119.         if (flag & cstlmask)
  120.           {
  121.               if (t > f)
  122.             {
  123.                 strcpy (bmvstr[1], bmvstr[0]);
  124.                 strcpy (bmvstr[0], CP[5]);
  125.                 strcpy (bmvstr[2], CP[7]);
  126.             }
  127.               else
  128.             {
  129.                 strcpy (bmvstr[1], bmvstr[0]);
  130.                 strcpy (bmvstr[0], CP[6]);
  131.                 strcpy (bmvstr[2], CP[8]);
  132.             }
  133.           }
  134.         }
  135.       }
  136.     else
  137.     bmvstr[0][0] = bmvstr[1][0] = bmvstr[2][0] = bmvstr[3][0] = bmvstr[4][0] = '\0';
  138. }
  139.  
  140.  
  141. #ifndef QUIETBOOKGEN
  142. void
  143. bkdisplay (s, cnt, moveno)
  144.      CHAR *s;
  145.      int cnt;
  146.      int moveno;
  147. {
  148.     static SHORT pnt;
  149. #ifndef SEMIQUIETBOOKGEN
  150.     struct leaf *node;
  151.     int r, c, l;
  152. #endif
  153.  
  154.     pnt = TrPnt[2];
  155.     printf ("matches = %d\n", cnt);
  156.     printf ("inout move is :%s:move number %d side %s\n", s, moveno / 2 + 1, !(moveno & 1) ? "white" : "black");
  157. #ifndef SEMIQUIETBOOKGEN
  158.     printf ("legal moves are \n");
  159.     while (pnt < TrPnt[3])
  160.       {
  161.       node = &Tree[pnt++];
  162.       Balgbr (node->f, node->t, (SHORT) node->flags);
  163.       printf ("%s %s %s %s %s\n", bmvstr[0], bmvstr[1], bmvstr[2], bmvstr[3],bmvstr[4]);
  164.       }
  165.     printf ("\n current board is\n");
  166.     for (r = 7; r >= 0; r--)
  167.       {
  168.       for (c = 0; c <= 7; c++)
  169.         {
  170.         l = locn (r, c);
  171.         if (color[l] == neutral)
  172.             printf (" -");
  173.         else if (color[l] == white)
  174.             printf (" %c", qxx[board[l]]);
  175.         else
  176.             printf (" %c", pxx[board[l]]);
  177.         }
  178.       printf ("\n");
  179.       }
  180.     printf ("\n\n");
  181. #endif
  182. }
  183.  
  184. #endif
  185.  
  186. int
  187. BVerifyMove (CHAR *s, UTSHORT *mv, int moveno)
  188.  
  189.      /*
  190.       * Compare the string 's' to the list of legal moves available for the
  191.       * opponent. If a match is found, make the move on the board.
  192.       */
  193.  
  194. {
  195.     static SHORT pnt, tempb, tempc, tempsf, tempst, cnt;
  196.     static struct leaf xnode;
  197.     struct leaf *node;
  198.  
  199.     *mv = 0;
  200.     cnt = 0;
  201.     VMoveList (opponent, 2);
  202.     pnt = TrPnt[2];
  203.     while (pnt < TrPnt[3])
  204.       {
  205.       node = &Tree[pnt++];
  206.       Balgbr (node->f, node->t, (SHORT) node->flags);
  207.       if (strcmp (s, bmvstr[0]) == 0 || strcmp (s, bmvstr[1]) == 0 ||
  208.           strcmp (s, bmvstr[2]) == 0 || strcmp (s, bmvstr[3]) == 0 || strcmp (s, bmvstr[4]) == 0)
  209.         {
  210.         cnt++;
  211.         xnode = *node;
  212.         }
  213.       }
  214.     if (cnt == 1)
  215.       {
  216.       MakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
  217.       if (SqAtakd (PieceList[opponent][0], computer))
  218.         {
  219.         UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
  220.         /* Illegal move in check */
  221. #ifndef QUIETBOOKGEN
  222.         printf (CP[77]);
  223.         printf ("\n");
  224.         bkdisplay (s, cnt, moveno);
  225. #endif
  226.         return (false);
  227.         }
  228.       else
  229.         {
  230.         *mv = (xnode.f << 8) | xnode.t;
  231.         Balgbr (xnode.f, xnode.t, false);
  232.         if (board[xnode.t] == pawn){
  233.                 if (xnode.t - xnode.f == 16)
  234.                       epsquare = xnode.f + 8;
  235.                 else if (xnode.f - xnode.t == 16)
  236.                       epsquare = xnode.f - 8;}
  237.             else epsquare = -1;
  238.  
  239.         return (true);
  240.         }
  241.       }
  242.     /* Illegal move */
  243. #ifndef QUIETBOOKGEN
  244.     printf (CP[75], s);
  245.     bkdisplay (s, cnt, moveno);
  246. #endif
  247.     return (false);
  248. }
  249.  
  250. void
  251. RESET (void)
  252.  
  253.      /*
  254.       * Reset the board and other variables to start a new game.
  255.       */
  256.  
  257. {
  258.     SHORT l;
  259.  
  260.     flag.illegal = flag.mate = flag.post = flag.quit = flag.reverse = flag.bothsides = flag.onemove = flag.force = false;
  261.     flag.material = flag.coords = flag.hash = flag.easy = flag.rcptr = true;
  262.     flag.stars = flag.shade = flag.back = flag.musttimeout = false;
  263. #ifdef CHESSTOOL
  264.     flag.beep=false;
  265. #else
  266.     flag.beep=true;
  267. #endif
  268. #ifdef CLIENT
  269.     flag.gamein = true;
  270. #else
  271.     flag.gamein = false;
  272. #endif
  273.     GenCnt = epsquare = 0;
  274.     GameCnt = 0;
  275.     Developed[white] = Developed[black] = false;
  276.     castld[white] = castld[black] = false;
  277.     PawnThreat[0] = CptrFlag[0] = false;
  278.     opponent = white;
  279.     computer = black;
  280.     for (l = 0; l < 64; l++)
  281.       {
  282.       board[l] = Stboard[l];
  283.       color[l] = Stcolor[l];
  284.       Mvboard[l] = 0;
  285.       }
  286.     InitializeStats ();
  287. }
  288.  
  289.  
  290. int 
  291. gnc (FILE * fd)
  292. {
  293.   int c;
  294.   c = getc (fd);
  295.   if (c == '(')
  296.     {
  297.       do
  298.     {
  299.       c = getc (fd);
  300.       if (c == ')')
  301.         {
  302.           c = getc (fd);
  303.           break;
  304.         }
  305.       if (c == EOF)
  306.         break;
  307.     }
  308.       while (true);
  309.     }
  310.   else if (c == '{')
  311.     {
  312.       do
  313.     {
  314.       c = getc (fd);
  315.       if (c == '}')
  316.         {
  317.           c = getc (fd);
  318.           break;
  319.         }
  320.       if (c == EOF)
  321.         break;
  322.     }
  323.       while (true);
  324.     }
  325.   return c;
  326. }
  327.  
  328. int
  329. Vparse (FILE * fd, UTSHORT *mv, SHORT side, CHAR *opening, int moveno)
  330. {
  331.   register int c, i;
  332.   CHAR s[128];
  333.   CHAR *p;
  334.  
  335.   while (true)
  336.     {
  337.  
  338.       while ((c = gnc (fd)) == ' ' || c == '\n');
  339.       if (c == '\r') continue;
  340.       i = 0;
  341.       if (c == '#' || c == '[' || c == '%')
  342.     {            /* comment */
  343.           curecoptr = ftell(fd);
  344.       p = opening;
  345.       do
  346.         {
  347.           *p++ = c;
  348.           c = gnc (fd);
  349.           if (c == '\r') continue;
  350.           /* goes to end of line */
  351.           if (c == '\n')
  352.         {
  353.           /* does the comment continue */
  354.           if ((c = getc (fd)) == '[') continue;
  355.           ungetc (c, fd);
  356.           *p = '\0';
  357.           return 0;
  358.           } if (c == EOF) return -1;
  359.         }
  360.       while (true);
  361.     }
  362.       /* is it a move number or analysis ( in [ ] or in { } ) */
  363.       /* number cannot start with a 0 because of 0-0 */
  364.       else if (!isalpha (c) && c != '0')
  365.     {
  366.       int nl = false;
  367.       int nonspace = false;
  368.  
  369.       while (true)
  370.         {
  371.           c = gnc (fd);
  372.           if (nl)
  373.         if (c == '#' || c == '[' || c == '%')
  374.           {
  375.             ungetc (c, fd);
  376.             return 0;
  377.           }
  378.           if (c == '\r')
  379.         continue;
  380.           if (c == '\n')
  381.         {
  382.           nl = true;
  383.           continue;
  384.         }
  385.           else
  386.         nl = false;
  387.           if (c == EOF)
  388.         {
  389.           return -1;
  390.         }
  391.           /* stop at first nonspace a ... is space */
  392.           /* must be nonspace because of 0-0 */
  393.           if (nonspace)
  394.         {
  395.           if (c != '.' && c != ' ')
  396.             break;
  397.         }
  398.           if (c == '.')
  399.         {
  400.           nonspace = true;
  401.         }
  402.           /* stop if alpha must be move */
  403.           else if (isalpha (c))
  404.         break;
  405.         }
  406.     }
  407.       s[0] = (CHAR) c;
  408.  
  409.       while ((c = gnc (fd)) != '\n' && c != ' ' && c != '\t' && c != EOF)
  410.     {
  411.       if (isupper (c))
  412.         {
  413.           if (c != 'O')
  414.         {
  415.           ungetc (c, fd);
  416.           c = ' ';
  417.           break;
  418.         }
  419.         }
  420.       if (c == '\r') continue;
  421.       if (c == '?') break;
  422.       if (c == '!') continue;
  423.       if (c == '+') continue;
  424.       if (c == '#') continue;
  425.       if (c == '%') continue;
  426.       if (c == '='){c = gnc(fd); c=tolower(c);}
  427.       if (c != 'x') s[++i] = c;
  428.     }
  429.       s[++i] = '\0';
  430.  
  431.       if (c == EOF) return (-1);
  432.       if (s[0] == '!' || s[0] == ';')
  433.     {
  434.       while (c != '\n' && c != EOF) c = gnc (fd);
  435.       if (c == EOF) return -1;
  436.       else return (0);
  437.     }
  438.       if ((strcmp (s, "o-o-o") == 0) || (strcmp (s, "OOO") == 0) || (strcmp (s, "O-O-O") == 0) || (strcmp (s, "0-0-0") == 0))
  439.     {
  440.       if (side == black) strcpy (s, "e8c8");
  441.       else strcpy (s, "e1c1");
  442.     }
  443.       else if ((strcmp ("o-o", s) == 0) || (strcmp (s, "OO") == 0) || (strcmp (s, "O-O") == 0) || (strcmp (s, "0-0") == 0))
  444.     {
  445.       if (side == black) strcpy (s, "e8g8");
  446.       else strcpy (s, "e1g1");
  447.     }
  448.       else if (strcmp (s, "draw") == 0) continue;
  449.       else if (strcmp (s, "Draw") == 0) continue;
  450.       else if (strcmp (s, "1-0") == 0) continue;
  451.       else if (strcmp (s, "0-1") == 0) continue;
  452.       else if (strcmp (s, "2-1/2") == 0) continue;
  453.       if (isupper (s[i - 1]))
  454.     s[i - 1] = tolower (s[i - 1]);
  455.  
  456.  
  457.       i = BVerifyMove (s, mv, moveno);
  458.       bhashkey = hashkey;
  459.       bhashbd = hashbd;
  460.       if (c == '?')
  461.     {            /* Bad move, not for the program to play */
  462.       *mv |= BADMOVE;    /* Flag it ! */
  463.       c = getc (fd);
  464.     }
  465.       else if (c == '+' || c == '\r')
  466.     c = gnc (fd);
  467.       if (!i)
  468.     {
  469.       printf ("%s \n", opening);
  470.       /* flush to start of next */
  471.       while ((c = gnc (fd)) != '[' && c != EOF && c != '#');
  472.       if (c == EOF)
  473.         return -1;
  474.       else
  475.         {
  476.           ungetc (c, fd);
  477.           return i;
  478.         }
  479.     }
  480.       return (i);
  481.     }
  482. }
  483.  
  484.  
  485. /*===================================== GDX =======================================*/
  486.  
  487. struct gdxadmin
  488. {
  489.     unsigned long bookcount;
  490.     unsigned long booksize;
  491.     unsigned long maxoffset;
  492. } ADMIN, B;
  493.  
  494. struct gdxdata
  495. {
  496.     unsigned long hashbd;
  497.     unsigned long hashkey;
  498.     unsigned int ecoptr;
  499.     utshort cntr;
  500. } DATA;
  501.  
  502. #ifdef LONG64
  503. #define lts(x) (unsigned long)(((x)&(~1))|side)
  504. #else
  505. #define lts(x) (unsigned long)(((x)&(~1))|side)
  506. #endif
  507. unsigned long currentoffset;
  508. int gfd;
  509.  
  510. void
  511. GetOpenings (void)
  512.  
  513.      /*
  514.       * If a text file of opening chess plays (the Opening Book) is available: 
  515.       * Read in the Opening Book file and parse the algebraic notation for a move
  516.       * into an unsigned integer format indicating the from and to square. Create
  517.       * or update a binary hash file with the recomended move/moves for each 
  518.       * position.  
  519.       * The binary hash file is opened with readonly access durring the game.
  520.       */
  521. {
  522.     register SHORT i;
  523.     CHAR opening[256];
  524.     CHAR msg[256];
  525.     UTSHORT xside, doit, side;
  526.     SHORT c;
  527.     UTSHORT mv;
  528.     unsigned long games = 0;
  529.     FILE *fd;
  530.  
  531.     printf("SIZES %d %d\n",sizeof(struct gdxadmin),sizeof(struct gdxdata));
  532.     printf("%s\n",bookfile);
  533.     if ((fd = fopen (bookfile, "r")) == NULL)
  534.     fd = fopen (PGNECO, "r");
  535.     if (fd != NULL)
  536.       {
  537.       /* yes add to book */
  538.       /* open book as writer */
  539.       gfd = open (binbookfile, O_RDONLY | O_BINARY);
  540.       if (gfd >= 0)
  541.         {
  542.         if (sizeof(struct gdxadmin) == read (gfd, &ADMIN, sizeof (struct gdxadmin)))
  543.           {
  544.               B.bookcount = ADMIN.bookcount;
  545.               B.booksize = ADMIN.booksize;
  546.               B.maxoffset = ADMIN.maxoffset;
  547.               if (B.booksize && !(B.maxoffset == ((unsigned long)(B.booksize - 1) * sizeof (struct gdxdata) + sizeof (struct gdxadmin))))
  548.             {
  549.                 printf ("bad format %s\n", binbookfile);
  550.                 exit (1);
  551.             }
  552.           }
  553.         else
  554.           {
  555.               printf ("bad format %s\n", binbookfile);
  556.               exit (1);
  557.           }
  558.         close (gfd);
  559.                 gfd = open (binbookfile, O_RDWR | O_BINARY);
  560.  
  561.         }
  562.       else
  563.         {
  564. #ifdef Think_C
  565.                 gfd = open (binbookfile, O_RDWR | O_CREAT | O_BINARY);
  566. #else
  567.                 gfd = open (binbookfile, O_RDWR | O_CREAT | O_BINARY, 0644);
  568. #endif
  569.         ADMIN.bookcount = B.bookcount = 0;
  570.         ADMIN.booksize = B.booksize = booksize;
  571.                 B.maxoffset = ADMIN.maxoffset = (unsigned long) (booksize - 1) * sizeof (struct gdxdata) + sizeof (struct gdxadmin);
  572.         DATA.hashbd = 0;
  573.         DATA.hashkey = 0;
  574.         DATA.cntr = 0;
  575.         DATA.ecoptr = 0;
  576.  
  577.         }
  578.       if (gfd >= 0)
  579.         {
  580.  
  581.  
  582.         /* setvbuf(fd,buffr,_IOFBF,2048); */
  583.         side = white;
  584.         xside = black;
  585.         InitializeStats();
  586.         i = 0;
  587.  
  588.         while ((c = Vparse (fd, &mv, side, opening, i)) >= 0)
  589.           {
  590.               if (c == 1)
  591.                         {
  592.  
  593.                 /*
  594.                              * if not first move of an opening and first
  595.                              * time we have seen it save next move as
  596.                              * hint
  597.                              */
  598.                 i++;
  599.                     doit = true;
  600.  
  601.                           DATA.hashbd = bhashbd;
  602.                           DATA.hashkey = (unsigned long)(lts(bhashkey));
  603.                           DATA.ecoptr = curecoptr;
  604.         write (gfd, &DATA, sizeof (struct gdxdata));
  605. #ifdef notdef
  606. fprintf(xfd,"%8x %8x %d %x %s\n",DATA.hashbd,DATA.hashkey,curecoptr,mv,opening);
  607. #endif
  608.  
  609.                 computer = opponent;
  610.                 opponent = computer ^ 1;
  611.  
  612.                 xside = side;
  613.                 side = side ^ 1;
  614.             }
  615.               else if (i > 0)
  616.             {
  617.                 /* reset for next opening */
  618.                 games++;
  619.                 RESET ();
  620.                 i = 0;
  621.                 side = white;
  622.                 xside = black;
  623.  
  624.             }
  625.           }
  626.         fclose (fd);
  627.         close (gfd);
  628.         exit(0);
  629.         }
  630.       }
  631.     if (binbookfile != NULL)
  632.       {
  633.       /* open book as reader */
  634.       gfd = open (binbookfile, O_RDONLY | O_BINARY);
  635.       if (gfd >= 0)
  636.         {
  637.         read (gfd, &ADMIN, sizeof (struct gdxadmin));
  638.         B.bookcount = ADMIN.bookcount;
  639.         B.booksize = ADMIN.booksize;
  640.         B.maxoffset = ADMIN.maxoffset;
  641.                 if (B.booksize && !(B.maxoffset == ((unsigned long) (B.booksize - 1) * sizeof (struct gdxdata) + sizeof (struct gdxadmin))))
  642.           {
  643.               printf ("bad format %s\n", binbookfile);
  644.               exit (1);
  645.           }
  646.  
  647.         }
  648.       else
  649.         {
  650.         B.bookcount = 0;
  651.         B.booksize = booksize;
  652.  
  653.         }
  654.  
  655. #if !defined CHESSTOOL && !defined XBOARD
  656.       sprintf (msg, CP[213], B.bookcount, B.booksize);
  657.       ShowMessage (msg);
  658. #endif
  659.       }
  660.     /* set every thing back to start game */
  661.     Book = BOOKFAIL;
  662.     RESET ();
  663.     /* now get ready to play */
  664.     if (!B.bookcount)
  665.       {
  666. #if !defined CHESSTOOL && !defined XBOARD
  667.       ShowMessage (CP[212]);
  668. #endif
  669.       Book = 0;
  670.       }
  671. }
  672.  
  673.  
  674.  
  675. int
  676. OpeningBook (SHORT *hint, SHORT side)
  677.  
  678.      /*
  679.       * Go thru each of the opening lines of play and check for a match with the
  680.       * current game listing. If a match occurs, generate a random number. If this
  681.       * number is the largest generated so far then the next move in this line
  682.       * becomes the current "candidate". After all lines are checked, the
  683.       * candidate move is put at the top of the Tree[] array and will be played by
  684.       * the program. Note that the program does not handle book transpositions.
  685.       */
  686. {
  687. }
  688. void LOpeningBook (SHORT side) { }
  689. void EOpeningBook (SHORT side) { }
  690.