home *** CD-ROM | disk | FTP | other *** search
/ Mega Top 1 / os2_top1.zip / os2_top1 / APPS / SPEL / GC_OS2_M / SRC-M.ZIP / search.c < prev    next >
Text File  |  1994-01-31  |  36KB  |  1,425 lines

  1. /*
  2.  * search.c - C source for GNU CHESS
  3.  *
  4.  * Copyright (c) 1988,1989,1990 John Stanback Copyright (c) 1992 Free Software
  5.  * 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. short background = 0;
  25. static short int DepthBeyond;
  26. unsigned short int PrVar[MAXDEPTH];
  27. extern char mvstr[4][6];
  28. extern short int recycle, ISZERO;
  29. #ifdef NULLMOVE
  30. short int null;            /* Null-move already made or not */
  31. short int PVari;        /* Is this the PV */
  32. #endif
  33. short int zwndw;
  34. unsigned int TTadd = 1;
  35. short int recycle;
  36.  
  37. #if ttblsz
  38.  
  39. #define CB(i) (unsigned char) ((color[2 * (i)] ? 0x80 : 0)\
  40.            | (board[2 * (i)] << 4)\
  41.            | (color[2 * (i) + 1] ? 0x8 : 0)\
  42.            | (board[2 * (i) + 1]))
  43. inline
  44. int
  45. ProbeTTable (short int side,
  46.          short int depth,
  47.          short int ply,
  48.          short int *alpha,
  49.          short int *beta,
  50.          short int *score)
  51.  
  52. /*
  53.  * Look for the current board position in the transposition table.
  54.  */
  55.  
  56. {
  57.   register struct hashentry *ptbl;
  58.   register /*unsigned*/ short i = 0;    /*to match new type of rehash --tpm*/
  59.  
  60.   ptbl = &ttable[side][hashkey % ttblsize];
  61.   while (true)
  62.     {
  63.       if (ptbl->depth == 0)
  64.     return false;
  65.       if (ptbl->hashbd == hashbd)
  66.     break;
  67.       if (++i > rehash)
  68.     return false;
  69.       ptbl++;
  70.     }
  71.  
  72.   /* rehash max rehash times */
  73.   PV = SwagHt = ptbl->mv;
  74.   if ((ptbl->depth >= (short) depth))
  75.     {
  76.  
  77.  
  78. #ifndef BAREBONES
  79.       HashCnt++;
  80. #endif
  81.       if (ptbl->flags & truescore)
  82.     {
  83.       *score = ptbl->score;
  84.       /* adjust *score so moves to mate is from root */
  85.       *beta = -20000;
  86.     }
  87.       else if (ptbl->flags & lowerbound)
  88.     {
  89.       if (ptbl->score > *alpha)
  90.         *alpha = ptbl->score - 1;
  91.     }
  92.       return (true);
  93.     }
  94.   return (false);
  95. }
  96.  
  97. inline
  98. int
  99. PutInTTable
  100.  (short int side,
  101.          short int score,
  102.          short int depth,
  103.          short int ply,
  104.          short int alpha,
  105.          short int beta,
  106.          short unsigned int mv)
  107.  
  108. /*
  109.  * Store the current board position in the transposition table.
  110.  */
  111.  
  112. {
  113.   register struct hashentry *ptbl;
  114.   register /*unsigned*/ short i = 0;    /*to match new type of rehash --tpm*/
  115.  
  116.   ptbl = &ttable[side][hashkey % ttblsize];
  117.   while (true)
  118.     {
  119.       if (ptbl->depth == 0 || ptbl->hashbd == hashbd)
  120.     break;
  121.       if (++i > rehash)
  122.     {
  123. #ifndef BAREBONES
  124.       THashCol++;
  125. #endif
  126.       ptbl += recycle;
  127.       break;
  128.     }
  129.       ptbl++;
  130.     }
  131.  
  132. #ifndef BAREBONES
  133.   TTadd++;
  134.   HashAdd++;
  135. #endif
  136.   /* adjust score so moves to mate is from this ply */
  137.   ptbl->hashbd = hashbd;
  138.   ptbl->depth = (unsigned char) depth;
  139.   ptbl->score = score;
  140.   ptbl->mv = mv;
  141.   if (score > beta)
  142.     {
  143.       ptbl->flags = lowerbound;
  144.       ptbl->score = beta + 1;
  145.     }
  146.   else
  147.     ptbl->flags = truescore;
  148.  
  149.   return true;
  150. }
  151.  
  152. #endif
  153.  
  154. #include "ataks.h"
  155.  
  156. #include "debug41.h"
  157. /* ............    MOVE GENERATION & SEARCH ROUTINES    .............. */
  158. inline
  159. short int
  160. repetition ()
  161.  
  162. /*  Check for draw by threefold repetition.  */
  163.  
  164. {
  165.   register short i, c, cnt;
  166.   register unsigned short m;
  167.   short b[64];
  168.  
  169.   cnt = c = 0;
  170.   /* try to avoid work */
  171.   if (GameCnt > Game50 + 4)
  172.     {
  173.       for (i = 0; i < 64; b[i++] = 0);
  174.       for (i = GameCnt; i >= Game50; i--)
  175.     {
  176.       m = GameList[i].gmove;
  177.       /* does piece exist on diff board? */
  178.       if (b[m & 0x3f])
  179.         {
  180.           /* does diffs cancel out, piece back? */
  181.           if ((b[m >> 8] += b[m & 0x3f]) == 0)
  182.         --c;
  183.           b[m & 0x3f] = 0;
  184.         }
  185.       else
  186.         {
  187.           /* create diff */
  188.           ++c;
  189.           /* does diff cancel out another diff? */
  190.           if (!(b[m >> 8] -= (b[m & 0x3f] = board[m & 0x3f] +
  191.                   (color[m & 0x3f] << 8))))
  192.         --c;;
  193.         }
  194.       /* if diff count is 0 we have a repetition */
  195.       if (c == 0)
  196.         if ((i ^ GameCnt) & 1)
  197.           cnt++;
  198.     }
  199.     }
  200.   return cnt;
  201. }
  202.  
  203. int plyscore, globalscore;
  204. int
  205. pick (short int p1, short int p2)
  206.  
  207. /*
  208.  * Find the best move in the tree between indexes p1 and p2. Swap the best
  209.  * move into the p1 element.
  210.  *
  211.  */
  212. {
  213.   register struct leaf *p, *q, *r, *k;
  214.   register s0;
  215.   struct leaf temp;
  216.  
  217.   k = p = &Tree[p1];
  218.   q = &Tree[p2];
  219.   s0 = p->score;
  220.   for (r = p + 1; r <= q; r++)
  221.     if ((r->score) > s0)
  222.       {
  223.     s0 = (r->score);
  224.     p = r;
  225.       }
  226.   if (p != k)
  227.     {
  228.       temp = *p;
  229.       *p = *k;
  230.       *k = temp;
  231.       return true;
  232.     }
  233.   return false;
  234. }
  235.  
  236. int bookflag = false;
  237. int Jscore = 0;
  238.  
  239. static int TCcount, TCleft;
  240. void
  241. SelectMove (short int side, short int iop)
  242.  
  243.  
  244. /*
  245.  * Select a move by calling function search() at progressively deeper ply
  246.  * until time is up or a mate or draw is reached. An alpha-beta window of
  247.  * -Awindow to +Bwindow points is set around the score returned from the
  248.  * previous iteration. If Sdepth != 0 then the program has correctly
  249.  * predicted the opponents move and the search will start at a depth of
  250.  * Sdepth+1 rather than a depth of 1.
  251.  */
  252.  
  253. {
  254.   static short int i, tempb, tempc, tempsf, tempst, xside, rpt;
  255.   static short int alpha, beta, score;
  256.   static struct GameRec *g;
  257. /*  unsigned long j;*/
  258.  
  259.   flag.timeout = false;
  260.   flag.back = false;
  261.   flag.musttimeout = false;
  262.   xside = side ^ 1;
  263.   recycle = (GameCnt % rehash) - rehash;
  264.   /* if background mode set to infinite */
  265.   if (iop == 2)
  266.     {
  267.       ResponseTime = 9999999;
  268.       background = true;
  269.     }
  270.   else
  271.     {
  272.       player = side;
  273.       if (TCflag)
  274.     {
  275.       TCcount = 0;
  276.       background = false;
  277.       if (TimeControl.moves[side] < 1)
  278.         TimeControl.moves[side] = 1;
  279.       /* special case time per move specified */
  280.       if (flag.onemove)
  281.         {
  282.           ResponseTime = TimeControl.clock[side] - 100;
  283.           TCleft = 0;
  284.         }
  285.       else
  286.         {
  287.           /* calculate avg time per move remaining */
  288.           TimeControl.clock[side] += TCadd;
  289.  
  290.           ResponseTime = (TimeControl.clock[side]) / (((TimeControl.moves[side]) * 2) + 1);
  291.           TCleft = (int) ResponseTime / 3;
  292.           ResponseTime += TCadd / 2;
  293.           if (TimeControl.moves[side] < 5)
  294.         TCcount = MAXTCCOUNTX - 10;
  295.         }
  296.       if (ResponseTime < 101)
  297.         {
  298.           ResponseTime = 100;
  299.           TCcount = MAXTCCOUNTX - 10;
  300.         }
  301.       else if (ResponseTime < 200)
  302.         {
  303.           TCcount = MAXTCCOUNTX - 10;
  304.         }
  305.     }
  306.       else
  307.     {
  308.       ResponseTime = MaxResponseTime;
  309.       TCleft = 0;
  310.       ElapsedTime (1);
  311.     }
  312.       if (TCleft)
  313.     {
  314.       TCcount = ((int) ((TimeControl.clock[side] - ResponseTime)) / 2) / TCleft;
  315.       if (TCcount > MAXTCCOUNTX)
  316.         TCcount = 0;
  317.       else
  318.         TCcount = MAXTCCOUNTX - TCcount;
  319.     }
  320.       else
  321.     TCcount = MAXTCCOUNTX;
  322.     }
  323.  
  324.   if (Sdepth > 0)
  325.     {
  326.       time0 = ft;
  327.       goto SS;
  328.     } 
  329.   ExtraTime = 0;
  330.   ExaminePosition ();
  331.   score = ScorePosition (side);
  332. #ifdef QUIETBACKGROUND
  333.   if (!background)
  334. #endif /* QUIETBACKGROUND */
  335.     ShowSidetoMove ();
  336. #ifdef QUIETBACKGROUND
  337.   if (!background)
  338. #endif /* QUIETBACKGROUND */
  339.     SearchStartStuff (side);
  340. #ifdef HISTORY
  341. #if (defined(NOMEMSET) || defined(MSDOS)) && !defined(__GNUC__)
  342.   for (j = 0; j <= 32768; j++)
  343.     history[j] = 0;
  344. #else
  345.   memset ((unsigned char *) history, 0, (unsigned long) sizeof (history));
  346. #endif /* NOMEMSET */
  347. #endif
  348.   FROMsquare = TOsquare = -1;
  349.   PV = 0;
  350.   if (iop == 1)
  351.     hint = 0;
  352.   for (i = 0; i < MAXDEPTH; i++)
  353.     PrVar[i] = killr0[i] = killr1[i] = killr2[i] = killr3[i] = 0;
  354.   /* set initial window for search */
  355.   alpha = score - ((computer == black) ? BAwindow : WAwindow);
  356.   beta = score + ((computer == black) ? BBwindow : WBwindow);
  357.   rpt = 0;
  358.   TrPnt[1] = 0;
  359.   root = &Tree[0];
  360.   MoveList (side, 1);
  361.   for (i = TrPnt[1]; i < TrPnt[2]; i++)
  362.     if (!pick (i, TrPnt[2] - 1))
  363.       break;
  364.   /* can I get a book move? */
  365.   if (flag.regularstart && Book)
  366.     {
  367.       flag.timeout = bookflag = OpeningBook (&hint, side);
  368.       if (TCflag)
  369.     ResponseTime += ResponseTime;
  370.     }
  371.   /* zero stats for hash table */
  372.   reminus = replus = 0;
  373.   GenCnt = NodeCnt = ETnodes = EvalNodes = HashCnt = FHashAdd = HashAdd = FHashCnt = THashCol = HashCol = 0;
  374.   globalscore = plyscore = score;
  375.   Jscore = 0;
  376.   zwndw = 20;
  377. #include "debug4.h"
  378.   /********************* main loop ********************************/
  379.   Sdepth = (MaxSearchDepth < (MINDEPTH - 1)) ? MaxSearchDepth : (MINDEPTH - 1);
  380.   while (!flag.timeout)
  381.     {
  382.       /* go down a level at a time */
  383.       Sdepth++;
  384. #ifdef NULLMOVE
  385.       null = 0;
  386.       PVari = 1;
  387. #endif
  388.       DepthBeyond = Sdepth + ((Sdepth == 1) ? 7 : 11);
  389.  
  390. #ifndef BAREBONES
  391. #ifdef QUIETBACKGROUND
  392.       if (!background)
  393. #endif /* QUIETBACKGROUND */
  394.     ShowDepth (' ');
  395. #endif
  396.       /* search at this level returns score of PV */
  397.       score = search (side, 1, Sdepth, alpha, beta, PrVar, &rpt);
  398.       /* save PV as killer */
  399.       for (i = 1; i <= Sdepth; i++) killr0[i] = PrVar[i];
  400.  
  401.       /* low search failure re-search with (-inf,score) limits  */
  402.       if (score < alpha)
  403.     {
  404. #ifndef BAREBONES
  405.       reminus++;
  406. #ifdef QUIETBACKGROUND
  407.       if (!background)
  408. #endif /* QUIETBACKGROUND */
  409.         ShowDepth ('-');
  410. #endif
  411.       if (TCflag && TCcount < MAXTCCOUNTR)
  412.         {
  413.           TCcount = MAXTCCOUNTR - 1;
  414.           ExtraTime += (8 * TCleft);
  415.         }
  416.  
  417.       score = search (side, 1, Sdepth, -9999, 9999, PrVar, &rpt);
  418.     }
  419.       /* high search failure re-search with (score, +inf) limits */
  420.       else if (score > beta && !(root->flags & exact))
  421.     {
  422. #ifndef BAREBONES
  423.       replus++;
  424. #ifdef QUIETBACKGROUND
  425.       if (!background)
  426. #endif /* QUIETBACKGROUND */
  427.         ShowDepth ('+');
  428. #endif
  429.       score = search (side, 1, Sdepth, -9999, 9999, PrVar, &rpt);
  430.     }
  431.       /**************** out of search ********************************************/
  432. SS:
  433.       if (flag.musttimeout || Sdepth >= MaxSearchDepth)
  434.     flag.timeout = true;
  435.  
  436.       else if (TCflag && (Sdepth > (MINDEPTH - 1)) && (TCcount < MAXTCCOUNTR))
  437.     {
  438.       if (killr0[1] != PrVar[1] /* || Killr0[2] != PrVar[2] */ )
  439.         {
  440.           TCcount++;
  441.           ExtraTime += TCleft;
  442.         }
  443.       if ((abs (score - globalscore) / Sdepth) > ZDELTA)
  444.         {
  445.           TCcount++;
  446.           ExtraTime += TCleft;
  447.         }
  448.     }
  449.       if (score > (Jscore - zwndw) && score > (Tree[1].score + 250))
  450.     ExtraTime = 0;
  451.       ElapsedTime (2);
  452.       if (root->flags & exact)
  453.     flag.timeout = true;
  454.       /*else if (Tree[1].score < -9000) flag.timeout = true;*/
  455. #if defined OLDTIME || !defined HASGETTIMEOFDAY
  456.       else if (!(Sdepth < MINDEPTH) && TCflag && ((4 * et) > (2 * ResponseTime + ExtraTime)))
  457.     flag.timeout = true;
  458. #else
  459.       else if (!(Sdepth < MINDEPTH) && TCflag &&
  460.            ((int) (1.93913099l * (pow ((double) et, 1.12446928l))) > (ResponseTime + ExtraTime)))
  461.     flag.timeout = true;
  462. #endif
  463.       /************************ time control ***********************************/
  464.  
  465.       /* save PV as killer */
  466.       for (i = 1; i <= Sdepth + 1; i++)
  467.     killr0[i] = PrVar[i];
  468.       if (!flag.timeout)
  469.     Tscore[0] = score;
  470.       /* if (!flag.timeout) */
  471. /*
  472.       for (i = TrPnt[1] + 1; i < TrPnt[2]; i++)
  473.     if (!pick (i, TrPnt[2] - 1))
  474.       break;
  475. /*
  476.       /* if done or nothing good to look at quit */
  477.       if ((root->flags & exact) || (score < -9000))
  478.     flag.timeout = true;
  479.       /* find the next best move put below root */
  480. #include "debug13.h"
  481.       if (!flag.timeout)
  482.     {
  483.       /* */
  484. #if !defined NODYNALPHA
  485.       Jscore = (plyscore + score) >> 1;
  486. #endif
  487.       zwndw = 20 + abs (Jscore / 12);
  488.       plyscore = score;
  489.       /* recompute search window */
  490.       beta = score + ((computer == black) ? BBwindow : WBwindow);
  491. #if !defined NODYNALPHA
  492.       alpha = ((Jscore < score) ? Jscore : score) - ((computer == black) ? BAwindow : WAwindow) - zwndw;
  493. #else
  494.       alpha = score - ((computer == black) ? BAwindow : WAwindow);
  495. #endif
  496.     }
  497. #ifndef BAREBONES
  498. #ifdef QUIETBACKGROUND
  499.       if (!background)
  500. #endif /* QUIETBACKGROUND */
  501.     ShowResults (score, PrVar, '.');
  502. #ifdef DEBUG41
  503.       debug41 (score, PrVar, '.');
  504. #endif
  505. #endif
  506. #include "debug16.h"
  507.     }
  508.   /******************************* end of main loop ***********************************/
  509.   /* background mode */
  510.   if (iop == 2)
  511.     return;
  512. #include "debug4.h"
  513.   if (rpt >= 2)
  514.     {
  515.       root->flags |= draw;
  516.       DRAW = CP[101];        /* Repetition */
  517.     }
  518.   else
  519.     /* if no moves and not in check then draw */
  520.   if ((score == -9999) && !(SqAtakd (PieceList[side][0], xside)))
  521.     {
  522.       root->flags |= draw;
  523.       DRAW = CP[87];        /* No moves */
  524.     }
  525.   else if (GameCnt == MAXMOVES)
  526.     {
  527.       root->flags |= draw;
  528.       DRAW = CP[80];        /* Max Moves */
  529.     }
  530.   /* not in book so set hint to guessed move for other side */
  531.   if (!bookflag)
  532.     hint = ((PrVar[1]) ? PrVar[2] : 0);
  533.  
  534.   /* if not mate or draw make move and output it */
  535.   if (((score > -9999) && (rpt <= 2)) || (root->flags & draw))
  536.     {
  537.       MakeMove (side, &Tree[0], &tempb, &tempc, &tempsf, &tempst, &INCscore);
  538. #if !defined NOMATERIAL
  539.       if (flag.material && !pmtl[black] && !pmtl[white] && (mtl[white] < (valueR + valueK)) && (mtl[black] < (valueR + valueK)))
  540.     {
  541.       root->flags |= draw;
  542.       DRAW = CP[224];    /* No pieces */
  543.     }
  544.       else
  545. #endif
  546.       if (!PieceCnt[black] && !PieceCnt[white])
  547.     {
  548.       root->flags |= draw;
  549.       DRAW = CP[88];    /* No pieces */
  550.     }
  551.       algbr (root->f, root->t, (short) root->flags);
  552.     }
  553.   else
  554.     {
  555.       algbr (0, 0, 0);        /* Zero move string when mate. */
  556.       root->score = score;    /* When mate, ignore distinctions!
  557.                  * --SMC */
  558.     }
  559.   g = &GameList[GameCnt];
  560.   if (g->flags & capture && g->piece == king)
  561.     {
  562.       flag.mate = flag.illegal = true;
  563.     }
  564.   /* If Time Control get the elapsed time */
  565.   if (TCflag)
  566.     ElapsedTime (1);
  567. #ifdef XBOARD
  568.   OutputMove (score, PrVar);
  569. #else
  570.   OutputMove ();
  571. #endif
  572.   /* if mate set flag */
  573.   if ((score == -9999 || score == 9998))
  574.     flag.mate = true;
  575.   /* if mate clear hint */
  576.   if (flag.mate)
  577.     hint = 0;
  578.   /* if pawn move or capture or castle or promote zero repitition array */
  579.   if ((board[root->t] == pawn) || (root->flags & (capture | cstlmask | promote)))
  580.     {
  581.       Game50 = GameCnt;
  582.       ZeroRPT ();
  583.     }
  584.   /* add move to game list */
  585.   g->score = score;
  586.   g->nodes = NodeCnt;
  587.   g->time = (et + 50) / 100;
  588.   g->depth = Sdepth;
  589. #include "debug40.h"
  590.   /* update time comtrol info */
  591.   if (TCflag)
  592.     {
  593.       TimeControl.clock[side] -= (et + OperatorTime);
  594.       timecomp[compptr] = (et + OperatorTime);
  595.       /* finished our required moves - setup the next set */
  596.       --TimeControl.moves[side];
  597.     }
  598.   /* check for end conditions */
  599.   if ((root->flags & draw) /* && flag.bothsides */ )
  600.     flag.mate = true;
  601.   else if (GameCnt == MAXMOVES)
  602.     {
  603.       flag.mate = true;
  604.     }
  605.   /* out of move store, you loose */
  606.   else
  607.     /* switch to other side */
  608.     player = xside;
  609.   Sdepth = 0;
  610. }
  611.  
  612.  
  613. int
  614. search (short int side,
  615.     register short int ply,
  616.     register short int depth,
  617.     short int alpha,
  618.     short int beta,
  619.     short unsigned int *bstline,
  620.     short int *rpt)
  621.  
  622. /*
  623.  * Perform an alpha-beta search to determine the score for the current board
  624.  * position. If depth <= 0 only capturing moves, pawn promotions and
  625.  * responses to check are generated and searched, otherwise all moves are
  626.  * processed. The search depth is modified for check evasions, certain
  627.  * re-captures and threats. Extensions may continue for up to 11 ply beyond
  628.  * the nominal search depth.
  629.  */
  630.  
  631.  
  632. {
  633.   register short j, pnt;
  634.   short tempb, tempc, tempsf, tempst;
  635.   short xside, pbst, score, rcnt, slk, InChk;
  636.   unsigned short mv, nxtline[MAXDEPTH];
  637.   struct leaf *node, tmp;
  638.   short best = -12000;
  639.   short bestwidth = 0;
  640. #ifdef NULLMOVE
  641.   short int PVsave;
  642.   short int PVarisave;
  643. #endif
  644.   NodeCnt++;
  645.   /* look every ZNODE nodes for a timeout */
  646. #ifdef NULLMOVE
  647.   if (!null)
  648.     {
  649. #endif
  650.       if (NodeCnt > ETnodes)
  651.     {
  652.       ElapsedTime (2);
  653.       if (flag.back)
  654.         {
  655.           flag.back = false;
  656.           flag.timeout = true;
  657.           flag.musttimeout = false;
  658.         }
  659.       else if (TCflag || MaxResponseTime)
  660.         {
  661.           if ((et >= (ResponseTime + ExtraTime)) && Sdepth > MINDEPTH )
  662.         {        /* try to extend to finish ply */
  663.           if (flag.back || (TCflag && TCcount < MAXTCCOUNTX))
  664.             {
  665.               flag.back = false;
  666.               flag.musttimeout = true;
  667.               TCcount += 1;
  668.               ExtraTime += TCleft;
  669.             }
  670.           else
  671.             {
  672.               flag.back = false;
  673.               flag.timeout = true;
  674.               flag.musttimeout = false;
  675.             }
  676.         }
  677.         }
  678.       else if (flag.back)
  679.         {
  680.           flag.back = false;
  681.           flag.timeout = true;
  682.           flag.musttimeout = false;
  683.         }
  684.  
  685.     }
  686.       else if (!TCflag && flag.musttimeout && Sdepth > MINDEPTH)
  687.     {
  688.       flag.timeout = true;
  689.       flag.musttimeout = false;
  690.     }
  691. #ifdef NULLMOVE
  692.     }
  693. #endif
  694.   xside = side ^ 1;
  695.   /* slk is lone king indicator for either side */
  696.   score = evaluate (side, ply, alpha, beta, INCscore, &InChk);
  697.  
  698.   /*
  699.    * check for possible repitition if so call repitition - rpt is
  700.    * repeat count
  701.    */
  702.   if ((ply <= Sdepth + 3) && rpthash[side][hashkey & 0xFF] > 0)
  703.     {
  704.       *rpt = repetition ();
  705.  
  706.       /*
  707.        * repeat position >2 don't need to return score it's taken
  708.        * care of above
  709.        */
  710.       if (*rpt == 1)
  711.     score /= 2;
  712.     }
  713.   else
  714.     *rpt = 0;
  715.  
  716.   /* score > 9000 its a draw or mate */
  717.   if (score > 9000)
  718.     {
  719.       bstline[ply] = 0;
  720.       return (score);
  721.     }
  722.   /* Do we need to add depth because of special conditions */
  723.   /* if in check or pawn threat or in capture sequence search deeper */
  724.   /*************************************** depth extensions ***********************************/
  725.   if (depth > 0)
  726.     {
  727.       /* Allow opponent a chance to check again */
  728.       if (InChk)
  729.     depth = (depth < 2) ? 2 : depth;
  730.       else if (PawnThreat[ply - 1] ||
  731.            (flag.rcptr && (score > alpha) &&
  732.       (score < beta) && (ply > 2) && CptrFlag[ply - 1] && CptrFlag[ply - 2]))
  733.     ++depth;
  734.     }
  735.   else
  736.     {
  737.       if (score >= alpha &&
  738.       (InChk || PawnThreat[ply - 1] || (hung[side] > 1 && ply == Sdepth + 1)))
  739.     depth = 1;
  740.       else if (score <= beta &&
  741.            ((ply < Sdepth + 4) && (ply > 4) &&
  742.         ChkFlag[ply - 2] && ChkFlag[ply - 4] &&
  743.         ChkFlag[ply - 2] != ChkFlag[ply - 4]))
  744.     depth = 1;
  745.     }
  746.   /*******************************************************************************************/
  747.   /* try the local transition table if it's there */
  748. #if ttblsz
  749.   if ( /*depth > 0 &&*/ flag.hash && ply > 1)
  750.     {
  751.       if (ProbeTTable (side, depth, ply, &alpha, &beta, &score) == true)
  752.     {
  753.       bstline[ply] = PV;
  754.       bstline[ply + 1] = 0;
  755. #include "debug64.h"
  756.       if (beta == -20000)
  757.         return (score);
  758.       if (alpha > beta)
  759.         return (alpha);
  760.     }
  761. #ifdef HASHFILE
  762.       /* ok try the transition file if its there */
  763.       else if (hashfile && (depth > HashDepth) && (GameCnt < HashMoveLimit)
  764.      && (ProbeFTable (side, depth, ply, &alpha, &beta, &score) == true))
  765.     {
  766.           PutInTTable (side, score, depth, ply, alpha, beta, PV);
  767.           bstline[ply] = PV;
  768.           bstline[ply + 1] = 0;
  769.           if (beta == -20000)
  770.         return (score);
  771.           if (alpha > beta)
  772.         return (alpha);
  773. #include "debug10.h"
  774.     }
  775. #endif /* HASHFILE */
  776.     }
  777. #endif /* ttblsz */
  778.  
  779.   /*
  780.    * if more then DepthBeyond ply past goal depth or at goal depth and
  781.    * score > beta quit - means we are out of the window
  782.    */
  783.   if (ply > DepthBeyond || (depth < 1 && score > beta))
  784.     {
  785.       return (score);
  786.     }
  787.  
  788.   /*
  789.    * if below first ply and not at goal depth generate all moves else
  790.    * only capture moves
  791.    */
  792.   if (ply > 1)
  793.     if (depth > 0 || ply < (SDEPTHLIM) ||
  794.     (background && ply < Sdepth + 2))
  795.       {
  796.     MoveList (side, ply);
  797.       }
  798.     else
  799.       {
  800.     CaptureList (side, ply);
  801.       }
  802.  
  803.   /* no moves return what we have */
  804.  
  805.   /*
  806.    * normally a search will continue til past goal and no more capture
  807.    * moves exist
  808.    */
  809.   /* unless it hits DepthBeyond */
  810.   if (TrPnt[ply] == TrPnt[ply + 1])
  811.     {
  812.       return (score);
  813.     }
  814.  
  815.  
  816.  
  817.   /* if not at goal set best = -inf else current score */
  818.   best = (depth > 0) ? -12000 : score;
  819. #ifdef NULLMOVE
  820.  
  821.   PVarisave = PVari;
  822.   if (!null &&            /* no previous null-move */
  823.       !PVari &&            /* no null-move during the PV */
  824.       (ply > 2) &&        /* not at ply 1 */
  825.       (ply <= Sdepth) &&
  826.       (depth > 3) &&
  827.       !InChk &&            /* no check */
  828.       ((mtl[side] + mtl[xside]) > NULLMOVELIM))
  829.     /* enough material such that zugzwang is unlike but who knows which value
  830.        is suitable? */
  831.     {
  832.  
  833.       /* ok, we make a null move, i.e.  this means we have nothing to do
  834.       but we have to keep the some arrays up to date otherwise gnuchess
  835.       gets confused.  Maybe somebody knows exactly which informations are
  836.      important and which not.
  837.  
  838.      Another idea is that we try the null-move first and generate the
  839.      moves later.  This may save time but we have to take care that
  840.      PV and other variables contain the right value so that the move
  841.      ordering works right.
  842.      */
  843.       register struct GameRec *g;
  844.  
  845.       nxtline[ply + 1] = 0;
  846.       CptrFlag[ply] = 0;
  847.       PawnThreat[ply] = 0;
  848.       Tscore[ply] = score;
  849.       PVsave = PV;
  850.       PV = 0;
  851.       null = 1;
  852.       g = &GameList[++GameCnt];
  853.       g->hashkey = hashkey;
  854.       g->hashbd = hashbd;
  855.       epsquare = -1;
  856.       TOsquare = -1;
  857.       g->Game50 = Game50;
  858.       g->gmove = -1;
  859.       g->flags = 0;
  860.       g->piece = 0;
  861.       g->color = neutral;
  862.  
  863.       best = -search (xside, ply + 1, depth - 2, -beta - 1, -beta, nxtline, &rcnt);
  864.       null = 0;
  865.       PV = PVsave;
  866.       GameCnt--;
  867.     if (best < alpha) best = -12000;
  868.       else if (best > beta) return (best);
  869.       else best = -12000;
  870.     }
  871. #endif
  872.   /* if best so far is better than alpha set alpha to best */
  873.   if (best > alpha)
  874.     alpha = best;
  875.   /********************** main loop ************************************************************************/
  876.   /* look at each move until no more or beta cutoff */
  877.   for (pnt = pbst = TrPnt[ply]; pnt < TrPnt[ply + 1] && best <= beta; pnt++)
  878.     {
  879.       /* find the most interesting looking of the remaining moves */
  880.       if (ply > 1)
  881.     pick (pnt, TrPnt[ply + 1] - 1);
  882. #ifdef NULLMOVE
  883.       PVari = PVarisave && (pnt == TrPnt[ply]);    /* Is this the PV? */
  884. #endif
  885.  
  886.       node = &Tree[pnt];
  887.       /* is this a forbidden move */
  888.       if (ply == 1 && node->score == -32768) continue;
  889.       nxtline[ply + 1] = 0;
  890.  
  891. #ifndef BAREBONES
  892.       /* if at top level */
  893.       if (ply == 1)
  894.     {            /* at the top update search status */
  895.       if (flag.post)
  896. #ifdef QUIETBACKGROUND
  897.         if (!background)
  898. #endif /* QUIETBACKGROUND */
  899.           ShowCurrentMove (pnt, node->f, node->t);
  900.     }
  901. #endif
  902.       if (!(node->flags & exact))
  903.     {
  904.       /* make the move and go deeper */
  905.       MakeMove (side, node, &tempb, &tempc, &tempsf, &tempst, &INCscore);
  906.       CptrFlag[ply] = (node->flags & capture);
  907.       PawnThreat[ply] = (node->flags & pwnthrt);
  908.       Tscore[ply] = node->score;
  909.       PV = node->reply;
  910.       node->score = -search (xside, ply + 1,
  911.                  (depth > 0) ? depth - 1 : 0,
  912.                  -beta, -alpha,
  913.                  nxtline, &rcnt);
  914. /*
  915.           if(!flag.timeout)node->score = score;
  916. */
  917.       node->width = (ply % 2 == 1) ? (TrPnt[ply + 2] - TrPnt[ply + 1]) : 0;
  918.       if (abs (node->score) > 9000)
  919.         node->flags |= exact;
  920.       else if (rcnt == 1)
  921.         node->score /= 2;
  922. #include "debug256.h"
  923.       if ((rcnt >= 2 || GameCnt - Game50 > 99 || (node->score == 9999 - ply && !ChkFlag[ply])))
  924.         {
  925.           node->flags |= (draw | exact);
  926.           DRAW = CP[58];    /* Draw */
  927.           node->score = ((side == computer) ? contempt : -contempt);
  928.         }
  929.       node->reply = nxtline[ply + 1];
  930.       /* reset to try next move */
  931.       UnmakeMove (side, node, &tempb, &tempc, &tempsf, &tempst);
  932.     }
  933.       /* if best move so far */
  934.       if (!flag.timeout && ((node->score > best) || ((node->score == best) && (node->width > bestwidth))))
  935.     {
  936.       /*
  937.        * all things being equal pick the denser part of the
  938.        * tree
  939.        */
  940.       bestwidth = node->width;
  941.  
  942.       /*
  943.        * if not at goal depth and better than alpha and not
  944.        * an exact score increment by depth
  945.        */
  946.       if (depth > 0 && node->score > alpha && !(node->flags & exact))
  947.         node->score += depth;
  948.       best = node->score;
  949.       pbst = pnt;
  950.       if (best > alpha)
  951.         {
  952.           alpha = best;
  953.         }
  954.       /* update best line */
  955.       for (j = ply + 1; nxtline[j] > 0; j++)
  956.         bstline[j] = nxtline[j];
  957.       bstline[j] = 0;
  958.       bstline[ply] = (node->f << 8) | node->t;
  959.       /* if at the top */
  960.       if (ply == 1)
  961.         {
  962.           /*
  963.            * if its better than the root score make it
  964.            * the root
  965.            */
  966.           if ((best > root->score) || ((best == root->score) && (bestwidth > root->width)))
  967.         {
  968.           tmp = Tree[pnt];
  969.           for (j = pnt - 1; j >= 0; j--)
  970.             Tree[j + 1] = Tree[j];
  971.           Tree[0] = tmp;
  972.           pbst = 0;
  973.         }
  974. #ifndef BAREBONES
  975. #ifdef QUIETBACKGROUND
  976.           if (!background)
  977. #endif /* QUIETBACKGROUND */
  978.         if (Sdepth > 2)
  979.           if (best > beta)
  980.             {
  981.               ShowResults (best, bstline, '+');
  982.             }
  983.           else if (best < alpha)
  984.             {
  985.               ShowResults (best, bstline, '-');
  986.             }
  987.           else
  988.             ShowResults (best, bstline, '&');
  989. #endif
  990.           if (!background && Sdepth > 2){
  991.              if( best < alpha ) { TCcount = 0;ExtraTime += 9*TCleft;}
  992.                  }
  993.         }
  994.     }
  995.       if (flag.timeout)
  996.     {
  997.       return (Tscore[ply - 1]);
  998.     }
  999.     }
  1000.  
  1001.   /******************************************************************************************/
  1002.   node = &Tree[pbst];
  1003.   mv = (node->f << 8) | node->t;
  1004. #ifdef NULLMOVE
  1005.   PVari = PVarisave;
  1006. #endif
  1007.  
  1008.   /*
  1009.    * we have a move so put it in local table - if it's already there
  1010.    * done else if not there or needs to be updated also put it in
  1011.    * hashfile
  1012.    */
  1013. #if ttblsz
  1014.   if (flag.hash && ply <= Sdepth && *rpt == 0 && best == alpha)
  1015.     {
  1016.       if (PutInTTable (side, best, depth, ply, alpha, beta, mv)
  1017. #ifdef HASHFILE
  1018.       && hashfile && (depth > HashDepth) && (GameCnt < HashMoveLimit))
  1019.     {
  1020.       PutInFTable (side, best, depth, ply, alpha, beta, node->f, node->t);
  1021.     }
  1022. #else
  1023.     );
  1024. #endif /* HASHFILE */
  1025.     }
  1026. #endif /* ttblsz */
  1027.   if (depth > 0)
  1028.     {
  1029. #ifdef HISTORY
  1030.       j = (node->f << 8) | node->t;
  1031.       if (side == black)
  1032.     j |= 0x4000;
  1033.       if (history[j] < HISTORYLIM)
  1034.     history[j] += (unsigned short) 1 << depth;
  1035. #endif
  1036.       if (node->t != (short) (GameList[GameCnt].gmove & 0xFF))
  1037.     if (best <= beta)
  1038.       killr3[ply] = mv;
  1039.     else if (mv != killr1[ply])
  1040.       {
  1041.         killr2[ply] = killr1[ply];
  1042.         killr1[ply] = mv;
  1043.       }
  1044.       killr0[ply] = ((best > 9000) ? mv : 0);
  1045.     }
  1046.   return (best);
  1047. }
  1048.  
  1049.  
  1050.  
  1051.  
  1052. int
  1053. castle (short int side, short int kf, short int kt, short int iop)
  1054.  
  1055. /* Make or Unmake a castling move. */
  1056.  
  1057. {
  1058.   register short rf, rt, t0, xside;
  1059.  
  1060.   xside = side ^ 1;
  1061.   if (kt > kf)
  1062.     {
  1063.       rf = kf + 3;
  1064.       rt = kt - 1;
  1065.     }
  1066.   else
  1067.     {
  1068.       rf = kf - 4;
  1069.       rt = kt + 1;
  1070.     }
  1071.   if (iop == 0)
  1072.     {
  1073.       if (kf != kingP[side] ||
  1074.       board[kf] != king ||
  1075.       board[rf] != rook ||
  1076.       color[kf] != side ||
  1077.       color[rf] != side ||
  1078.       Mvboard[kf] != 0 ||
  1079.       Mvboard[rf] != 0 ||
  1080.       color[kt] != neutral ||
  1081.       color[rt] != neutral ||
  1082.       color[kt - 1] != neutral ||
  1083.       SqAtakd (kf, xside) ||
  1084.       SqAtakd (kt, xside) ||
  1085.       SqAtakd (rt, xside))
  1086.     return (false);
  1087.     }
  1088.   else
  1089.     {
  1090.       if (iop == 1)
  1091.     {
  1092.       castld[side] = true;
  1093.       Mvboard[kf]++;
  1094.       Mvboard[rf]++;
  1095.     }
  1096.       else
  1097.     {
  1098.       castld[side] = false;
  1099.       Mvboard[kf]--;
  1100.       Mvboard[rf]--;
  1101.       t0 = kt;
  1102.       kt = kf;
  1103.       kf = t0;
  1104.       t0 = rt;
  1105.       rt = rf;
  1106.       rf = t0;
  1107.     }
  1108.       board[kt] = king;
  1109.       color[rt] = color[kt] = side;
  1110.       Pindex[kt] = 0;
  1111.       board[kf] = no_piece;
  1112.       color[rf] = color[kf] = neutral;
  1113.       board[rt] = rook;
  1114.       Pindex[rt] = Pindex[rf];
  1115.       board[rf] = no_piece;
  1116.       PieceList[side][Pindex[kt]] = kt;
  1117.       PieceList[side][Pindex[rt]] = rt;
  1118.       UpdateHashbd (side, king, kf, kt);
  1119.       UpdateHashbd (side, rook, rf, rt);
  1120.     }
  1121.   return (true);
  1122. }
  1123.  
  1124.  
  1125. void
  1126. EnPassant (short int xside, short int f, short int t, short int iop)
  1127.  
  1128. /*
  1129.  * Make or unmake an en passant move.
  1130.  */
  1131.  
  1132. {
  1133.   register short l;
  1134.  
  1135.   l = t + ((t > f) ? -8 : 8);
  1136.   if (iop == 1)
  1137.     {
  1138.       board[l] = no_piece;
  1139.       color[l] = neutral;
  1140.     }
  1141.   else
  1142.     {
  1143.       board[l] = pawn;
  1144.       color[l] = xside;
  1145.     }
  1146.   InitializeStats ();
  1147. }
  1148.  
  1149.  
  1150. void
  1151. UpdatePieceList (short int side, short int sq, short int iop)
  1152.  
  1153. /*
  1154.  * Update the PieceList and Pindex arrays when a piece is captured or when a
  1155.  * capture is unmade.
  1156.  */
  1157.  
  1158. {
  1159.   register short i;
  1160.  
  1161.   if (iop == 1)
  1162.     {
  1163.       PieceCnt[side]--;
  1164.       for (i = Pindex[sq]; i <= PieceCnt[side]; i++)
  1165.     {
  1166.       PieceList[side][i] = PieceList[side][i + 1];
  1167.       Pindex[PieceList[side][i]] = i;
  1168.     }
  1169.     }
  1170.   else
  1171.     {
  1172.       PieceCnt[side]++;
  1173.       PieceList[side][PieceCnt[side]] = sq;
  1174.       Pindex[sq] = PieceCnt[side];
  1175.     }
  1176. }
  1177.  
  1178. void
  1179. MakeMove (short int side,
  1180.       struct leaf *node,
  1181.       short int *tempb,    /* color of to square */
  1182.       short int *tempc,    /* piece at to square */
  1183.       short int *tempsf,    /* static value of piece on from */
  1184.       short int *tempst,    /* static value of piece on to */
  1185.       short int *INCscore)    /* score increment for pawn structure change */
  1186.  
  1187. /*
  1188.  * Update Arrays board[], color[], and Pindex[] to reflect the new board
  1189.  * position obtained after making the move pointed to by node. Also update
  1190.  * miscellaneous stuff that changes when a move is made.
  1191.  */
  1192.  
  1193. {
  1194.   register short f, t, xside, ct, cf;
  1195.   register struct GameRec *g;
  1196.  
  1197.   xside = side ^ 1;
  1198.   g = &GameList[++GameCnt];
  1199.   g->hashkey = hashkey;
  1200.   g->hashbd = hashbd;
  1201.   g->epssq = epsquare;
  1202.   f = node->f;
  1203.   t = node->t;
  1204.   epsquare = -1;
  1205.   /* FROMsquare = f;*/
  1206.   TOsquare = t;
  1207.   *INCscore = 0;
  1208.   g->Game50 = Game50;
  1209.   g->gmove = (f << 8) | t;
  1210.   g->flags = node->flags;
  1211.   if (node->flags & cstlmask)
  1212.     {
  1213.       g->piece = no_piece;
  1214.       g->color = side;
  1215.       (void) castle (side, f, t, 1);
  1216.       Game50 = GameCnt;
  1217.     }
  1218.   else
  1219.     {
  1220.       if (!(node->flags & capture) && (board[f] != pawn))
  1221.     {
  1222.       rpthash[side][hashkey & 0xFF]++;
  1223.       ISZERO++;
  1224.     }
  1225.       else
  1226.     Game50 = GameCnt;
  1227.       *tempsf = svalue[f];
  1228.       *tempst = svalue[t];
  1229.       g->piece = *tempb = board[t];
  1230.       g->color = *tempc = color[t];
  1231.       if (*tempc != neutral)
  1232.     {
  1233.       UpdatePieceList (*tempc, t, 1);
  1234.       /* if capture decrement pawn count */
  1235.       if (*tempb == pawn)
  1236.         {
  1237.           --PawnCnt[*tempc][column (t)];
  1238.         }
  1239.       if (board[f] == pawn)
  1240.         {
  1241.           cf = column (f);
  1242.           ct = column (t);
  1243.           /* move count from from to to */
  1244.           --PawnCnt[side][cf];
  1245.           ++PawnCnt[side][ct];
  1246.  
  1247.           /*
  1248.            * calculate increment for pawn structure
  1249.            * changes
  1250.            */
  1251.           /* doubled or more - */
  1252.           if (PawnCnt[side][ct] > (1 + PawnCnt[side][cf]))
  1253.         *INCscore -= 15;
  1254.           /* went to empty column + */
  1255.           else if (PawnCnt[side][ct] < 1 + PawnCnt[side][cf])
  1256.         *INCscore += 15;
  1257.  
  1258.           /*
  1259.            * went to outside col or empty col on one
  1260.            * side ????????
  1261.            */
  1262.           else if (ct == 0 || ct == 7 || PawnCnt[side][ct + ct - cf] == 0)
  1263.         *INCscore -= 15;
  1264.         }
  1265.       mtl[xside] -= value[*tempb];
  1266.       if (*tempb == pawn)
  1267.         pmtl[xside] -= valueP;
  1268.       UpdateHashbd (xside, *tempb, -1, t);
  1269.       *INCscore += *tempst;
  1270.       Mvboard[t]++;
  1271.     }
  1272.       color[t] = color[f];
  1273.       board[t] = board[f];
  1274.       svalue[t] = svalue[f];
  1275.       Pindex[t] = Pindex[f];
  1276.       PieceList[side][Pindex[t]] = t;
  1277.       color[f] = neutral;
  1278.       board[f] = no_piece;
  1279.       if (board[t] == pawn)
  1280.     if (t - f == 16)
  1281.       epsquare = f + 8;
  1282.     else if (f - t == 16)
  1283.       epsquare = f - 8;
  1284.       if (node->flags & promote)
  1285.     {
  1286.       board[t] = node->flags & pmask;
  1287.       if (board[t] == queen)
  1288.         HasQueen[side]++;
  1289.       else if (board[t] == rook)
  1290.         HasRook[side]++;
  1291.       else if (board[t] == bishop)
  1292.         HasBishop[side]++;
  1293.       else if (board[t] == knight)
  1294.         HasKnight[side]++;
  1295.       --PawnCnt[side][column (t)];
  1296.       mtl[side] += value[board[t]] - valueP;
  1297.       pmtl[side] -= valueP;
  1298.       UpdateHashbd (side, pawn, f, -1);
  1299.       UpdateHashbd (side, board[t], f, -1);
  1300.       *INCscore -= *tempsf;
  1301.     }
  1302.       if (node->flags & epmask)
  1303.     EnPassant (xside, f, t, 1);
  1304.       else
  1305.     UpdateHashbd (side, board[t], f, t);
  1306.       Mvboard[f]++;
  1307.     }
  1308. }
  1309.  
  1310. void
  1311. UnmakeMove (short int side,
  1312.         struct leaf *node,
  1313.         short int *tempb,
  1314.         short int *tempc,
  1315.         short int *tempsf,
  1316.         short int *tempst)
  1317.  
  1318. /*
  1319.  * Take back a move.
  1320.  */
  1321.  
  1322. {
  1323.   register short f, t, xside;
  1324.  
  1325.   xside = side ^ 1;
  1326.   f = node->f;
  1327.   t = node->t;
  1328.   Game50 = GameList[GameCnt].Game50;
  1329.   if (node->flags & cstlmask)
  1330.     (void) castle (side, f, t, 2);
  1331.   else
  1332.     {
  1333.       color[f] = color[t];
  1334.       board[f] = board[t];
  1335.       svalue[f] = *tempsf;
  1336.       Pindex[f] = Pindex[t];
  1337.       PieceList[side][Pindex[f]] = f;
  1338.       color[t] = *tempc;
  1339.       board[t] = *tempb;
  1340.       svalue[t] = *tempst;
  1341.       if (node->flags & promote)
  1342.     {
  1343.       board[f] = pawn;
  1344.       ++PawnCnt[side][column (t)];
  1345.       mtl[side] += valueP - value[node->flags & pmask];
  1346.       pmtl[side] += valueP;
  1347.       UpdateHashbd (side, (short) node->flags & pmask, -1, t);
  1348.       UpdateHashbd (side, pawn, -1, t);
  1349.     }
  1350.       if (*tempc != neutral)
  1351.     {
  1352.       UpdatePieceList (*tempc, t, 2);
  1353.       if (*tempb == pawn)
  1354.         {
  1355.           ++PawnCnt[*tempc][column (t)];
  1356.         }
  1357.       if (board[f] == pawn)
  1358.         {
  1359.           --PawnCnt[side][column (t)];
  1360.           ++PawnCnt[side][column (f)];
  1361.         }
  1362.       mtl[xside] += value[*tempb];
  1363.       if (*tempb == pawn)
  1364.         pmtl[xside] += valueP;
  1365.       UpdateHashbd (xside, *tempb, -1, t);
  1366.       Mvboard[t]--;
  1367.     }
  1368.       if (node->flags & epmask)
  1369.     {
  1370.       EnPassant (xside, f, t, 2);
  1371.     }
  1372.       else
  1373.     UpdateHashbd (side, board[f], f, t);
  1374.       Mvboard[f]--;
  1375.       if (!(node->flags & capture) && (board[f] != pawn))
  1376.     {
  1377.       rpthash[side][hashkey & 0xFF]--;
  1378.       ISZERO--;
  1379.     }
  1380.     }
  1381.   epsquare = GameList[GameCnt--].epssq;
  1382. }
  1383.  
  1384.  
  1385. void
  1386. InitializeStats (void)
  1387.  
  1388. /*
  1389.  * Scan thru the board seeing what's on each square. If a piece is found,
  1390.  * update the variables PieceCnt, PawnCnt, Pindex and PieceList. Also
  1391.  * determine the material for each side and set the hashkey and hashbd
  1392.  * variables to represent the current board position. Array
  1393.  * PieceList[side][indx] contains the location of all the pieces of either
  1394.  * side. Array Pindex[sq] contains the indx into PieceList for a given
  1395.  * square.
  1396.  */
  1397.  
  1398. {
  1399.   register short i, sq;
  1400.  
  1401.   epsquare = -1;
  1402.   for (i = 0; i < 8; i++)
  1403.     {
  1404.       PawnCnt[white][i] = PawnCnt[black][i] = 0;
  1405.     }
  1406.   mtl[white] = mtl[black] = pmtl[white] = pmtl[black] = 0;
  1407.   PieceCnt[white] = PieceCnt[black] = 0;
  1408.   hashbd = hashkey = 0;
  1409.   for (sq = 0; sq < 64; sq++)
  1410.     if (color[sq] != neutral)
  1411.       {
  1412.     mtl[color[sq]] += value[board[sq]];
  1413.     if (board[sq] == pawn)
  1414.       {
  1415.         pmtl[color[sq]] += valueP;
  1416.         ++PawnCnt[color[sq]][column (sq)];
  1417.       }
  1418.     Pindex[sq] = ((board[sq] == king) ? 0 : ++PieceCnt[color[sq]]);
  1419.  
  1420.     PieceList[color[sq]][Pindex[sq]] = sq;
  1421.     hashbd ^= hashcode[color[sq]][board[sq]][sq].bd;
  1422.     hashkey ^= hashcode[color[sq]][board[sq]][sq].key;
  1423.       }
  1424. }
  1425.