home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / gnuch40.zip / gnuchess-4.0.pl79 / src / init.c < prev    next >
C/C++ Source or Header  |  1998-09-28  |  13KB  |  505 lines

  1. /*
  2.  * init.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
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2, or (at your option)
  14.  * any later version.
  15.  *
  16.  * GNU Chess is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with GNU Chess; see the file COPYING.  If not, write to
  23.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  */
  25. #include "gnuchess.h"
  26. #include "ttable.h"
  27. #ifdef HAVE_GETTIMEOFDAY
  28. #include <sys/time.h>
  29. #endif
  30. extern SHORT notime;
  31. /* .... MOVE GENERATION VARIABLES AND INITIALIZATIONS .... */
  32.  
  33.  
  34. SHORT distdata[64][64], taxidata[64][64];
  35.  
  36. #ifdef KILLT
  37. /* put moves to the center first */
  38. void
  39. Initialize_killt (void)
  40. {
  41.   register UTSHORT f, t, s;
  42.   register SHORT d;
  43.   for (f = 0; f < 64; f++)
  44.     for (t = 0; t < 64; t++)
  45.       {
  46.     d = taxidata[f][0x1b];
  47.     if (taxidata[f][0x1c] < d)
  48.       d = taxidata[f][0x1c];
  49.     if (taxidata[f][0x23] < d)
  50.       d = taxidata[f][0x23];
  51.     if (taxidata[f][0x24] < d)
  52.       d = taxidata[f][0x24];
  53.     s = d;
  54.     d = taxidata[t][0x1b];
  55.     if (taxidata[t][0x1c] < d)
  56.       d = taxidata[t][0x1c];
  57.     if (taxidata[t][0x23] < d)
  58.       d = taxidata[t][0x23];
  59.     if (taxidata[t][0x24] < d)
  60.       d = taxidata[t][0x24];
  61.     s -= d;
  62.     killt[(f << 8) | t] = s;
  63.     killt[(f << 8) | t | 0x80] = s;
  64.       }
  65. }
  66. #endif
  67. void
  68. Initialize_dist (void)
  69. {
  70.   register SHORT a, b, d, di;
  71.  
  72.   for (a = 0; a < 64; a++)
  73.     for (b = 0; b < 64; b++)
  74.       {
  75.     d = abs (column (a) - column (b));
  76.     di = abs (row (a) - row (b));
  77.     taxidata[a][b] = d + di;
  78.     distdata[a][b] = (d > di ? d : di);
  79.       }
  80. #ifdef KILLT
  81.   Initialize_killt ();
  82. #endif
  83. }
  84.  
  85. const SHORT Stboard[64] =
  86. {rook, knight, bishop, queen, king, bishop, knight, rook,
  87.  pawn, pawn, pawn, pawn, pawn, pawn, pawn, pawn,
  88.  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  89.  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  90.  pawn, pawn, pawn, pawn, pawn, pawn, pawn, pawn,
  91.  rook, knight, bishop, queen, king, bishop, knight, rook};
  92. const SHORT Stcolor[64] =
  93. {white, white, white, white, white, white, white, white,
  94.  white, white, white, white, white, white, white, white,
  95.  neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral,
  96.  neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral,
  97.  neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral,
  98.  neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral,
  99.  black, black, black, black, black, black, black, black,
  100.  black, black, black, black, black, black, black, black};
  101. SHORT board[64], color[64];
  102.  
  103. /* given epsquare, from where can a pawn be taken? */
  104. const SHORT epmove1[64] =
  105. {0, 1, 2, 3, 4, 5, 6, 7,
  106.  8, 9, 10, 11, 12, 13, 14, 15,
  107.  16, 24, 25, 26, 27, 28, 29, 30,
  108.  24, 25, 26, 27, 28, 29, 30, 31,
  109.  32, 33, 34, 35, 36, 37, 38, 39,
  110.  40, 32, 33, 34, 35, 36, 37, 38,
  111.  48, 49, 50, 51, 52, 53, 54, 55,
  112.  56, 57, 58, 59, 60, 61, 62, 63};
  113. const SHORT epmove2[64] =
  114. {0, 1, 2, 3, 4, 5, 6, 7,
  115.  8, 9, 10, 11, 12, 13, 14, 15,
  116.  25, 26, 27, 28, 29, 30, 31, 23,
  117.  24, 25, 26, 27, 28, 29, 30, 31,
  118.  32, 33, 34, 35, 36, 37, 38, 39,
  119.  33, 34, 35, 36, 37, 38, 39, 47,
  120.  48, 49, 50, 51, 52, 53, 54, 55,
  121.  56, 57, 58, 59, 60, 61, 62, 63};
  122.  
  123.  
  124. /*
  125.  * nextpos[piece][from-square] , nextdir[piece][from-square] gives vector of
  126.  * positions reachable from from-square in ppos with piece such that the
  127.  * sequence    ppos = nextpos[piece][from-square]; pdir =
  128.  * nextdir[piece][from-square]; u = ppos[sq]; do { u = ppos[u]; if(color[u]
  129.  * != neutral) u = pdir[u]; } while (sq != u); will generate the sequence of
  130.  * all squares reachable from sq.
  131.  *
  132.  * If the path is blocked u = pdir[sq] will generate the continuation of the
  133.  * sequence in other directions.
  134.  */
  135.  
  136. UCHAR nextpos[8][64][64];
  137. UCHAR nextdir[8][64][64];
  138.  
  139. /*
  140.  * ptype is used to separate white and black pawns, like this; ptyp =
  141.  * ptype[side][piece] piece can be used directly in nextpos/nextdir when
  142.  * generating moves for pieces that are not black pawns.
  143.  */
  144. const SHORT ptype[2][8] =
  145. { { no_piece, pawn, knight, bishop, rook, queen, king, no_piece },
  146.   { no_piece, bpawn, knight, bishop, rook, queen, king, no_piece } };
  147.  
  148. /* data used to generate nextpos/nextdir */
  149. static const SHORT direc[8][8] =
  150. {
  151.    { 0, 0, 0, 0, 0, 0, 0, 0 },
  152.    { 10, 9, 11, 0, 0, 0, 0, 0 },
  153.    { 8, -8, 12, -12, 19, -19, 21, -21 },
  154.    { 9, 11, -9, -11, 0, 0, 0, 0 },
  155.    { 1, 10, -1, -10, 0, 0, 0, 0 },
  156.    { 1, 10, -1, -10, 9, 11, -9, -11 },
  157.    { 1, 10, -1, -10, 9, 11, -9, -11 },
  158.    { -10, -9, -11, 0, 0, 0, 0, 0 } };
  159. static const SHORT max_steps[8] =
  160. {0, 2, 1, 7, 7, 7, 1, 2};
  161. static const SHORT nunmap[120] =
  162. {
  163.   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  164.   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  165.   -1, 0, 1, 2, 3, 4, 5, 6, 7, -1,
  166.   -1, 8, 9, 10, 11, 12, 13, 14, 15, -1,
  167.   -1, 16, 17, 18, 19, 20, 21, 22, 23, -1,
  168.   -1, 24, 25, 26, 27, 28, 29, 30, 31, -1,
  169.   -1, 32, 33, 34, 35, 36, 37, 38, 39, -1,
  170.   -1, 40, 41, 42, 43, 44, 45, 46, 47, -1,
  171.   -1, 48, 49, 50, 51, 52, 53, 54, 55, -1,
  172.   -1, 56, 57, 58, 59, 60, 61, 62, 63, -1,
  173.   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  174.   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
  175.  
  176. int InitFlag = false;
  177. void
  178. Initialize_moves (void)
  179.  
  180. /*
  181.  * This procedure pre-calculates all moves for every piece from every square.
  182.  * This data is stored in nextpos/nextdir and used later in the move
  183.  * generation routines.
  184.  */
  185.  
  186. {
  187.   SHORT ptyp, po, p0, d, di, s, delta;
  188.   UCHAR *ppos, *pdir;
  189.   SHORT dest[8][8];
  190.   SHORT steps[8];
  191.   SHORT sorted[8];
  192.  
  193.   for (ptyp = 0; ptyp < 8; ptyp++)
  194.     for (po = 0; po < 64; po++)
  195.       for (p0 = 0; p0 < 64; p0++)
  196.     {
  197.       nextpos[ptyp][po][p0] = (UCHAR) po;
  198.       nextdir[ptyp][po][p0] = (UCHAR) po;
  199.     }
  200.   for (ptyp = 1; ptyp < 8; ptyp++)
  201.     for (po = 21; po < 99; po++)
  202.       if (nunmap[po] >= 0)
  203.     {
  204.       ppos = nextpos[ptyp][nunmap[po]];
  205.       pdir = nextdir[ptyp][nunmap[po]];
  206.       /* dest is a function of direction and steps */
  207.       for (d = 0; d < 8; d++)
  208.         {
  209.           dest[d][0] = nunmap[po];
  210.           delta = direc[ptyp][d];
  211.           if (delta != 0)
  212.         {
  213.           p0 = po;
  214.           for (s = 0; s < max_steps[ptyp]; s++)
  215.             {
  216.               p0 = p0 + delta;
  217.  
  218.               /*
  219.                * break if (off board) or (pawns only move two
  220.                * steps from home square)
  221.                */
  222.               if ((nunmap[p0] < 0) || (((ptyp == pawn) || (ptyp == bpawn))
  223.                            && ((s > 0) && ((d > 0) || (Stboard[nunmap[po]] != pawn)))))
  224.             break;
  225.               else
  226.             dest[d][s] = nunmap[p0];
  227.             }
  228.         }
  229.           else
  230.         s = 0;
  231.  
  232.           /*
  233.            * sort dest in number of steps order currently no sort
  234.            * is done due to compability with the move generation
  235.            * order in old gnu chess
  236.            */
  237.           steps[d] = s;
  238.           for (di = d; s > 0 && di > 0; di--)
  239.         if (steps[sorted[di - 1]] == 0)    /* should be: < s */
  240.           sorted[di] = sorted[di - 1];
  241.         else
  242.           break;
  243.           sorted[di] = d;
  244.         }
  245.  
  246.       /*
  247.        * update nextpos/nextdir, pawns have two threads (capture
  248.        * and no capture)
  249.        */
  250.       p0 = nunmap[po];
  251.       if (ptyp == pawn || ptyp == bpawn)
  252.         {
  253.           for (s = 0; s < steps[0]; s++)
  254.         {
  255.           ppos[p0] = (UCHAR) dest[0][s];
  256.           p0 = dest[0][s];
  257.         }
  258.           p0 = nunmap[po];
  259.           for (d = 1; d < 3; d++)
  260.         {
  261.           pdir[p0] = (UCHAR) dest[d][0];
  262.           p0 = dest[d][0];
  263.         }
  264.         }
  265.       else
  266.         {
  267.           pdir[p0] = (UCHAR) dest[sorted[0]][0];
  268.           for (d = 0; d < 8; d++)
  269.         for (s = 0; s < steps[sorted[d]]; s++)
  270.           {
  271.             ppos[p0] = (UCHAR) dest[sorted[d]][s];
  272.             p0 = dest[sorted[d]][s];
  273.             if (d < 7)
  274.               pdir[p0] = (UCHAR) dest[sorted[d + 1]][0];
  275.  
  276.             /*
  277.              * else is already initialized
  278.              */
  279.           }
  280.         }
  281.     }
  282. }
  283.  
  284. void
  285. NewGame (void)
  286.  
  287. /*
  288.  * Reset the board and other variables to start a new game.
  289.  */
  290.  
  291. {
  292.   SHORT l;
  293. #ifdef HAVE_GETTIMEOFDAY
  294.   struct timeval tv;
  295. #endif
  296. #ifdef CLIENT
  297.   if(GameCnt >0)ListGame();
  298.   fflush(stdout);
  299. #endif
  300.   compptr = oppptr = 0;
  301.   stage = stage2 = -1;        /* the game is not yet started */
  302.   notime = true;
  303. flag.illegal=flag.mate=flag.quit=flag.bothsides=flag.onemove=flag.force=flag.back=flag.musttimeout=false;
  304. flag.easy = true;
  305.  
  306. flag.verydeep= flag.neweval= flag.threat= flag.deepnull= flag.pvs = true; /* TomV */
  307. flag.pvs = false;
  308. #ifdef DEBUG
  309.  flag.nott = flag.noft = flag.nocache = false;
  310. #endif
  311.  
  312. #ifdef CLIENT
  313.   flag.gamein = true;
  314.   flag.post = true;
  315. #else 
  316.   flag.gamein = false;
  317. #endif
  318.   mycnt1 = mycnt2 = 0;
  319.   GenCnt = NodeCnt = et0 = epsquare =  dither =  XCmore = 0;
  320.   contempt = -200;
  321.   WAwindow = WAWNDW;
  322.   WBwindow = WBWNDW;
  323.   BAwindow = BAWNDW;
  324.   BBwindow = BBWNDW;
  325.   xwndw = BXWNDW;
  326.   if (!MaxSearchDepth)
  327.     MaxSearchDepth = MAXDEPTH - 1;
  328.   contempt = 0;
  329.   GameCnt = 0;
  330.   Game50 = 1;
  331.   hint = 0x0C14;
  332.   ZeroRPT ();
  333.   Developed[white] = Developed[black] = false;
  334.   castld[white] = castld[black] = false;
  335.   PawnThreat[0] = CptrFlag[0] = false;
  336.   Pscore[0] = Tscore[0] = 12000;
  337.   opponent = white;
  338.   computer = black;
  339.   for (l = 0; l < TREE; l++)
  340.     Tree[l].f = Tree[l].t = 0;
  341.   if (!InitFlag)
  342.     InitHashCode((unsigned int)1);
  343.   for (l = 0; l < 64; l++)
  344.     {
  345.       board[l] = Stboard[l];
  346.       color[l] = Stcolor[l];
  347.       Mvboard[l] = 0;
  348.     }
  349.   ClrScreen ();
  350.   InitializeStats ();
  351. #ifdef HAVE_GETTIMEOFDAY
  352.   gettimeofday(&tv, NULL);
  353.   time0 = tv.tv_sec*100+tv.tv_usec/10000;
  354. #else
  355.   time0 = time ((time_t *) 0) * 100;
  356. #endif
  357.   ElapsedTime (1);
  358.   flag.regularstart = true;
  359.   Book = BOOKFAIL;
  360.   TimeControl.clock[white] = TimeControl.clock[black] = 0;
  361.   SetTimeControl();
  362.   
  363.   if (!InitFlag)
  364.     {
  365.     CHAR sx[256];
  366.     strcpy(sx,CP[169]);
  367.       if (!TCflag && MaxResponseTime == 0) SelectLevel (sx);
  368.       UpdateDisplay (0, 0, 1, 0);
  369.       GetOpenings ();
  370. #ifdef CACHE
  371.     etab[0] = (struct etable *)malloc(ETABLE*sizeof(struct etable));
  372.     etab[1] = (struct etable *)malloc(ETABLE*sizeof(struct etable));
  373.     if(etab[0] == NULL || etab[1] == NULL){ perror("can't alloc etab");exit(1);}
  374. #endif
  375. #if ttblsz
  376.       Initialize_ttable();
  377. #endif
  378.       InitFlag = true;
  379.     }
  380. #if ttblsz
  381.     ZeroTTable(0);
  382. #endif /* ttblsz */
  383. #ifdef CACHE
  384.    memset ((CHAR *) etab[0], 0, ETABLE*sizeof(struct etable));
  385.    memset ((CHAR *) etab[1], 0, ETABLE*sizeof(struct etable));
  386. #endif
  387. #ifdef NODITHER
  388.   PCRASH = PCRASHS;
  389.   PCENTER = PCENTERS;
  390. #else
  391.   PCRASH = PCRASHS + (dither?(rand() % PCRASHV):0);
  392.   PCENTER = PCENTERS + (dither?(rand() % PCENTERV):0);
  393. #endif
  394.   return;
  395. }
  396.  
  397. void
  398. InitConst (CHAR *lang)
  399. {
  400.   FILE *constfile;
  401.   CHAR s[512];
  402.   CHAR sl[5];
  403.   int len, entry;
  404.   CHAR *p, *q;
  405.  
  406. flag.illegal=flag.mate=flag.post=flag.quit=flag.reverse=flag.bothsides=flag.onemove=flag.force=false;
  407. flag.material=flag.coords=flag.hash=flag.easy=flag.beep=flag.rcptr=true;
  408. flag.autolist=flag.stars=flag.shade=flag.back=flag.musttimeout=false;
  409. #ifdef CLIENT
  410.   flag.gamein = true;
  411.   flag.post = true;
  412. #else 
  413.   flag.gamein = false;
  414. #endif
  415. #if defined(MSDOS) && !defined(SEVENBIT)
  416.   flag.rv = false;
  417. #else
  418.   flag.rv = true;
  419. #endif /* MSDOS && !SEVENBIT */
  420.   constfile = fopen (LANGFILE, "r");
  421.   if (!constfile)
  422.     {
  423.     constfile = fopen(SRCLANGFILE, "r");
  424.     }
  425.   if (!constfile)
  426.     {
  427.       printf ("NO LANGFILE (file gnuchess.lang not found)\n");
  428.       exit (1);
  429.     }
  430.   while (fgets (s, sizeof (s), constfile))
  431.     {
  432.       if (s[0] == '!') continue;
  433.       len = strlen (s);
  434.       for (q = &s[len]; q > &s[8]; q--) if (*q == '}') break;
  435.       if (q == &s[8])
  436.     {
  437.       printf ("{ error in constfile\n");
  438.       exit (1);
  439.     }
  440.       *q = '\0';
  441.       if (s[3] != ':' || s[7] != ':' || s[8] != '{')
  442.     {
  443.       printf ("Langfile format error %s\n", s);
  444.       exit (1);
  445.     }
  446.       s[3] = s[7] = '\0';
  447.       if (lang == NULL)
  448.     {
  449.       lang = sl;
  450.       strcpy (sl, &s[4]);
  451.     }
  452.       if (strcmp (&s[4], lang))
  453.     continue;
  454.       entry = atoi (s);
  455.       if (entry < 0 || entry >= CPSIZE)
  456.     {
  457.       printf ("Langfile number error\n");
  458.       exit (1);
  459.     }
  460.       for (q = p = &s[9]; *p; p++)
  461.     {
  462.       if (*p != '\\')
  463.         {
  464.           *q++ = *p;
  465.         }
  466.       else if (*(p + 1) == 'n')
  467.         {
  468.           *q++ = '\n';
  469.           p++;
  470.         }
  471.     }
  472.       *q = '\0';
  473.       if (entry < 0 || entry > 255)
  474.     {
  475.       printf ("Langfile error %d\n", entry);
  476.       exit (0);
  477.     }
  478.       CP[entry] = (CHAR *) malloc ((unsigned) strlen (&s[9]) + 1);
  479.       if (CP[entry] == NULL)
  480.     {
  481.       perror ("malloc");
  482.       exit (0);
  483.     }
  484.       strcpy (CP[entry], &s[9]);
  485.  
  486.     }
  487.   fclose (constfile);
  488. }
  489. #if defined (ALLOCATE)
  490. void
  491. Initialize_mem()
  492. {
  493.         ALLOCATE(nextpos);
  494.         ALLOCATE(nextdir);
  495. /* #ifdef CACHE */
  496. /*        ALLOCATE(etab); */
  497. /*#endif */
  498. #ifdef HISTORY
  499.         ALLOCATE(history);
  500. #endif
  501.         ALLOCATE(Tree);
  502.         printf("Total free memory = %ld\n", FreeMem());
  503. }
  504. #endif /* ALLOCATE */
  505.