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

  1. /*
  2.  * eval.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 "ataks.h"
  27. #include "ttable.h" /* uses hashbd, hashkey and eval cache */
  28.  
  29. /* Backward pawn bonus indexed by # of attackers on the square */
  30. static const SHORT BACKWARD[16] =
  31. {-6, -10, -15, -21, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28};
  32.  
  33. /* Bishop mobility bonus indexed by # reachable squares */
  34. static const SHORT BMBLTY[14] =
  35. {-2, 0, 2, 4, 6, 8, 10, 12, 13, 14, 15, 16, 16, 16};
  36.  
  37. /* Rook mobility bonus indexed by # reachable squares */
  38. static const SHORT RMBLTY[15] =
  39. {0, 2, 4, 6, 8, 10, 11, 12, 13, 14, 14, 14, 14, 14, 14};
  40.  
  41. /* Positional values for a dying king */
  42. static const SHORT DyingKing[64] =
  43. {0, 8, 16, 24, 24, 16, 8, 0,
  44.  8, 32, 40, 48, 48, 40, 32, 8,
  45.  16, 40, 56, 64, 64, 56, 40, 16,
  46.  24, 48, 64, 72, 72, 64, 48, 24,
  47.  24, 48, 64, 72, 72, 64, 48, 24,
  48.  16, 40, 56, 64, 64, 56, 40, 16,
  49.  8, 32, 40, 48, 48, 40, 32, 8,
  50.  0, 8, 16, 24, 24, 16, 8, 0};
  51.  
  52. /* Isolated pawn penalty by rank */
  53. static const SHORT ISOLANI[8] =
  54. /*{-18, -20, -22, -24, -24, -22, -20, -18};*/
  55. {-8, -10, -12, -14, -14, -12, -10, -8};
  56.  
  57. /* table for King Bishop Knight endings */
  58. static const SHORT KBNK[64] =
  59. {620, 560, 500, 440, 380, 320, 260, 240,
  60.  560, 520, 460, 400, 340, 280, 230, 260,
  61.  500, 460, 320, 280, 260, 220, 280, 320,
  62.  440, 400, 280, 200, 200, 260, 340, 380,
  63.  380, 340, 260, 200, 200, 280, 400, 440,
  64.  320, 280, 220, 260, 280, 320, 460, 500,
  65.  260, 230, 280, 340, 400, 460, 520, 560,
  66.  240, 260, 320, 380, 440, 500, 560, 620};
  67.  
  68. /* penalty for threats to king, indexed by number of such threats */
  69. static const SHORT KTHRT[36] =
  70. {0, -8, -20, -36, -52, -68, -80, -80, -80, -80, -80, -80,
  71.  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
  72.  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80};
  73.  
  74. /* King positional bonus inopening stage */
  75. static const SHORT KingOpening[64] =
  76. {0, 0, -4, -10, -10, -4, 0, 0,
  77.  -4, -4, -8, -12, -12, -8, -4, -4,
  78.  -12, -16, -20, -20, -20, -20, -16, -12,
  79.  -16, -20, -24, -24, -24, -24, -20, -16,
  80.  -16, -20, -24, -24, -24, -24, -20, -16,
  81.  -12, -16, -20, -20, -20, -20, -16, -12,
  82.  -4, -4, -8, -12, -12, -8, -4, -4,
  83.  0, 0, -4, -10, -10, -4, 0, 0};
  84.  
  85. /* King positional bonus in end stage */
  86. static const SHORT KingEnding[64] =
  87. {0, 6, 12, 18, 18, 12, 6, 0,
  88.  6, 12, 18, 24, 24, 18, 12, 6,
  89.  12, 18, 24, 30, 30, 24, 18, 12,
  90.  18, 24, 30, 36, 36, 30, 24, 18,
  91.  18, 24, 30, 36, 36, 30, 24, 18,
  92.  12, 18, 24, 30, 30, 24, 18, 12,
  93.  6, 12, 18, 24, 24, 18, 12, 6,
  94.  0, 6, 12, 18, 18, 12, 6, 0};
  95.  
  96. /* Passed pawn positional bonus */
  97. static const SHORT PassedPawn0[8] =
  98. {0, 60, 80, 120, 200, 360, 600, 800};
  99. static const SHORT PassedPawn1[8] =
  100. {0, 30, 40, 60, 100, 180, 300, 800};
  101. static const SHORT PassedPawn2[8] =
  102. {0, 15, 25, 35, 50, 90, 140, 800};
  103. static const SHORT PassedPawn3[8] =
  104. {0, 5, 10, 15, 20, 30, 140, 800};
  105.  
  106. /* Knight positional bonus */
  107. static const SHORT pknight[64] =
  108. {0, 4, 8, 10, 10, 8, 4, 0,
  109.  4, 8, 16, 20, 20, 16, 8, 4,
  110.  8, 16, 24, 28, 28, 24, 16, 8,
  111.  10, 20, 28, 32, 32, 28, 20, 10,
  112.  10, 20, 28, 32, 32, 28, 20, 10,
  113.  8, 16, 24, 28, 28, 24, 16, 8,
  114.  4, 8, 16, 20, 20, 16, 8, 4,
  115.  0, 4, 8, 10, 10, 8, 4, 0};
  116.  
  117. /* Bishop positional bonus */
  118. static const SHORT pbishop[64] =
  119. {14, 14, 14, 14, 14, 14, 14, 14,
  120.  14, 22, 18, 18, 18, 18, 22, 14,
  121.  14, 18, 22, 22, 22, 22, 18, 14,
  122.  14, 18, 22, 22, 22, 22, 18, 14,
  123.  14, 18, 22, 22, 22, 22, 18, 14,
  124.  14, 18, 22, 22, 22, 22, 18, 14,
  125.  14, 22, 18, 18, 18, 18, 22, 14,
  126.  14, 14, 14, 14, 14, 14, 14, 14};
  127.  
  128. /* Pawn positional bonus */
  129. static const SHORT PawnAdvance[64] =
  130. {0, 0, 0, 0, 0, 0, 0, 0,
  131.  4, 4, 4, 0, 0, 4, 4, 4,
  132.  6, 8, 8, 10, 10, 8, 8, 6,
  133.  6, 8, 12, 16, 16, 12, 8, 6,
  134.  8, 12, 16, 24, 24, 16, 12, 8,
  135.  12, 16, 24, 32, 32, 24, 16, 12,
  136.  12, 16, 24, 32, 32, 24, 16, 12,
  137.  0, 0, 0, 0, 0, 0, 0, 0};
  138.  
  139. static const SHORT CentralPawn[64] =
  140. { 0, 0, 0, 0, 0, 0, 0, 0,
  141.   0, 0, 0, 0, 0, 0, 0, 0,
  142.   0, 0, 0, 0, 0, 0, 0, 0,
  143.   0, 0, 0, 1, 1, 0, 0, 0,
  144.   0, 0, 0, 1, 1, 0, 0, 0,
  145.   0, 0, 0, 0, 0, 0, 0, 0,
  146.   0, 0, 0, 0, 0, 0, 0, 0,
  147.   0, 0, 0, 0, 0, 0, 0, 0} ;
  148.  
  149.  
  150. #define AHOPEN (-270)
  151.  
  152. static SHORT kpkwv_ (SHORT, SHORT, SHORT, SHORT, SHORT, SHORT);
  153. static SHORT kpkbv_ (SHORT, SHORT, SHORT, SHORT, SHORT, SHORT);
  154. inline static int ScoreKBNK (SHORT, SHORT, SHORT);
  155. inline static int ScoreK1PK (SHORT, SHORT, SHORT, SHORT, SHORT, SHORT);
  156.  
  157. SHORT PUTVAR = false;
  158. SHORT Mwpawn[64], Mbpawn[64], Mknight[2][64], Mbishop[2][64];
  159. static SHORT Mking[2][64], Kfield[2][64];
  160. static SHORT c1, c2, *atk1, *atk2, *PC1, *PC2;
  161. SHORT atak[2][64];
  162. SHORT emtl[2];
  163. static SHORT PawnBonus, BishopBonus, RookBonus;
  164. static SHORT KNIGHTPOST, KNIGHTSTRONG, BISHOPSTRONG, KATAK;
  165. static SHORT PEDRNK2B, PWEAKH, PADVNCM, PADVNCI, PAWNSHIELD, PDOUBLED, PBLOK;
  166. static SHORT RHOPN, RHOPNX, KHOPN, KHOPNX, KSFTY;
  167. static SHORT ATAKD, HUNGP, HUNGX, KCASTLD, KMOVD, XRAY, PINVAL;
  168. SHORT pscore[2];
  169. /************************* Evaluation cache code ****************************/
  170. /* NOTE: The static evaluation cache "EETable" belongs to eval.c and cannot */
  171. /*       be moved to ttable.c */
  172.  
  173. #ifdef CACHE
  174. struct etable *etab[2];
  175.  
  176. inline void
  177. PutInEETable (SHORT side,int score)
  178.  
  179. /*
  180.  * Store the current eval position in the static cache
  181.  */
  182.  
  183. {
  184.     register struct etable *ptbl;
  185. #ifdef DEBUG
  186.     if (flag.nocache) return;
  187. #endif
  188.     ptbl = &((etab[side])[hashkey % (ETABLE)]);
  189.     ptbl->ehashbd = hashbd;
  190.     ptbl->escore[white] = pscore[white];
  191.     ptbl->escore[black] = pscore[black];
  192.     ptbl->hung[white] = hung[white];
  193.     ptbl->hung[black] = hung[black];
  194.     ptbl->score = score;
  195.     memcpy (ptbl->sscore, svalue, sizeof (svalue));
  196. #if defined HASHSTATS 
  197.     EADD++;
  198. #endif
  199.     return;
  200. }
  201.  
  202. inline int
  203. CheckEETable (SHORT side)
  204.  
  205. /* Check the static cache for an entry  */
  206. {
  207.     register struct etable *ptbl;
  208. #ifdef DEBUG
  209.     if (flag.nocache) return false;
  210. #endif
  211.     ptbl = &((etab[side])[hashkey % (ETABLE)]);
  212.     if (hashbd == ptbl->ehashbd) return true;
  213.     return false;
  214. }
  215.  
  216. inline int
  217. ProbeEETable (SHORT side, SHORT *score)
  218.  
  219. /* Get an evaluation from the static cache */
  220. {
  221.     register struct etable *ptbl;
  222. #ifdef DEBUG
  223.     if (flag.nocache) return false;
  224. #endif
  225.     ptbl = &((etab[side])[hashkey % (ETABLE)]);
  226.     if (hashbd == ptbl->ehashbd)
  227.       {
  228.       pscore[white] = ptbl->escore[white];
  229.       pscore[black] = ptbl->escore[black];
  230.       memcpy (svalue, ptbl->sscore, sizeof (svalue));
  231.       *score = ptbl->score;
  232.           hung[white] = ptbl->hung[white];
  233.           hung[black] = ptbl->hung[black];
  234. #if defined HASHSTATS
  235.       EGET++;
  236. #endif
  237.       return true;
  238.       }
  239.     return false;
  240.  
  241. }
  242. #else /* Define null stubs for the above procedures */
  243. #define PutInEETable(side, score)
  244. #define ProbeEETable(side, score) (false)
  245. #define CheckEETable(side) (false)
  246. #endif /* CACHE */
  247.  
  248. /* ............    POSITIONAL EVALUATION ROUTINES    ............ */
  249.  
  250. /*
  251.  * Inputs are:
  252.  * pmtl[side] - value of pawns
  253.  * mtl[side]  - value of all material
  254.  * emtl[side] - vaule of all material - value of pawns - value of king
  255.  * hung[side] - count of hung pieces
  256.  * Tscore[ply] - search tree score for ply
  257.  * ply
  258.  * Pscore[ply] - positional score for ply ply
  259.  * INCscore    - bonus score or penalty for certain positions
  260.  * slk - single lone king flag
  261.  * Sdepth - search goal depth
  262.  * ChkFlag[ply]- checking piece at level ply or 0 if no check
  263.  * PC1[column] - # of my pawns in this column
  264.  * PC2[column] - # of opponents pawns in column
  265.  * PieceCnt[side] - just what it says
  266.  */
  267.  
  268. inline
  269. int
  270. ScoreKPK (SHORT side,
  271.       SHORT winner,
  272.       SHORT loser,
  273.       SHORT king1,
  274.       register SHORT king2,
  275.       register SHORT sq)
  276.  
  277. /*
  278.  * Score King and Pawns versus King endings.
  279.  */
  280.  
  281. {
  282.     register SHORT s, r;
  283.  
  284.     s = ((PieceCnt[winner] == 1) ? 50 : 120);
  285.     if (winner == white)
  286.       {
  287.       r = row (sq) - ((side == loser) ? 1 : 0);
  288.       if (row (king2) >= r && distance (sq, king2) < 8 - r)
  289.           s += 10 * row (sq);
  290.       else
  291.           s = 500 + 50 * row (sq);
  292.       if (row (sq) < 6)
  293.           sq += 16;
  294.       else if (row (sq) == 6)
  295.           sq += 8;
  296.       }
  297.     else
  298.       {
  299.       r = row (sq) + ((side == loser) ? 1 : 0);
  300.       if (row (king2) <= r && distance (sq, king2) < r + 1)
  301.           s += 10 * (7 - row (sq));
  302.       else
  303.           s = 500 + 50 * (7 - row (sq));
  304.       if (row (sq) > 1)
  305.           sq -= 16;
  306.       else if (row (sq) == 1)
  307.           sq -= 8;
  308.       }
  309.     s += 8 * (taxicab (king2, sq) - taxicab (king1, sq));
  310.     return (s);
  311. }
  312.  
  313. inline
  314. SHORT
  315. ScoreLoneKing (SHORT side)
  316. /*
  317.  * Static evaluation when loser has only a king and winner has no pawns or no
  318.  * pieces.
  319.  */
  320.  
  321. {
  322.   register SHORT winner, loser, king1, king2, s, i;
  323.  
  324.   if (mtl[white] == valueK && mtl[black] == valueK)
  325.     return 0;
  326.   UpdateWeights ();
  327.   winner = ((mtl[white] > mtl[black]) ? white : black);
  328.   loser = winner ^ 1;
  329.   king1 = PieceList[winner][0];
  330.   king2 = PieceList[loser][0];
  331.  
  332.   s = 0;
  333.  
  334.   if (pmtl[winner] == 0)
  335.     {
  336.       if (emtl[winner] == valueB + valueN)
  337.     s = ScoreKBNK (winner, king1, king2);
  338.       else if (emtl[winner] == valueN + valueN)
  339.     s = 0;
  340.       else if (emtl[winner] < valueR)
  341.         s = 0;
  342.       else
  343.     s = 500 + emtl[winner] - DyingKing[king2] - 10 * distance (king1, king2);
  344.     }
  345.   else
  346.     {
  347.       if (pmtl[winner] == valueP)
  348.     s = ScoreK1PK (side, winner, loser, king1, king2, PieceList[winner][1]);
  349.       else
  350.     for (i = 1; i <= PieceCnt[winner]; i++)
  351.       s += ScoreKPK (side, winner, loser, king1, king2, PieceList[winner][i]);
  352.     }
  353.   return ((side == winner) ? s : -s);
  354. }
  355.  
  356. inline
  357. int
  358. ScoreKBNK (SHORT winner, SHORT king1, SHORT king2)
  359. /*
  360.  * Score King+Bishop+Knight versus King endings.  Works fine now.
  361.  */
  362.  
  363. {
  364.     register SHORT s, Bsq, Nsq, KBNKsq = 0;
  365.  
  366.     if (board[PieceList[winner][1]] == bishop)
  367.       {
  368.         Bsq = PieceList[winner][1];
  369.         Nsq = PieceList[winner][2];
  370.       }
  371.     else
  372.       {
  373.         Bsq = PieceList[winner][2];
  374.         Nsq = PieceList[winner][1];
  375.       }
  376.  
  377.     KBNKsq = (((row (Bsq) % 2) == (column (Bsq) % 2)) ? 0 : 7);
  378.  
  379.     s = emtl[winner] - 300;
  380.     s += ((KBNKsq == 0) ? KBNK[king2] : KBNK[locn (row (king2), 7 - column (king2))]);
  381.     s -= (8*taxicab(king1,king2) + 2*distance(Nsq,king2) + distance(Bsq,king2));
  382.     s += KingEnding[king1];
  383.     return (s);
  384.  
  385. }
  386.  
  387. SHORT dist_ (SHORT f1, SHORT r1, SHORT f2, SHORT r2)
  388. {
  389.   return distdata [ f1-9+8*r1 ][ f2-9+8*r2 ];
  390. }
  391.  
  392. inline 
  393. int  
  394. ScoreK1PK (SHORT side,
  395.            SHORT winner,
  396.            SHORT loser,
  397.            SHORT king1,
  398.            register SHORT king2,
  399.            register SHORT sq)
  400.  
  401.      /*
  402.       *  We call Don Beal's routine with the necessary parameters and determine
  403.       *  win/draw/loss.  Then we compute the real evaluation which is +-500 for
  404.       *  a win/loss and 10 for a draw, plus some points to lead the computer to
  405.       *  a decisive winning/drawing line.
  406.       */
  407.  
  408. {
  409. #ifdef WAY4PL64
  410.   SHORT s;
  411. #endif 
  412.   SHORT win, sqc, sqr, k1c, k1r, k2c, k2r;
  413.   const int drawn = 10, won = 500;
  414.  
  415. #ifdef WAY4PL64
  416. #ifdef CACHE
  417.   if (ProbeEETable(side,&s)) return s;
  418. #endif 
  419. #endif
  420.   sqc = column (sq) + 1;
  421.   sqr = row (sq) + 1;
  422.   k1c = column (king1) + 1;
  423.   k1r = row (king1) + 1;
  424.   k2c = column (king2) + 1;
  425.   k2r = row (king2) + 1;
  426.   if (winner == black)
  427.     {  
  428.       sqr = 9 - sqr;
  429.       k1r = 9 - k1r;
  430.       k2r = 9 - k2r;
  431.     }  
  432.   if (sqc > 4)
  433.     {
  434.       sqc = 9 - sqc;
  435.       k1c = 9 - k1c;
  436.       k2c = 9 - k2c;
  437.     }  
  438.        
  439.   if (side == winner)
  440.     win = kpkwv_ (sqc, sqr, k1c, k1r, k2c, k2r);
  441.   else 
  442.     win = kpkbv_ (sqc, sqr, k1c, k1r, k2c, k2r);
  443.      
  444. #ifdef WAY4PL64
  445.   if (!win)  s = drawn + 5 * distance (sq, king2) - 5*distance(king1,king2);
  446.   else       s = won + 50 * (sqr - 2) + 10*distance(sq,king2);
  447. #else
  448.   if (!win)
  449.     return drawn + 5 * distance (sq, king2);
  450.   else
  451.     return won + 50 * (sqr - 2);
  452. #endif
  453.  
  454. #ifdef WAY4PL64
  455. #ifdef CACHE
  456.   if (PUTVAR) PutInEETable (side, s);
  457. #endif
  458.  
  459.   return s;
  460. #endif
  461. }
  462.  
  463.  
  464. static SHORT 
  465. kpkwv_ (SHORT pf, SHORT pr, SHORT wf, SHORT wr, SHORT bf, SHORT br)
  466. {
  467.  
  468.   /*
  469.    *  Don Beal's routine, which was originally in Fortran.  See AICC 2
  470.    */
  471.  
  472.   static SHORT wbdd, mbpf, nbpf, blpu;
  473.   static SHORT brpu, mwpf, wlpu, wrpu, blpuu, brpuu, wlpuu, wrpuu, md,
  474.     bq, blpuuu, brpuuu, bsd, tbf, sgf, bpp, sdr, sgr, wsd, wsg, ppr, wpp;
  475.  
  476.   ppr = ((pr == 2) ? 3 : pr);
  477.   if (pf == 1)
  478.     { 
  479.       if (bf == 3)
  480.         { 
  481.       if (pr == 7 && wf == 1 && wr == 8 && br > 6) return (0);
  482.           if (pr == 6 && wf < 4 && wr == 6 && br == 8) return (1);
  483.         }
  484.       if (bf == 1 && br > pr) return (0);
  485.       if (pr == 7 && bf > 2) return (1);
  486.       if (bf <= 3 && br - ppr > 1) return (0);
  487.       if (wf == 1 && bf == 3 && wr - pr == 1 && br - pr == 1) return(0);
  488.     }
  489.   bq = dist_ (bf, br, pf, 8);
  490.   if (bq > 8 - ppr) return (1);
  491.   mbpf = bf - pf;
  492.   if (mbpf < 0) mbpf = -mbpf;
  493.   bpp = dist_ (bf, br, pf, ppr);
  494.   wpp = dist_ (wf, wr, pf, ppr);
  495.   if (bpp - wpp < -1 && br - pr != mbpf) return (0);
  496.   if (pf == 1 && pr <= 3 && wf <= 2 && wr == 8 && bf == 4 && br >= 7) return (1);
  497.   if (!(pf != 2 || pr != 6 || bf != 1 || br != 8))
  498.     { 
  499.       if (wf <= 3 && wr == 6) return (0);
  500.       if (wf == 4 && wr == 8) return (0);
  501.     }
  502.   if (pr == 7)
  503.     { 
  504.       if (wr < 8 && wpp == 2 && bq == 0) return (1);
  505.       if (wr == 6 && wf == pf && bq == 0) return (1);
  506.       if (wr >= 6 && wpp <= 2 && bq != 0) return (1);
  507.     }
  508.   blpuu = dist_ (bf, br, pf - 1, pr + 2);
  509.   wbdd = dist_ (wf, wr, bf, br - 2);
  510.   brpuu = dist_ (bf, br, pf + 1, pr + 2);
  511.   if (pr == 6)
  512.     { 
  513.       if (dist_ (bf, br, pf + 1, pr) > 1 &&
  514.           brpuu > dist_ (wf, wr, pf + 1, pr)) return (1);
  515.       if (pf != 1)
  516.         { 
  517.       if (blpuu > dist_ (wf, wr, pf - 1, pr)) return (1);
  518.             if (br == 8 && mbpf == 1 && wbdd == 1) return (1);
  519.             if (br > 6 && nbpf == 2 && dist_ (wf, wr, bf, 5) <= 1) return (1);
  520.         }
  521.       else
  522.           if (wf == 1 && wr == 8 && bf == 2 && br == 6) return (0);
  523.     }
  524.   mwpf = wf - pf;
  525.   if (mwpf < 0) mwpf = -mwpf;
  526.   if (pr >= 5 && mwpf == 2 && wr == pr && bf == wf && br - pr == 2) return (1);
  527.   brpu = dist_ (bf, br, pf + 1, pr + 1);
  528.   wrpu = dist_ (wf, wr, pf + 1, pr + 1);
  529.   blpu = dist_ (bf, br, pf - 1, pr + 1);
  530.   wlpu = dist_ (wf, wr, pf - 1, pr + 1);
  531.   if (!(pf == 1 || pr != 5))
  532.     { 
  533.       if (mwpf <= 1 && wr - pr == 1) return (1);
  534.       if (wrpu == 1 && brpu > 1) return (1);
  535.       if (wr >= 4 && bf == wf && br - pr >= 2 && mbpf == 3) return (1);
  536.       if (wlpu == 1 && blpu > 1) return (1);
  537.     }
  538.   if (pr == 2 && br == 3 && mbpf > 1 && dist_ (wf, wr, bf, br + 2) <= 1) return (1);
  539.   if (wr - pr == 2 && br == pr && mbpf == 1 && mwpf > 1 &&
  540.       (wf - pf) * (bf - pf) > 0) return (0);
  541.   if (pf == 1 && wf == 1 && wr == br && bf > 3) return (1);
  542.   sgf = pf - 1;
  543.   if (wf >= pf) { sgf = pf + 1; }
  544.   sgr = wr - (mwpf - 1);
  545.   if (mwpf == 0 && wr > br) sgr = wr - 1;
  546.   wsg = dist_ (wf, wr, sgf, sgr);
  547.   if (wr - pr - mwpf > 0 && wr - br >= -1 && bpp - (wsg + (sgr - ppr))
  548.       >= -1 && dist_ (bf, br, sgf, sgr) > wsg) return (1);
  549.   md = mbpf - mwpf;
  550.   if (!(pf != 1 || bf <= 3))
  551.     { 
  552.       sdr = br + (bf - 3);
  553.       if (sdr > 8) sdr = 8;
  554.       if (wr > br + 1) sdr = br;
  555.       if (sdr > ppr)
  556.         { 
  557.       wsd = dist_ (wf, wr, 3, sdr);
  558.           bsd = dist_ (bf, br, 3, sdr);
  559.           if (bsd - wsd < -1) return (0);
  560.           if (bsd <= wsd && md <= 0) return (0);
  561.         }
  562.     }
  563.   brpuuu = dist_ (bf, br, pf + 1, pr + 3);
  564.   if (brpu > wrpu && brpuuu > wrpu && pr - wr != pf - wf) return (1);
  565.   if (brpuuu == 0 && wrpu == 1) return (1);
  566.   blpuuu = dist_ (bf, br, pf - 1, pr + 3);
  567.   if (pf != 1)
  568.     { 
  569.       if (blpu > wlpu && blpuuu > wlpu && pr - wr != wf - pf) return (1);
  570.       if (blpuuu == 0 && wlpu == 1) return (1);
  571.     }
  572.   wrpuu = dist_ (wf, wr, pf + 1, pr + 2);
  573.   if (brpuu > wrpuu) return(1);
  574.   wlpuu = dist_ (wf, wr, pf - 1, pr + 2);
  575.   if (pf > 1 && blpuu > wlpuu) return (1);
  576.   if (br == pr)
  577.     { 
  578.       if (mwpf <= 2 && wr - pr == -1 && mbpf != 2) return (1);
  579.       if (dist_ (wf, wr, bf - 1, br + 2) <= 1 && bf - pf > 1) return (1);
  580.       if (dist_ (wf, wr, bf + 1, br + 2) <= 1 && bf - pf < -1) return (1);
  581.     }
  582.   if (pf != 1)
  583.     { 
  584.       if (br == pr && mbpf > 1 && dist_ (wf, wr, pf, pr - 1) <= 1) return (1);
  585.       if (br - pr >= 3 && wbdd == 1) return (1);
  586.       if (wr - pr >= 2 && wr < br && md >= 0) return (1);
  587.       if (mwpf <= 2 && wr - pr >= 3 && bf != pf && wr - br <= 1) return (1);
  588.       if (wr >= pr && br - pr >= 5 && mbpf >= 3 && md >= -1 && ppr == 3) return (1);
  589.       if (md >= -1 && pr == 2 && br == 8) return (1);
  590.     }
  591.   tbf = bf - 1;
  592.   if (pf > bf) tbf = bf + 1;
  593.   if (mbpf > 1 && br == ppr && dist_ (wf, wr, tbf, wr + 2) <= 1) return (1);
  594.   if (br == pr && bf - pf == -2 && dist_ (wf, wr, pf + 2, pr - 1) <= 1) return (1);
  595.   if (pf > 2 && br == pr && bf - pf == 2 &&
  596.       dist_ (wf, wr, pf - 2, pr - 1) <= 1) return(1);
  597.   return (0);
  598. }                /* kpkwv_ */
  599.  
  600. static SHORT 
  601. kpkbv_ (SHORT pf, SHORT pr, SHORT wf, SHORT wr, SHORT bf, SHORT br)
  602. {
  603.   static SHORT incf[8] =
  604.     {0, 1, 1, 1, 0, -1, -1, -1};
  605.   static SHORT incr[8] =
  606.     {1, 1, 0, -1, -1, -1, 0, 1};
  607.  
  608.   static SHORT i, nm, nbf, nbr;
  609.  
  610.   nm = 0;
  611.   for (i = 0; i < 8; ++i)
  612.     {
  613.       nbf = bf + incf[i];
  614.       if (nbf < 1 || nbf > 8) continue;
  615.       nbr = br + incr[i];
  616.       if (nbr < 1 || nbr > 8) continue;
  617.       if (dist_ (nbf, nbr, wf, wr) < 2) continue;
  618.       if (nbf == pf && nbr == pr) return (0);
  619.       if (nbr == pr + 1 && (nbf == pf - 1 || nbf == pf + 1)) continue;
  620.       ++nm;
  621.       if (kpkwv_ (pf, pr, wf, wr, nbf, nbr) == 0) return(0);
  622.     }
  623.   if (nm > 0) return(-1);
  624.   return(0);
  625. }                /* kpkbv_ */
  626.  
  627. int
  628. evaluate (register SHORT side,
  629.       register SHORT ply,
  630.       register SHORT depth,
  631.           register SHORT ext,
  632.       register SHORT alpha,
  633.       register SHORT beta,
  634.       SHORT *terminal,
  635.       SHORT *InChk)    /* output Check flag */
  636.  
  637. /*
  638.  * Compute an estimate of the score by adding the positional score from the
  639.  * previous ply to the material difference. If this score falls inside a
  640.  * window which is 180 points wider than the alpha-beta window (or within a
  641.  * 50 point window during quiescence search) call ScorePosition() to
  642.  * determine a score, otherwise return the estimated score. If one side has
  643.  * only a king and the other either has no pawns or no pieces then the
  644.  * function ScoreLoneKing() is called.
  645.  */
  646.  
  647. {
  648.     register SHORT xside, slk;
  649.     SHORT s;
  650.  
  651.     xside = side ^ 1;
  652.     s = -Pscore[ply - 1] + mtl[side] - mtl[xside] - INCscore;
  653.     *terminal = false;
  654.     hung[white] = hung[black] = 0;
  655.     slk = ((mtl[white] == valueK && (pmtl[black] == 0 || emtl[black] == 0)) ||
  656.       (mtl[black] == valueK && (pmtl[white] == 0 || emtl[white] == 0)));
  657.  
  658.     /* should we use the estimate or score the position */
  659.     if ( !slk && (ply == 1 || 
  660. #ifdef PRUNE
  661.           depth == 1 || depth == 2 ||
  662. #endif
  663. #ifdef CACHE
  664.         (CheckEETable (side)) ||
  665. #endif
  666.         (flag.neweval ? ((
  667.         (ply==Sdepth || (!ext && depth == 0 && s>=alpha-30 && s<=beta+30)) ||
  668.         (ext && s >= alpha - 25 && s <= beta + 25)) )
  669.         :
  670.         ((Sdepth ==  ply) ||
  671.         (ply > Sdepth && (s >= (alpha - 30) && s <= (beta + 30)) )) )
  672.         ))
  673.       {
  674.     /* score the position */
  675.     ataks (side, atak[side]);
  676.     ataks (xside, atak[xside]);
  677.     if (Anyatak (side, PieceList[xside][0]))
  678.         return (10001 - ply);
  679.     ChkFlag[ply - 1] = *InChk = 
  680.         (Anyatak (xside, PieceList[side][0])) ? Pindex[TOsquare]+1 : 0;
  681. #ifndef BAREBONES 
  682.     EvalNodes++;
  683. #endif
  684.     if (ply>4) PUTVAR = true;
  685.     s = ScorePosition (side);
  686.     PUTVAR = false;
  687.       }
  688.     else
  689.       {
  690.     /* use the estimate but look at check and slk */
  691.         if (SqAtakd (PieceList[xside][0], side)) return (10001 - ply);
  692.     *InChk = SqAtakd (PieceList[side][0], xside);
  693.         ChkFlag[ply - 1] = (*InChk ? Pindex[TOsquare] + 1 : 0);
  694. #ifdef DEBUG 
  695.         if (debuglevel & 4096)
  696.             printf("%lx %lx %d %d\n",hashbd,hashkey,ply,s);
  697. #endif
  698.     if (slk)
  699.       {
  700.         if (ply>4) PUTVAR=true;
  701.         s = ScoreLoneKing (side);
  702.         PUTVAR=false;
  703.         *terminal = (s == 0 ? true : false);
  704.       }
  705.       }
  706.  
  707.     Pscore[ply] = s - mtl[side] + mtl[xside];
  708.     QueenCheck[ply - 1] =       /* tom@izf.tno.nl */
  709.           ((*InChk) && board[TOsquare] == queen) ? TOsquare : 0;
  710. #ifdef DEBUG 
  711.     if (debuglevel & 4096)
  712.     printf("%lx %lx %d %d\n",hashbd,hashkey,ply,s);
  713. #endif
  714.     return (s);
  715. }
  716.  
  717. inline
  718. int
  719. BRscan (register SHORT sq, SHORT *mob)
  720.  
  721. /*
  722.  * Find Bishop and Rook mobility, XRAY attacks, and pins. Increment the
  723.  * hung[] array if a pin is found.
  724.  */
  725. {
  726.     register UCHAR *ppos, *pdir;
  727.     register SHORT s, mobx;
  728.     register SHORT u, pin;
  729.     SHORT piece, *Kf;
  730.     mobx = s = 0;
  731.     Kf = Kfield[c1];
  732.     piece = board[sq];
  733.     ppos = nextpos[piece][sq];
  734.     pdir = nextdir[piece][sq];
  735.     u = ppos[sq];
  736.     pin = -1;            /* start new direction */
  737.     do
  738.       {
  739.       s += Kf[u];
  740.       if (color[u] == neutral)
  741.         {
  742.         mobx++;
  743.         if (ppos[u] == pdir[u])
  744.             pin = -1;    /* oops new direction */
  745.         u = ppos[u];
  746.         }
  747.       else if (pin < 0)
  748.         {
  749.         if (board[u] == pawn || board[u] == king)
  750.             u = pdir[u];
  751.         else
  752.           {
  753.               if (ppos[u] != pdir[u])
  754.               pin = u;    /* not on the edge and on to find a pin */
  755.               u = ppos[u];
  756.           }
  757.         }
  758.       else
  759.         {
  760.         if (color[u] == c2 && (board[u] > piece || atk2[u] == 0))
  761.           {
  762.               if (color[pin] == c2)
  763.             {
  764.                 s += PINVAL;
  765.                 if (atk2[pin] == 0 || atk1[pin] > control[board[pin]] + 1)
  766.                 ++hung[c2];
  767.             }
  768.               else
  769.               s += XRAY;
  770.           }
  771.         pin = -1;    /* new direction */
  772.         u = pdir[u];
  773.         }
  774.       }
  775.     while (u != sq);
  776.     *mob = mobx;
  777.     return s;
  778. }
  779.  
  780. inline
  781. SHORT
  782. KingScan (register SHORT sq)
  783.  
  784. /*
  785.  * Assign penalties if king can be threatened by checks, if squares near the
  786.  * king are controlled by the enemy (especially the queen), or if there are
  787.  * no pawns near the king. 
  788.     The following must be true: 
  789.         board[sq] == king 
  790.         c1 == color[sq] 
  791.         c2 == otherside[c1]
  792.  */
  793.  
  794. #define ScoreThreat \
  795.     if (color[u] != c2)\
  796.       if (atk1[u] == 0 || (atk2[u] & 0xFF) > 1) ++cnt;\
  797.       else s -= 3
  798.  
  799. {
  800.     register SHORT cnt;
  801.     register UCHAR *ppos, *pdir;
  802.     register SHORT s;
  803.     register SHORT u;
  804.     SHORT ok;
  805.  
  806.     s = 0;
  807.     cnt = 0;
  808.     if (HasBishop[c2] || HasQueen[c2])
  809.       {
  810.       ppos = nextpos[bishop][sq];
  811.       pdir = nextdir[bishop][sq];
  812.       u = ppos[sq];
  813.       do
  814.         {
  815.         if (atk2[u] & ctlBQ)
  816.             ScoreThreat;
  817.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  818.         }
  819.       while (u != sq);
  820.       }
  821.     if (HasRook[c2] || HasQueen[c2])
  822.       {
  823.       ppos = nextpos[rook][sq];
  824.       pdir = nextdir[rook][sq];
  825.       u = ppos[sq];
  826.       do
  827.         {
  828.         if (atk2[u] & ctlRQ)
  829.             ScoreThreat;
  830.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  831.         }
  832.       while (u != sq);
  833.       }
  834.     if (HasKnight[c2])
  835.       {
  836.       pdir = nextdir[knight][sq];
  837.       u = pdir[sq];
  838.       do
  839.         {
  840.         if (atk2[u] & ctlNN)
  841.             ScoreThreat;
  842.         u = pdir[u];
  843.         }
  844.       while (u != sq);
  845.       }
  846.     s += (KSFTY * KTHRT[cnt]) / 16;
  847.  
  848.     cnt = 0;
  849.     ok = false;
  850.     pdir = nextpos[king][sq];
  851.     u = pdir[sq];
  852.     do
  853.       {
  854.       if (board[u] == pawn)
  855.           ok = true;
  856.       if (atk2[u] > atk1[u])
  857.         {
  858.         ++cnt;
  859.         if (atk2[u] & ctlQ)
  860.             if (atk2[u] > ctlQ + 1 && atk1[u] < ctlQ)
  861.             s -= 4 * KSFTY;
  862.         }
  863.       u = pdir[u];
  864.       }
  865.     while (u != sq);
  866.     if (!ok)
  867.     s -= KSFTY;
  868.     if (cnt > 1)
  869.     s -= (KSFTY);
  870.     return (s);
  871. }
  872.  
  873.  
  874. inline
  875. int
  876. trapped (register SHORT sq)
  877.  
  878. /*
  879.  * See if the attacked piece has unattacked squares to move to. The following
  880.  * must be true: c1 == color[sq] c2 == otherside[c1]
  881.  */
  882.  
  883. {
  884.     register SHORT u;
  885.     register UCHAR *ppos, *pdir;
  886.     register SHORT piece;
  887.  
  888.     piece = board[sq];
  889.     ppos = nextpos[ptype[c1][piece]][sq];
  890.     pdir = nextdir[ptype[c1][piece]][sq];
  891.     if (piece == pawn)
  892.       {
  893.       u = ppos[sq];        /* follow no captures thread */
  894.       if (color[u] == neutral)
  895.         {
  896.         if (atk1[u] >= atk2[u])
  897.             return (false);
  898.         if (atk2[u] < ctlP)
  899.           {
  900.               u = ppos[u];
  901.               if (color[u] == neutral && atk1[u] >= atk2[u])
  902.               return (false);
  903.           }
  904.         }
  905.       u = pdir[sq];        /* follow captures thread */
  906.       if (color[u] == c2)
  907.           return (false);
  908.       u = pdir[u];
  909.       if (color[u] == c2)
  910.           return (false);
  911.       }
  912.     else
  913.       {
  914.       u = ppos[sq];
  915.       do
  916.         {
  917.         if (color[u] != c1)
  918.             if (atk2[u] == 0 || board[u] >= piece)
  919.             return (false);
  920.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  921.         }
  922.       while (u != sq);
  923.       }
  924.     return (true);
  925. }
  926.  
  927. static inline int
  928. PawnValue (register SHORT sq, SHORT side)
  929. /*
  930.  * Calculate the positional value for a pawn on 'sq'.
  931.  */
  932.  
  933. {
  934.     register SHORT fyle, rank;
  935.     register SHORT j, s, a1, a2, in_square, r, e;
  936.  
  937.     a1 = (atk1[sq] & 0x4FFF);
  938.     a2 = (atk2[sq] & 0x4FFF);
  939.     rank = row (sq);
  940.     fyle = column (sq);
  941.     s = 0;
  942.  
  943.      /* Central pawns, double pawns and isolanis */
  944.     if (CentralPawn[sq])
  945.         s += PCENTER * 2;
  946.     if ((fyle == 0 || PC1[fyle - 1] == 0) && (fyle == 7 || PC1[fyle + 1] == 0))
  947.       {
  948.      s += ISOLANI[fyle];
  949.     if (PC2[fyle] == 0)
  950.          s += PWEAKH;
  951.       }
  952.     if (PC1[fyle] > 1)
  953.         s += PDOUBLED;
  954.  
  955.     if (c1 == white)
  956.       {
  957.       s += Mwpawn[sq];
  958.       if ((sq == 11 || sq == 12) && color[sq + 8] != neutral) 
  959.           s += PEDRNK2B;
  960.       if (a1 < ctlP && atk1[sq + 8] < ctlP && atk2[sq + 8] & ctlP)
  961.         {
  962.         s += BACKWARD[a2 & 0xFF] * 2;
  963.         if (PC2[fyle] == 0) s += PWEAKH;
  964.         if (color[sq + 8] != neutral) s += PBLOK;
  965.         }
  966.       if (c1 == computer && rank != 7 && color[sq+8] == black && board[sq+8] == pawn) s -= PCRASH;
  967.       if (PC2[fyle] == 0)
  968.         {
  969.         r = rank - ((side == black)?1:0);
  970.         in_square = (row (bking) >= r && distance (sq, bking) < 8 - r);
  971.         e = (a2 == 0 || side == white)? 0:1;
  972.         for (j = sq + 8; j < 64; j += 8)
  973.             if (atk2[j] >= ctlP) { e = 2; break; }
  974.             else if (atk2[j] > 0 || color[j] != neutral) e = 1;
  975.  
  976.         if (e == 2) s += (stage * PassedPawn3[rank]) / 10;
  977.         else if (in_square /*|| e == 1*/) s += (stage * PassedPawn2[rank]) / 10;
  978.         else if (emtl[black] > 0) s += (stage * PassedPawn1[rank]) / 10;
  979.         else s += PassedPawn0[rank];
  980.         }
  981.       }
  982.     else if (c1 == black)
  983.       {
  984.       s += Mbpawn[sq];
  985.       if ((sq == 51 || sq == 52) && color[sq - 8] != neutral)
  986.           s += PEDRNK2B;
  987.  
  988.       if (a1 < ctlP && atk1[sq - 8] < ctlP && atk2[sq - 8] & ctlP)
  989.         {
  990.         s += BACKWARD[a2 & 0xFF] * 2;
  991.         if (PC2[fyle] == 0) s += PWEAKH;
  992.         if (color[sq - 8] != neutral) s += PBLOK;
  993.         }
  994.       if (c1 == computer && rank != 0 && color[sq-8] == white && board[sq-8] == pawn) s -= PCRASH;
  995.       if (PC2[fyle] == 0)
  996.         {
  997.         r = rank + ((side == white)?1:0);
  998.         in_square = (row (wking) <= r && distance (sq, wking) < r + 1);
  999.         e = (a2 == 0 || side == black)?0:1;
  1000.         for (j = sq - 8; j >= 0; j -= 8)
  1001.             if (atk2[j] >= ctlP) { e = 2; break; }
  1002.             else if (atk2[j] > 0 || color[j] != neutral) e = 1;
  1003.  
  1004.         if (e == 2) s += (stage * PassedPawn3[7 - rank]) / 10;
  1005.         else if (in_square /*|| e == 1*/) s += (stage * PassedPawn2[7 - rank]) / 10;
  1006.         else if (emtl[white] > 0) s += (stage * PassedPawn1[7 - rank]) / 10;
  1007.         else s += PassedPawn0[7 - rank];
  1008.         }
  1009.       }
  1010.     if ((rank > 2 && rank < 5) && (fyle > 2 && fyle < 5)) s += PCENTER;
  1011. #ifdef notdef
  1012.     if (a2 > 0)
  1013.       {
  1014.       if (a1 == 0 || a2 > ctlP + 1)
  1015.         {
  1016.         s += HUNGP;
  1017.         if (trapped (sq)) hung[c1] += 2;
  1018.         hung[c1]++;
  1019.         }
  1020.       else if (a2 > a1) s += ATAKD;
  1021.       }
  1022. #endif
  1023.     return (s);
  1024. }
  1025.  
  1026. inline
  1027. int
  1028. KnightValue (register SHORT sq, register SHORT side)
  1029.  
  1030. /*
  1031.  * Calculate the positional value for a knight on 'sq'.
  1032.  */
  1033.  
  1034. {
  1035.     register SHORT s, a2, a1;
  1036.  
  1037.     s = Mknight[c1][sq];
  1038.     a2 = (atk2[sq] & 0x4FFF);
  1039.     if (a2 > 0)
  1040.       {
  1041.       a1 = (atk1[sq] & 0x4FFF);
  1042.       if (a1 == 0 || a2 > ctlBN + 1)
  1043.         {
  1044.         s += HUNGP;
  1045.         if (trapped (sq))
  1046.             hung[c1] += 2;
  1047.         hung[c1]++;
  1048.         }
  1049.       else if (a2 >= ctlBN || a1 < ctlP)
  1050.           s += ATAKD;
  1051.       }
  1052.     return (s);
  1053. }
  1054.  
  1055. inline
  1056. int
  1057. BishopValue (register SHORT sq, register SHORT side)
  1058.  
  1059. /*
  1060.  * Calculate the positional value for a bishop on 'sq'.
  1061.  */
  1062.  
  1063. {
  1064.     register SHORT s;
  1065.     register SHORT a2, a1;
  1066.     SHORT mob;
  1067.  
  1068.     s = Mbishop[c1][sq];
  1069.     s += BRscan (sq, &mob);
  1070.     s += BMBLTY[mob] * 2; 
  1071.     a2 = (atk2[sq] & 0x4FFF);
  1072.     if (a2 > 0)
  1073.       {
  1074.       a1 = (atk1[sq] & 0x4FFF);
  1075.       if (a1 == 0 || a2 > ctlBN + 1)
  1076.         {
  1077.         s += HUNGP;
  1078.         if (trapped (sq))
  1079.             hung[c1] += 2;
  1080.         hung[c1]++;
  1081.         }
  1082.       else if (a2 >= ctlBN || a1 < ctlP)
  1083.           s += ATAKD;
  1084.       }
  1085.     return (s);
  1086. }
  1087.  
  1088. inline
  1089. int
  1090. RookValue (register SHORT sq, register SHORT side)
  1091.  
  1092. /*
  1093.  * Calculate the positional value for a rook on 'sq'.
  1094.  */
  1095.  
  1096. {
  1097.     register SHORT s;
  1098.     register SHORT fyle, a2, a1;
  1099.     SHORT mob;
  1100.  
  1101.     s = RookBonus;
  1102.     s += BRscan (sq, &mob);
  1103.     s += RMBLTY[mob]; 
  1104.     fyle = column (sq);
  1105.     if (PC1[fyle] == 0)
  1106.     { s += RHOPN;
  1107.             if (PC2[fyle] == 0)
  1108.             s += RHOPNX;
  1109.         }
  1110.     if (pmtl[c2] > 100 && row (sq) == rank7[c1])
  1111.     s += 25;
  1112.     s += 14 - taxicab (sq, EnemyKing);
  1113.     a2 = (atk2[sq] & 0x4FFF);
  1114.     if (a2 > 0)
  1115.       {
  1116.       a1 = (atk1[sq] & 0x4FFF);
  1117.       if (a1 == 0 || a2 > ctlR + 1)
  1118.         {
  1119.         s += HUNGP;
  1120.         if (trapped (sq))
  1121.             hung[c1] += 2;
  1122.         hung[c1]++;
  1123.         }
  1124.       else if (a2 >= ctlR || a1 < ctlP)
  1125.           s += ATAKD;
  1126.       }
  1127.     return (s);
  1128. }
  1129.  
  1130. inline
  1131. int
  1132. QueenValue (register SHORT sq, register SHORT side)
  1133.  
  1134. /*
  1135.  * Calculate the positional value for a queen on 'sq'.
  1136.  */
  1137.  
  1138. {
  1139.     register SHORT s, a2, a1;
  1140.  
  1141.     s = ((distance (sq, EnemyKing) < 3) ? 12 : 0);
  1142.     if (stage > 2)
  1143.     s += 14 - taxicab (sq, EnemyKing);
  1144.     a2 = (atk2[sq] & 0x4FFF);
  1145.     if (a2 > 0)
  1146.       {
  1147.       a1 = (atk1[sq] & 0x4FFF);
  1148.       if (a1 == 0 || a2 > ctlQ + 1)
  1149.         {
  1150.         s += HUNGP;
  1151.         if (trapped (sq))
  1152.             hung[c1] += 2;
  1153.         hung[c1]++;
  1154.         }
  1155.       else if (a2 >= ctlQ || a1 < ctlP)
  1156.           s += ATAKD;
  1157.       }
  1158.     return (s);
  1159. }
  1160.  
  1161. inline
  1162. int
  1163. KingValue (register SHORT sq, register SHORT side)
  1164.  
  1165. /*
  1166.  * Calculate the positional value for a king on 'sq'.
  1167.  */
  1168.  
  1169. {
  1170.     register SHORT s;
  1171.     register SHORT fyle;
  1172.     SHORT a2, a1;
  1173.     s = (emtl[c2] > KINGPOSLIMIT) ? Mking[c1][sq] : Mking[c1][sq] / 2;
  1174.     if (KSFTY > 0)
  1175. /*    if (Developed[c2] || stage > 0) */
  1176.         s += KingScan (sq);
  1177.     if (castld[c1])
  1178.     s += KCASTLD;
  1179.     else if (Mvboard[kingP[c1]])
  1180.     s += KMOVD;
  1181.  
  1182.     fyle = column (sq);
  1183.     if (PC1[fyle] == 0)
  1184.     s += KHOPN;
  1185.     if (PC2[fyle] == 0)
  1186.     s += KHOPNX;
  1187.     switch (fyle)
  1188.       {
  1189.       case 5:
  1190.       if (PC1[7] == 0)
  1191.           s += KHOPN;
  1192.       if (PC2[7] == 0)
  1193.           s += KHOPNX;
  1194.       /* Fall through */
  1195.       case 6:
  1196.       case 4:
  1197.       case 0:
  1198.  
  1199.       if (PC1[fyle + 1] == 0)
  1200.           s += KHOPN;
  1201.       if (PC2[fyle + 1] == 0)
  1202.           s += KHOPNX;
  1203.       break;
  1204.       case 2:
  1205.       if (PC1[0] == 0)
  1206.           s += KHOPN;
  1207.       if (PC2[0] == 0)
  1208.           s += KHOPNX;
  1209.       /* Fall through */
  1210.       case 1:
  1211.       case 3:
  1212.       case 7:
  1213.       if (PC1[fyle - 1] == 0)
  1214.           s += KHOPN;
  1215.       if (PC2[fyle - 1] == 0)
  1216.           s += KHOPNX;
  1217.       break;
  1218.       default:
  1219.       /* Impossible! */
  1220.       break;
  1221.       }
  1222.     /*  Some extra code for Ng5 problem */
  1223.     if (computer==c1 && fyle >= 6 && HasQueen[c2] && PC1[7]==0)
  1224.       s += AHOPEN;
  1225.     if (computer==c1 && fyle <= 1 && HasQueen[c2] && PC1[0]==0)
  1226.       s += AHOPEN;
  1227.  
  1228.     a2 = (atk2[sq] & 0x4FFF);
  1229.     if (a2 > 0)
  1230.       {
  1231.       a1 = (atk1[sq] & 0x4FFF);
  1232.       if (a1 == 0 || a2 > ctlK + 1)
  1233.         {
  1234.         s += HUNGP;
  1235.         ++hung[c1];
  1236.         }
  1237.       else
  1238.           s += ATAKD;
  1239.       }
  1240.     return (s);
  1241. }
  1242.  
  1243.  
  1244. static int (*PieceValue[7]) (SHORT, SHORT) =
  1245. {NULL, PawnValue, KnightValue, BishopValue, RookValue, QueenValue, KingValue};
  1246.  
  1247. SHORT
  1248. ScorePosition (register SHORT side)
  1249.  
  1250. /*
  1251.  * Perform normal static evaluation of board position. A score is generated
  1252.  * for each piece and these are summed to get a score for each side.
  1253.  */
  1254.  
  1255. {
  1256.     register SHORT score;
  1257.     register SHORT sq, i, xside;
  1258.     SHORT s;
  1259.  
  1260.     xside = side ^ 1;
  1261.     hung[white] = hung[black] = pscore[white] = pscore[black] = 0;
  1262. /* initialize Hasxxx */
  1263.     HasKnight[white] = HasKnight[black] = 0;
  1264.     HasBishop[white] = HasBishop[black] = 0;
  1265.     HasRook[white] = HasRook[black] = 0;
  1266.     HasQueen[white] = HasQueen[black] = 0;
  1267.     for (s = white; s <= black; s++)
  1268.     for (i = PieceCnt[s]; i >= 0; i--)
  1269.         switch (board[PieceList[s][i]])
  1270.           {
  1271.           case knight:
  1272.           ++HasKnight[s];
  1273.           break;
  1274.           case bishop:
  1275.           ++HasBishop[s];
  1276.           break;
  1277.           case rook:
  1278.           ++HasRook[s];
  1279.           break;
  1280.           case queen:
  1281.           ++HasQueen[s];
  1282.           break;
  1283.           }
  1284. #ifdef CACHE
  1285.     if (!(hashkey+hashbd) || !ProbeEETable (side, &s))
  1286.       {
  1287. #endif
  1288.           UpdateWeights ();
  1289.       for (c1 = white; c1 <= black; c1++)
  1290.         {
  1291.         c2 = c1 ^ 1;
  1292.         /* atk1 is array of atacks on squares by my side */
  1293.         atk1 = atak[c1];
  1294.         /* atk2 is array of atacks on squares by other side */
  1295.         atk2 = atak[c2];
  1296.         /* same for PC1 and PC2 */
  1297.         PC1 = PawnCnt[c1];
  1298.         PC2 = PawnCnt[c2];
  1299.         for (i = PieceCnt[c1]; i >= 0; i--)
  1300.           {
  1301.               sq = PieceList[c1][i];
  1302.               s = (*PieceValue[board[sq]]) (sq, side);    
  1303. /*              switch (board[sq])
  1304.             {
  1305.             case pawn:
  1306.                 s = PawnValue (sq, side);
  1307.                 break;
  1308.             case knight:
  1309.                 s = KnightValue (sq);
  1310.                 break;
  1311.             case bishop:
  1312.                 s = BishopValue (sq);
  1313.                 break;
  1314.             case rook:
  1315.                 s = RookValue (sq);
  1316.                 break;
  1317.             case queen:
  1318.                 s = QueenValue (sq);
  1319.                 break;
  1320.             case king:
  1321.                 s = KingValue (sq);
  1322.                 break;
  1323.             default:
  1324.                 s = 0;
  1325.                 break;
  1326.             } */
  1327.               pscore[c1] += s;
  1328.               svalue[sq] = s;
  1329.           }
  1330.         }
  1331.     if (hung[side] > 1)
  1332.     pscore[side] += HUNGX;
  1333.     if (hung[xside] > 1)
  1334.     pscore[xside] += HUNGX;
  1335.     if (hung[computer] > 1)
  1336.     pscore[computer] += 8 * HUNGX; 
  1337.  
  1338. /*  Bonus for double bishops  */
  1339.     if (HasBishop[side] == 2)
  1340.     pscore[side] += 10 + 2 * stage;
  1341.     if (HasBishop[xside] == 2)
  1342.     pscore[xside] += 10 + 2 * stage;
  1343.  
  1344.     score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10;
  1345. #ifndef NODITHER
  1346.     if (dither)
  1347.       {
  1348.       if (flag.hash)
  1349.           gsrand (starttime + (unsigned int) hashbd);
  1350.       score += urand () % dither;
  1351.       }
  1352. #endif
  1353.     if (score > 0 && pmtl[side] == 0)
  1354.     if (emtl[side] < valueR)
  1355.         score = 0;
  1356.     else if (score < valueR)
  1357.         score /= 2;
  1358.     if (score < 0 && pmtl[xside] == 0)
  1359.     if (emtl[xside] < valueR)
  1360.         score = 0;
  1361.     else if (-score < valueR)
  1362.         score /= 2;
  1363.  
  1364.     if (mtl[xside] == valueK && emtl[side] > valueB)
  1365.     score += 200;
  1366.     if (mtl[side] == valueK && emtl[xside] > valueB)
  1367.     score -= 200;
  1368. #ifdef CACHE
  1369.     if(PUTVAR)PutInEETable(side,score);
  1370. #endif
  1371.     return (score);
  1372. #ifdef CACHE
  1373. }
  1374. else {
  1375. return s;
  1376. }
  1377. #endif
  1378. }
  1379. static inline void
  1380. BlendBoard (const SHORT a[64], const SHORT b[64], SHORT c[64])
  1381. {
  1382.     register int sq, s;
  1383.     s = 10 - stage;
  1384.     for (sq = 0; sq < 64; sq++)
  1385.     c[sq] = ((a[sq] * s) + (b[sq] * stage)) / 10;
  1386. }
  1387.  
  1388.  
  1389. void
  1390. ExaminePosition (void)
  1391.  
  1392. /*
  1393.  * This is done one time before the search is started. Set up arrays Mwpawn,
  1394.  * Mbpawn, Mknight, Mbishop, Mking which are used in the SqValue() function
  1395.  * to determine the positional value of each piece.
  1396.  */
  1397.  
  1398. {
  1399.     register SHORT i, sq;
  1400.     register SHORT fyle;
  1401.     SHORT wpadv, bpadv, wstrong, bstrong, z, side, pp, j, k, val, Pd, rank;
  1402.     static SHORT PawnStorm = false;
  1403. /* update ataks arrays */
  1404.     ataks (white, atak[white]);
  1405.     ataks (black, atak[black]);
  1406. /*    */
  1407.     UpdateWeights ();
  1408. /* initialize Hasxxx */
  1409.     HasKnight[white] = HasKnight[black] = 0;
  1410.     HasBishop[white] = HasBishop[black] = 0;
  1411.     HasRook[white] = HasRook[black] = 0;
  1412.     HasQueen[white] = HasQueen[black] = 0;
  1413.     for (side = white; side <= black; side++)
  1414.     for (i = PieceCnt[side]; i >= 0; i--)
  1415.         switch (board[PieceList[side][i]])
  1416.           {
  1417.           case knight:
  1418.           ++HasKnight[side];
  1419.           break;
  1420.           case bishop:
  1421.           ++HasBishop[side];
  1422.           break;
  1423.           case rook:
  1424.           ++HasRook[side];
  1425.           break;
  1426.           case queen:
  1427.           ++HasQueen[side];
  1428.           break;
  1429.           }
  1430. /* Developed if has moved knights and bishops */
  1431.     if (!Developed[white])
  1432.     Developed[white] = (board[1] != knight && board[2] != bishop &&
  1433.                 board[5] != bishop && board[6] != knight);
  1434.     if (!Developed[black])
  1435.     Developed[black] = (board[57] != knight && board[58] != bishop &&
  1436.                 board[61] != bishop && board[62] != knight);
  1437. /* Pawn Storm */
  1438. /*    if (!PawnStorm && stage < 5)*/
  1439.     PawnStorm = (stage < 5) &&
  1440.                ((column (wking) < 3 && column (bking) > 4) ||
  1441.              (column (wking) > 4 && column (bking) < 3));
  1442. /* setup base tables */
  1443.     memcpy (Mknight[white],pknight,sizeof(pknight));
  1444.     memcpy (Mknight[black],pknight,sizeof(pknight));
  1445.     memcpy(Mbishop[white],pbishop,sizeof(pbishop));
  1446.     memcpy(Mbishop[black],pbishop,sizeof(pbishop));
  1447.  
  1448. /* linear interpolate on stage    */
  1449. /* Mking = (KingOpening * (10 - stage) + KingEnding * srage) /10  */
  1450.     BlendBoard (KingOpening, KingEnding, Mking[white]);
  1451.     BlendBoard (KingOpening, KingEnding, Mking[black]);
  1452.  
  1453.     for (sq = 0; sq < 64; sq++)
  1454.       {
  1455.       fyle = column (sq);
  1456.       rank = row (sq);
  1457.       wstrong = bstrong = true;
  1458. /* does a black pawn attack to squares in this col from sq to end */
  1459.       for (i = sq; i < 64; i += 8)
  1460.           if (Patak (black, i)) { wstrong = false; break; }
  1461. /* does a white pawn attack to squares in this col from sq to end */
  1462.       for (i = sq; i >= 0; i -= 8)
  1463.           if (Patak (white, i)) { bstrong = false; break; }
  1464. /*     */
  1465.       wpadv = bpadv = PADVNCM;
  1466.       if ((fyle == 0 || PawnCnt[white][fyle - 1] == 0) && (fyle == 7 || PawnCnt[white][fyle + 1] == 0)) wpadv = PADVNCI;
  1467.       if ((fyle == 0 || PawnCnt[black][fyle - 1] == 0) && (fyle == 7 || PawnCnt[black][fyle + 1] == 0)) bpadv = PADVNCI;
  1468.       Mwpawn[sq] = (wpadv * PawnAdvance[sq]) / 10;
  1469.       Mbpawn[sq] = (bpadv * PawnAdvance[63 - sq]) / 10;
  1470.       Mwpawn[sq] += PawnBonus;
  1471.       Mbpawn[sq] += PawnBonus;
  1472. /*     */
  1473.       if (Mvboard[kingP[white]])
  1474.         {
  1475.         if ((fyle < 3 || fyle > 4) && distance (sq, wking) < 3)
  1476.             Mwpawn[sq] += PAWNSHIELD;
  1477.         }
  1478.       else if (rank < 3 && (fyle < 2 || fyle > 5))
  1479.           Mwpawn[sq] += PAWNSHIELD / 2;
  1480. /*     */
  1481.       if (Mvboard[kingP[black]])
  1482.         {
  1483.         if ((fyle < 3 || fyle > 4) && distance (sq, bking) < 3)
  1484.             Mbpawn[sq] += PAWNSHIELD;
  1485.         }
  1486.       else if (rank > 4 && (fyle < 2 || fyle > 5))
  1487.           Mbpawn[sq] += PAWNSHIELD / 2;
  1488. /*     */
  1489.       if (PawnStorm)
  1490.         {
  1491.         if ((column (wking) < 4 && fyle > 4) || (column (wking) > 3 && fyle < 3))
  1492.             Mwpawn[sq] += 4 * rank;
  1493.         if ((column (bking) < 4 && fyle > 4) || (column (bking) > 3 && fyle < 3))
  1494.             Mbpawn[sq] -= (4 * rank - 28);
  1495.         }
  1496. /*     */
  1497.       Mknight[white][sq] += 5 - distance (sq, bking);
  1498.       Mknight[white][sq] += 5 - distance (sq, wking);
  1499.       Mknight[black][sq] += 5 - distance (sq, wking);
  1500.       Mknight[black][sq] += 5 - distance (sq, bking);
  1501. /*     */
  1502.       Mbishop[white][sq] += BishopBonus;
  1503.       Mbishop[black][sq] += BishopBonus;
  1504. /*     */
  1505.       for (i = PieceCnt[black]; i >= 0; i--)
  1506.           if (distance (sq, PieceList[black][i]) < 3)
  1507.           Mknight[white][sq] += KNIGHTPOST;
  1508.       for (i = PieceCnt[white]; i >= 0; i--)
  1509.           if (distance (sq, PieceList[white][i]) < 3)
  1510.           Mknight[black][sq] += KNIGHTPOST;
  1511. /*     */
  1512.       if (wstrong)
  1513.           Mknight[white][sq] += KNIGHTSTRONG;
  1514.       if (bstrong)
  1515.           Mknight[black][sq] += KNIGHTSTRONG;
  1516.       if (wstrong)
  1517.           Mbishop[white][sq] += BISHOPSTRONG;
  1518.       if (bstrong)
  1519.           Mbishop[black][sq] += BISHOPSTRONG;
  1520. /*     */
  1521. #ifdef notdef
  1522.       if (HasBishop[white] == 2)
  1523.           Mbishop[white][sq] += 8;
  1524.       if (HasBishop[black] == 2)
  1525.           Mbishop[black][sq] += 8;
  1526.       if (HasKnight[white] == 2)
  1527.           Mknight[white][sq] += 5;
  1528.       if (HasKnight[black] == 2)
  1529.           Mknight[black][sq] += 5;
  1530. #endif
  1531. /*     */
  1532.  
  1533.       Kfield[white][sq] = Kfield[black][sq] = 0;
  1534.       if (distance (sq, wking) == 1)
  1535.           Kfield[black][sq] = KATAK;
  1536.       if (distance (sq, bking) == 1)
  1537.           Kfield[white][sq] = KATAK;
  1538. /*     */
  1539.       Pd = 0;
  1540.       for (k = 0; k <= PieceCnt[white]; k++)
  1541.         {
  1542.         i = PieceList[white][k];
  1543.         if (board[i] == pawn)
  1544.           {
  1545.               pp = true;
  1546.               for (j = i + 8; j < 64; j += 8)
  1547.               if (Patak (black, j) || board[j] == pawn)
  1548.                 {
  1549.                 pp = false;
  1550.                 break;
  1551.                 }
  1552.               z = (pp ? i + ((row (i) == 6) ? 8 : 16) : i);
  1553.               Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  1554.           }
  1555.         }
  1556. /*     */
  1557.       for (k = 0; k <= PieceCnt[black]; k++)
  1558.         {
  1559.         i = PieceList[black][k];
  1560.         if (board[i] == pawn)
  1561.           {
  1562.               pp = true;
  1563.               for (j = i - 8; j >= 0; j -= 8)
  1564.               if (Patak (white, j) || board[j] == pawn)
  1565.                 {
  1566.                 pp = false;
  1567.                 break;
  1568.                 }
  1569.               z = (pp ? i - ((row (i) == 1) ? 8 : 16) : i);
  1570.               Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  1571.           }
  1572.         }
  1573. /*     */
  1574.       if (Pd != 0)
  1575.         {
  1576.         val = (Pd * stage2) / 4;
  1577.         Mking[white][sq] -= val;
  1578.         Mking[black][sq] -= val;
  1579.         }
  1580.       }
  1581. }
  1582.  
  1583. void
  1584. UpdateWeights (void)
  1585.  
  1586. /*
  1587.  * If material balance has changed, determine the values for the positional
  1588.  * evaluation terms.
  1589.  */
  1590.  
  1591. {
  1592.     register SHORT s1, tmtl;
  1593.  
  1594.     emtl[white] = mtl[white] - pmtl[white] - valueK;
  1595.     emtl[black] = mtl[black] - pmtl[black] - valueK;
  1596.     tmtl = emtl[white] + emtl[black];
  1597.     s1 = ((tmtl > 6600) ? 0 : ((tmtl < 1400) ? 10 : (6600 - tmtl) / 520));
  1598.     if (s1 != stage)
  1599.       {
  1600.     stage = s1;
  1601.     stage2 = ((tmtl > 3600) ? 0 : ((tmtl < 1400) ? 10 : (3600 - tmtl) / 220));
  1602.     PEDRNK2B = -15;        /* centre pawn on 2nd rank & blocked */
  1603.     PBLOK = -4;        /* blocked backward pawn */
  1604.     PDOUBLED = -14;        /* doubled pawn */
  1605.     PWEAKH = -12;        /* weak pawn on half open file */
  1606.     PAWNSHIELD = 10-stage;    /* pawn near friendly king */
  1607.     PADVNCM = 12;        /* advanced pawn multiplier */
  1608.     PADVNCI = 7;        /* muliplier for isolated pawn */
  1609.     PawnBonus = stage;
  1610.  
  1611.     KNIGHTPOST = (stage + 2) / 3;    /* knight near enemy pieces */
  1612.     KNIGHTSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  1613.  
  1614.     BISHOPSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  1615.     BishopBonus = BBONUS * stage;
  1616.  
  1617.     RHOPN = 10;        /* rook on half open file */
  1618.     RHOPNX = 4;
  1619.     RookBonus = RBONUS * stage;
  1620.  
  1621.     XRAY = 8;        /* Xray attack on piece */
  1622.     PINVAL = 16;        /* Pin */
  1623.  
  1624.     KHOPN = (2 * stage - 20);    /* king on half open file */
  1625.     KHOPNX = KHOPN / 2;
  1626.     KCASTLD = 10 - stage;
  1627.     KMOVD = -40 / (stage + 1);    /* king moved before castling */
  1628.     KATAK = (10 - stage);        /* B,R attacks near enemy king */
  1629.     KSFTY = ((stage < 8) ? (KINGSAFETY - 4 * stage) : 0);
  1630.  
  1631.     ATAKD = -8;        /* defender > attacker */
  1632.     HUNGP = -12;        /* each hung piece */
  1633.     HUNGX = -18;        /* extra for >1 hung piece */
  1634.       }
  1635. }
  1636.  
  1637.