home *** CD-ROM | disk | FTP | other *** search
/ Dream 44 / Amiga_Dream_44.iso / RiscPc / jeux / ArcBoard004.arc / !GNUChessX / src / misc / eco_c < prev    next >
Text File  |  1995-07-02  |  16KB  |  688 lines

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