home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 5 / ctrom5b.zip / ctrom5b / OS2 / SPEL / UCHESS / UCHESSRC / EVAL.C < prev    next >
Text File  |  1994-11-01  |  56KB  |  2,041 lines

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