home *** CD-ROM | disk | FTP | other *** search
/ Dream 44 / Amiga_Dream_44.iso / RiscPc / jeux / ArcBoard004.arc / !GNUChessX / src / c / eval < prev    next >
Text File  |  1995-07-02  |  42KB  |  1,635 lines

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