home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / wps / games / gnuchess / sources / book.c < prev    next >
C/C++ Source or Header  |  1990-11-29  |  9KB  |  347 lines

  1. //
  2. //  Copyright (C) 1986, 1987, 1988, 1989, 1990 Free Software Foundation, Inc.
  3. //  Copyright (c) 1988, 1989, 1990  John Stanback
  4. //
  5. //  Project:    OS/2 PM Port of GNU CHESS 3.1 (PmChess)
  6. //
  7. //  Version:    1990-11-17
  8. //
  9. //   Module:    Book Move Load Logic (Book.c)
  10. //
  11. //   Porter:    Ported to Windows 3.0 by Darly Baker
  12. //
  13. //   Porter:    Ported to OS/2 1.2+ by Kent Cedola
  14. //
  15. //   System:    OS2 1.2 using Microsoft C 6.0
  16. //
  17. //  Remarks:    Since OS/2 doesn't have all the restrictions of Windows, I
  18. //              restored most of this code from the MS-DOS version of
  19. //              GNU Chess.
  20. //
  21. //  License:
  22. //
  23. //    CHESS is distributed in the hope that it will be useful, but WITHOUT ANY
  24. //    WARRANTY.  No author or distributor accepts responsibility to anyone for
  25. //    the consequences of using it or for whether it serves any particular
  26. //    purpose or works at all, unless he says so in writing.  Refer to the
  27. //    CHESS General Public License for full details.
  28. //
  29. //    Everyone is granted permission to copy, modify and redistribute CHESS,
  30. //    but only under the conditions described in the CHESS General Public
  31. //    License.  A copy of this license is supposed to have been given to you
  32. //    along with CHESS so you can know your rights and responsibilities.  It
  33. //    should be in a file named COPYING.  Among other things, the copyright
  34. //    notice and this notice must be preserved on all copies.
  35. //
  36. #define INCL_DOS
  37. #define INCL_PM
  38. #include <os2.h>
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <string.h>
  42. #include <memory.h>
  43. #include "PmChess.h"
  44. #include "GnuChess.h"
  45. #include "Defs.h"
  46. #include "Resource.h"
  47.  
  48.  
  49. void
  50. GetOpenings (HWND hWnd)
  51. /*
  52.    Read in the Opening Book file and parse the algebraic notation for a move
  53.    into an unsigned integer format indicating the from and to square. Create
  54.    a linked list of opening lines of play, with entry->next pointing to the
  55.    next line and entry->move pointing to a chunk of memory containing the
  56.    moves. More Opening lines of up to 256 half moves may be added to
  57.    gnuchess.book.
  58. */
  59.  
  60. {
  61.   FILE *fd;
  62.   int c, i, j, side;
  63.   /* char buffr[2048]; */
  64.   struct BookEntry *entry;
  65.   unsigned short mv, *mp, tmp[100];
  66.  
  67.   if ((fd = fopen ("gnuchess.boo", "r")) != NULL)
  68.     {
  69.       /* setvbuf(fd,buffr,_IOFBF,2048); */
  70.       Book = NULL;
  71.       i = 0;
  72.       side = white;
  73.       while ((c = parse (fd, &mv, side)) >= 0)
  74.     if (c == 1)
  75.       {
  76.         tmp[++i] = mv;
  77.         side = otherside[side];
  78.       }
  79.     else if (c == 0 && i > 0)
  80.       {
  81.         entry = (struct BookEntry *) malloc (sizeof (struct BookEntry));
  82.         mp = (unsigned short *) malloc ((i + 1) * sizeof (unsigned short));
  83.         entry->mv = mp;
  84.         entry->next = Book;
  85.         Book = entry;
  86.         for (j = 1; j <= i; j++)
  87.           *(mp++) = tmp[j];
  88.         *mp = 0;
  89.         i = 0;
  90.         side = white;
  91.       }
  92.       fclose (fd);
  93.     }
  94.   else
  95.     {
  96.     SMessageBox(hWnd, IDS_OBNF, IDS_CHESS);
  97.     }
  98. }
  99.  
  100. int
  101. parse (fd, mv, side)
  102.      FILE *fd;
  103.      short unsigned int *mv;
  104.      short int side;
  105. {
  106.   int c, i, r1, r2, c1, c2;
  107.   char s[100];
  108.   while ((c = getc (fd)) == ' ') ;
  109.   i = 0;
  110.   s[0] = (CHAR)c;
  111.   while (c != ' ' && c != '\n' && c != EOF)
  112.     s[++i] = (CHAR)(c = getc (fd));
  113.   s[++i] = '\0';
  114.   if (c == EOF)
  115.     return (-1);
  116.   if (s[0] == '!' || s[0] == ';' || i < 3)
  117.     {
  118.       while (c != '\n' && c != EOF)
  119.     c = getc (fd);
  120.       return (0);
  121.     }
  122.   if (s[4] == 'o')
  123.     if (side == black)
  124.       *mv = 0x3C3A;
  125.     else
  126.       *mv = 0x0402;
  127.   else if (s[0] == 'o')
  128.     if (side == black)
  129.       *mv = 0x3C3E;
  130.     else
  131.       *mv = 0x0406;
  132.   else
  133.     {
  134.       c1 = s[0] - 'a';
  135.       r1 = s[1] - '1';
  136.       c2 = s[2] - 'a';
  137.       r2 = s[3] - '1';
  138.       *mv = (locn (r1, c1) << 8) + locn (r2, c2);
  139.     }
  140.   return (1);
  141. }
  142.  
  143. void
  144. OpeningBook (unsigned short *hint)
  145.  
  146. /*
  147.   Go thru each of the opening lines of play and check for a match with the
  148.   current game listing. If a match occurs, generate a random number. If this
  149.   number is the largest generated so far then the next move in this line
  150.   becomes the current "candidate". After all lines are checked, the
  151.   candidate move is put at the top of the Tree[] array and will be played by
  152.   the program. Note that the program does not handle book transpositions.
  153. */
  154.  
  155. {
  156.   short j, pnt;
  157.   unsigned short m, *mp;
  158.   unsigned r, r0;
  159.   struct BookEntry *p;
  160.  
  161.   srand ((unsigned int) time0);
  162.   r0 = m = 0;
  163.   p = Book;
  164.   while (p != NULL)
  165.     {
  166.       mp = p->mv;
  167.       for (j = 0; j <= GameCnt; j++)
  168.     if (GameList[j].gmove != *(mp++))
  169.       break;
  170.       if (j > GameCnt)
  171.     if ((r = rand ()) > r0)
  172.       {
  173.         r0 = r;
  174.         m = *mp;
  175.         *hint = *(++mp);
  176.       }
  177.       p = p->next;
  178.     }
  179.  
  180.   for (pnt = TrPnt[1]; pnt < TrPnt[2]; pnt++)
  181.     if (((Tree[pnt].f << 8) | Tree[pnt].t) == (SHORT)m)
  182.       Tree[pnt].score = 0;
  183.   pick (TrPnt[1], TrPnt[2] - 1);
  184.   if (Tree[TrPnt[1]].score < 0)
  185.     Book = NULL;
  186. }
  187.  
  188.  
  189.  
  190. #ifdef oldjunk
  191.  
  192. static unsigned int book_used = 0;
  193. static char far * xBook;
  194. GLOBALHANDLE hBook = 0;
  195.  
  196. void FreeBook (void)
  197. {
  198.    GlobalUnlock ( hBook );
  199.    GlobalFree ( hBook);
  200.    hBook = 0;
  201.    book_used = 0;
  202. }
  203.  
  204. static void far *Book_alloc ( unsigned int size )
  205. {
  206.     char far * temp;
  207.     if ( book_used > 32*1024 ) return (void far *)0;
  208.     temp = xBook+book_used;
  209.     book_used += size;
  210.     return temp;
  211. }
  212.  
  213.  
  214. void
  215. GetOpenings (HWND hWnd)
  216.      
  217. /*
  218.    Read in the Opening Book file and parse the algebraic notation for a move
  219.    into an unsigned integer format indicating the from and to square. Create
  220.    a linked list of opening lines of play, with entry->next pointing to the
  221.    next line and entry->move pointing to a chunk of memory containing the
  222.    moves. More Opening lines of up to 256 half moves may be added to
  223.    gnuchess.book.
  224. */
  225. #ifndef BOOK
  226. #define BOOK "/usr/games/lib/gnuchess.book"
  227. #endif /* BOOK */     
  228. {
  229.   FILE *fd;
  230.   int c, i, j, side;
  231.  
  232.   /* char buffr[2048]; */
  233.   struct BookEntry far  *entry;
  234.   unsigned short mv, far  *mp, tmp[100];
  235.   char lpFile[_MAX_FNAME+_MAX_EXT+_MAX_DRIVE+_MAX_DIR+1];
  236.   char sFname[_MAX_FNAME], sExt[_MAX_EXT], sDrive[_MAX_DRIVE], sDir[_MAX_DIR];
  237.  
  238.   GetModuleFileName ( GetWindowWord(hWnd, GWW_HINSTANCE),
  239.                       lpFile, sizeof(lpFile) );
  240.  
  241.   _splitpath ( lpFile, sDrive, sDir, sFname, sExt);
  242.   _makepath  ( lpFile, sDrive, sDir, "gnuchess", "boo");
  243.  
  244.   fd = fopen (lpFile, "r");
  245.  
  246. /*  if ((fd = fopen (BOOK, "r")) == NULL)
  247.     fd = fopen ("gnuchess.book", "r"); */
  248.   if (fd != NULL)
  249.     {
  250.       hBook = GlobalAlloc ( GMEM_MOVEABLE | GMEM_ZEROINIT,
  251.                             (long) (32*1024 * sizeof (char)) );
  252.  
  253.       if( hBook == NULL )
  254.         {
  255.            Book = NULL;
  256.            SMessageBox (hWnd, IDS_OBAE, IDS_CHESS);
  257.            return;
  258.         }
  259.       xBook = (unsigned char far *) GlobalLock (hBook);
  260.  
  261.  
  262.       /* setvbuf(fd,buffr,_IOFBF,2048); */
  263.       Book = NULL;
  264.       i = 0;
  265.       side = white;
  266.       while ((c = parse (fd, &mv, side)) >= 0)
  267.         if (c == 1)
  268.           {
  269.             tmp[++i] = mv;
  270.             side = otherside[side];
  271.           }
  272.         else if (c == 0 && i > 0)
  273.           {
  274.             entry = (struct BookEntry far *) Book_alloc ( sizeof (struct BookEntry));
  275.             mp = (unsigned short far *) Book_alloc ( (i + 1) * sizeof (unsigned short));
  276.             if ( (entry == 0 ) || (mp == 0) )
  277.               {
  278.                 Book = NULL;
  279.                 SMessageBox (hWnd, IDS_OBAE, IDS_CHESS);
  280.                 GlobalUnlock ( hBook );
  281.                 GlobalFree ( hBook);
  282.                 return;
  283.               }
  284.             entry->mv = mp;
  285.             entry->next = Book;
  286.             Book = entry;
  287.             for (j = 1; j <= i; j++)
  288.               *(mp++) = tmp[j];
  289.             *mp = 0;
  290.             i = 0;
  291.             side = white;
  292.           }
  293.       fclose (fd);
  294.     }
  295.   else
  296.     SMessageBox (hWnd, IDS_OBNF, IDS_CHESS);
  297. }
  298.  
  299. void
  300. OpeningBook (unsigned short *hint)
  301.  
  302. /*
  303.   Go thru each of the opening lines of play and check for a match with the
  304.   current game listing. If a match occurs, generate a random number. If this
  305.   number is the largest generated so far then the next move in this line
  306.   becomes the current "candidate". After all lines are checked, the
  307.   candidate move is put at the top of the Tree[] array and will be played by
  308.   the program. Note that the program does not handle book transpositions.
  309. */
  310.  
  311. {
  312.   short j, pnt;
  313.   unsigned short m, far *mp;
  314.   unsigned r, r0;
  315.   struct BookEntry far *p;
  316.  
  317.   srand ((unsigned int) time ((long *) 0));
  318.   r0 = m = 0;
  319.   p = Book;
  320.   while (p != NULL)
  321.     {
  322.       mp = p->mv;
  323.       for (j = 1; j <= GameCnt; j++)
  324.         if (GameList[j].gmove != *(mp++))
  325.           break;
  326.       if (j > GameCnt)
  327.         if ((r = urand ()) > r0)
  328.           {
  329.             r0 = r;
  330.             m = *mp;
  331.             *hint = *(++mp);
  332.           }
  333.       p = p->next;
  334.     }
  335.  
  336.   for (pnt = TrPnt[1]; pnt < TrPnt[2]; pnt++)
  337.     if (((Tree[pnt].f << 8) | Tree[pnt].t) == m)
  338.       Tree[pnt].score = 0;
  339.   pick (TrPnt[1], TrPnt[2] - 1);
  340.   if (Tree[TrPnt[1]].score < 0) {
  341.    FreeBook ();
  342.    Book = NULL;
  343.   }
  344. }
  345.  
  346. #endif
  347.