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