home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / useful / game / think / uchess.lha / UChess / src / eval.c < prev    next >
C/C++ Source or Header  |  1994-02-21  |  78KB  |  3,085 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. #endif
  33.  
  34. int ScoreKBNK (short winner, short king1, short king2);
  35. int ScoreKPK (short side,
  36.       short winner,
  37.       short loser,
  38.       short king1,
  39.       register short king2,
  40.       register short sq);
  41.  
  42.  
  43. extern short __aligned PCRASH,PCENTER;
  44. short __aligned QueenCheck[MAXDEPTH]; /* tom@izf.tno.nl */
  45. int __aligned myneweval=1;
  46. short int __aligned sscore[2];
  47. /* Backward pawn bonus indexed by # of attackers on the square */
  48. static const short __aligned BACKWARD[16] =
  49. {-6, -10, -15, -21, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28};
  50.  
  51. /* Bishop mobility bonus indexed by # reachable squares */
  52. static const short __aligned BMBLTY[14] =
  53. {-2, 0, 2, 4, 6, 8, 10, 12, 13, 14, 15, 16, 16, 16};
  54.  
  55. /* Rook mobility bonus indexed by # reachable squares */
  56. static const short __aligned RMBLTY[15] =
  57. {0, 2, 4, 6, 8, 10, 11, 12, 13, 14, 14, 14, 14, 14, 14};
  58.  
  59. /* Positional values for a dying king */
  60. static const short __aligned DyingKing[64] =
  61. {0, 8, 16, 24, 24, 16, 8, 0,
  62.  8, 32, 40, 48, 48, 40, 32, 8,
  63.  16, 40, 56, 64, 64, 56, 40, 16,
  64.  24, 48, 64, 72, 72, 64, 48, 24,
  65.  24, 48, 64, 72, 72, 64, 48, 24,
  66.  16, 40, 56, 64, 64, 56, 40, 16,
  67.  8, 32, 40, 48, 48, 40, 32, 8,
  68.  0, 8, 16, 24, 24, 16, 8, 0};
  69.  
  70. /* Isoloted pawn penalty by rank */
  71. static const short __aligned ISOLANI[8] =
  72. {-12, -16, -20, -24, -24, -20, -16, -12};
  73.  
  74. /* table for King Bishop Knight endings */
  75. static const short __aligned KBNK[64] =
  76. #ifdef PRE4PL67KBNK
  77. {99, 90, 80, 70, 60, 50, 40, 40,
  78.  90, 80, 60, 50, 40, 30, 20, 40,
  79.  80, 60, 40, 30, 20, 10, 30, 50,
  80.  70, 50, 30, 10, 0, 20, 40, 60,
  81.  60, 40, 20, 0, 10, 30, 50, 70,
  82.  50, 30, 10, 20, 30, 40, 60, 80,
  83.  40, 20, 30, 40, 50, 60, 80, 90,
  84.  40, 40, 50, 60, 70, 80, 90, 99};
  85. #else
  86. {620, 560, 500, 440, 380, 320, 260, 240,
  87.  560, 520, 460, 400, 340, 280, 230, 260,
  88.  500, 460, 320, 280, 260, 220, 280, 320,
  89.  440, 400, 280, 200, 200, 260, 340, 380,
  90.  380, 340, 260, 200, 200, 280, 400, 440,
  91.  320, 280, 220, 260, 280, 320, 460, 500,
  92.  260, 230, 280, 340, 400, 460, 520, 560,
  93.  240, 260, 320, 380, 440, 500, 560, 620};
  94. #endif
  95.  
  96. /* penalty for threats to king, indexed by number of such threats */
  97. static const short __aligned KTHRT[36] =
  98. {0, -8, -20, -36, -52, -68, -80, -80, -80, -80, -80, -80,
  99.  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
  100.  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80};
  101.  
  102. /* King positional bonus inopening stage */
  103. static const short __aligned KingOpening[64] =
  104. {0, 0, -4, -10, -10, -4, 0, 0,
  105.  -4, -4, -8, -12, -12, -8, -4, -4,
  106.  -12, -16, -20, -20, -20, -20, -16, -12,
  107.  -16, -20, -24, -24, -24, -24, -20, -16,
  108.  -16, -20, -24, -24, -24, -24, -20, -16,
  109.  -12, -16, -20, -20, -20, -20, -16, -12,
  110.  -4, -4, -8, -12, -12, -8, -4, -4,
  111.  0, 0, -4, -10, -10, -4, 0, 0};
  112.  
  113. /* King positional bonus in end stage */
  114. static const short __aligned KingEnding[64] =
  115. {0, 6, 12, 18, 18, 12, 6, 0,
  116.  6, 12, 18, 24, 24, 18, 12, 6,
  117.  12, 18, 24, 30, 30, 24, 18, 12,
  118.  18, 24, 30, 36, 36, 30, 24, 18,
  119.  18, 24, 30, 36, 36, 30, 24, 18,
  120.  12, 18, 24, 30, 30, 24, 18, 12,
  121.  6, 12, 18, 24, 24, 18, 12, 6,
  122.  0, 6, 12, 18, 18, 12, 6, 0};
  123.  
  124. /* Passed pawn positional bonus */
  125. static const short __aligned PassedPawn0[8] =
  126. {0, 60, 80, 120, 200, 360, 600, 800};
  127. static const short __aligned PassedPawn1[8] =
  128. {0, 30, 40, 60, 100, 180, 300, 800};
  129. static const short __aligned PassedPawn2[8] =
  130. {0, 15, 25, 35, 50, 90, 140, 800};
  131. static const short __aligned PassedPawn3[8] =
  132. {0, 5, 10, 15, 20, 30, 140, 800};
  133.  
  134. /* Knight positional bonus */
  135. static const short __aligned pknight[64] =
  136. {0, 4, 8, 10, 10, 8, 4, 0,
  137.  4, 8, 16, 20, 20, 16, 8, 4,
  138.  8, 16, 24, 28, 28, 24, 16, 8,
  139.  10, 20, 28, 32, 32, 28, 20, 10,
  140.  10, 20, 28, 32, 32, 28, 20, 10,
  141.  8, 16, 24, 28, 28, 24, 16, 8,
  142.  4, 8, 16, 20, 20, 16, 8, 4,
  143.  0, 4, 8, 10, 10, 8, 4, 0};
  144.  
  145. /* Bishop positional bonus */
  146. static const short __aligned pbishop[64] =
  147. {14, 14, 14, 14, 14, 14, 14, 14,
  148.  14, 22, 18, 18, 18, 18, 22, 14,
  149.  14, 18, 22, 22, 22, 22, 18, 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, 22, 18, 18, 18, 18, 22, 14,
  154.  14, 14, 14, 14, 14, 14, 14, 14};
  155.  
  156. /* Pawn positional bonus */
  157. static const short __aligned PawnAdvance[64] =
  158. {0, 0, 0, 0, 0, 0, 0, 0,
  159.  4, 4, 4, 0, 0, 4, 4, 4,
  160.  6, 8, 2, 10, 10, 2, 8, 6,
  161.  6, 8, 12, 16, 16, 12, 8, 6,
  162.  8, 12, 16, 24, 24, 16, 12, 8,
  163.  12, 16, 24, 32, 32, 24, 16, 12,
  164.  12, 16, 24, 32, 32, 24, 16, 12,
  165.  0, 0, 0, 0, 0, 0, 0, 0};
  166. #if !defined NOSCORESPACE
  167. #ifdef BLACKAG0
  168. /* Space positional bonus */
  169. static const short __aligned SpaceBonusB[64] =
  170. {0, 0, 0, 0, 0, 0, 0, 0,
  171.  0, 0, 2, 2, 2, 2, 0, 0,
  172.  1, 1, 2, 4, 4, 2, 1, 1,
  173.  0, 0, 3, 4, 4, 3, 0, 0,
  174.  0, 0, 5, 5, 5, 5, 0, 0,
  175.  0, 0, 4, 4, 7, 7, 0, 0,
  176.  0, 0, 0, 0, 0, 0, 0, 0,
  177.  0, 0, 0, 0, 0, 0, 0, 0};
  178. #elif defined BLACKAG1
  179. /* Space positional bonus */
  180. static const short __aligned SpaceBonusB[64] =
  181. {1, 1, 1, 1, 1, 1, 1, 1,
  182.  1, 1, 2, 2, 2, 2, 1, 1,
  183.  1, 1, 2, 3, 3, 2, 1, 1,
  184.  1, 1, 2, 4, 4, 2, 1, 1,
  185.  1, 1, 3, 5, 5, 3, 1, 1,
  186.  1, 1, 3, 6, 6, 3, 1, 1,
  187.  1, 1, 3, 7, 7, 3, 1, 1,
  188.  1, 1, 1, 1, 1, 1, 1, 1};
  189. #elif defined BLACKAG2
  190. /* Space positional bonus */
  191. static const short __aligned SpaceBonusB[64] =
  192. {1, 1, 1, 1, 1, 1, 1, 1,
  193.  1, 1, 2, 2, 2, 2, 1, 1,
  194.  1, 1, 3, 3, 3, 3, 1, 1,
  195.  1, 1, 4, 4, 4, 4, 1, 1,
  196.  1, 1, 5, 6, 6, 5, 1, 1,
  197.  1, 1, 6, 7, 7, 6, 1, 1,
  198.  1, 1, 7, 8, 8, 7, 1, 1,
  199.  1, 1, 1, 1, 1, 1, 1, 1};
  200. #elif defined BLACKAG3
  201. /* Space positional bonus */
  202. static const short __aligned SpaceBonusB[64] =
  203. {0, 0, 0, 0, 0, 0, 0, 0,
  204.  0, 0, 2, 2, 2, 2, 0, 0,
  205.  0, 0, 3, 3, 3, 3, 0, 0,
  206.  0, 0, 4, 4, 4, 3, 0, 0,
  207.  0, 0, 6, 6, 4, 4, 0, 0,
  208.  0, 0, 7, 7, 5, 5, 0, 0,
  209.  0, 0, 8, 8, 7, 7, 0, 0,
  210.  0, 0, 0, 0, 0, 0, 0, 0};
  211. #elif defined BLACKAG4
  212. /* Space positional bonus */
  213. static const short __aligned SpaceBonusB[64] =
  214. {1, 1, 1, 1, 1, 1, 1, 1,
  215.  1, 1, 2, 4, 4, 2, 1, 1,
  216.  1, 1, 2, 4, 4, 2, 1, 1,
  217.  1, 1, 2, 4, 4, 2, 1, 1,
  218.  1, 1, 2, 4, 4, 2, 1, 1,
  219.  1, 1, 2, 4, 4, 2, 1, 1,
  220.  1, 1, 2, 4, 4, 2, 1, 1,
  221.  1, 1, 1, 1, 1, 1, 1, 1};
  222. #endif
  223.  
  224. #ifdef WHITEAG0
  225. /* Space positional bonus */
  226. static const short __alignedSpaceBonusW[64] =
  227. {0, 0, 0, 0, 0, 0, 0, 0,
  228.  0, 0, 5, 5, 5, 5, 0, 0,
  229.  0, 0, 3, 4, 4, 3, 0, 0,
  230.  0, 0, 2, 4, 4, 2, 0, 0,
  231.  0, 0, 1, 4, 4, 1, 0, 0,
  232.  0, 0, 1, 4, 4, 1, 0, 0,
  233.  0, 0, 1, 2, 2, 1, 0, 0,
  234.  0, 0, 0, 0, 0, 0, 0, 0};
  235. #elif defined WHITEAG1
  236. /* Space positional bonus */
  237. static const short __alignedSpaceBonusW[64] =
  238. {1, 1, 1, 1, 1, 1, 1, 1,
  239.  1, 1, 3, 7, 7, 3, 1, 1,
  240.  1, 1, 3, 6, 6, 3, 1, 1,
  241.  1, 1, 3, 5, 5, 3, 1, 1,
  242.  1, 1, 2, 4, 4, 2, 1, 1,
  243.  1, 1, 2, 3, 3, 2, 1, 1,
  244.  1, 1, 2, 2, 2, 2, 1, 1,
  245.  1, 1, 1, 1, 1, 1, 1, 1};
  246. #elif defined WHITEAG2
  247. /* Space positional bonus */
  248. static const short __alignedSpaceBonusW[64] =
  249. {1, 1, 1, 1, 1, 1, 1, 1,
  250.  1, 1, 7, 8, 8, 7, 1, 1,
  251.  1, 1, 6, 7, 7, 6, 1, 1,
  252.  1, 1, 5, 6, 6, 5, 1, 1,
  253.  1, 1, 4, 4, 4, 4, 1, 1,
  254.  1, 1, 3, 3, 3, 3, 1, 1,
  255.  1, 1, 2, 2, 2, 2, 1, 1,
  256.  1, 1, 1, 1, 1, 1, 1, 1};
  257. #elif defined WHITEAG3
  258. /* Space positional bonus */
  259. static const short __alignedSpaceBonusW[64] =
  260. {0, 0, 0, 0, 0, 0, 0, 0,
  261.  0, 0, 8, 8, 7, 7, 0, 0,
  262.  0, 0, 7, 7, 5, 5, 0, 0,
  263.  0, 0, 6, 6, 4, 4, 0, 0,
  264.  0, 0, 4, 4, 4, 3, 0, 0,
  265.  0, 0, 3, 3, 3, 3, 0, 0,
  266.  0, 0, 2, 2, 2, 2, 0, 0,
  267.  0, 0, 0, 0, 0, 0, 0, 0};
  268. #elif defined WHITEAG4
  269. /* Space positional bonus */
  270. static const short __alignedSpaceBonusW[64] =
  271. {1, 1, 1, 1, 1, 1, 1, 1,
  272.  1, 1, 2, 4, 4, 2, 1, 1,
  273.  1, 1, 2, 4, 4, 2, 1, 1,
  274.  1, 1, 2, 4, 4, 2, 1, 1,
  275.  1, 1, 2, 4, 4, 2, 1, 1,
  276.  1, 1, 2, 4, 4, 2, 1, 1,
  277.  1, 1, 2, 4, 4, 2, 1, 1,
  278.  1, 1, 1, 1, 1, 1, 1, 1};
  279. #endif
  280. #endif
  281.  
  282. short __aligned Mwpawn[64];
  283. short __aligned Mbpawn[64];
  284. short __aligned Mknight[2][64];
  285. short __aligned Mbishop[2][64];
  286. static short __aligned Mking[2][64];
  287. static short __aligned Kfield[2][64];
  288. static short __aligned c1, c2, *atk1, *atk2, *PC1, *PC2;
  289. static short __aligned atak[2][64];
  290. short __aligned emtl[2];
  291. static short __aligned PawnBonus, BishopBonus, RookBonus;
  292. static short __aligned KNIGHTPOST, KNIGHTSTRONG, BISHOPSTRONG, KATAK;
  293. static short __aligned PEDRNK2B, PWEAKH, PADVNCM, PADVNCI, PAWNSHIELD, PDOUBLED, PBLOK;
  294. static short __aligned RHOPN, RHOPNX, KHOPN, KHOPNX, KSFTY;
  295. static short __aligned ATAKD, HUNGP, HUNGX, KCASTLD, KMOVD, XRAY, PINVAL;
  296. short __aligned pscore[2];
  297. short __aligned tmtl;
  298.  
  299. #ifdef CACHE
  300. inline void
  301. PutInEETable (ARGSZ int side,int score)
  302.  
  303. /*
  304.  * Store the current eval position in the transposition table.
  305.  */
  306.  
  307. {
  308.     register struct etable *ptbl;
  309.     ptbl = &etab[side][hashkey % (ETABLE)];
  310. //    if (ptbl->ehashbd == hashbd) return;
  311.     ptbl->ehashbd = hashbd;
  312.     ptbl->escore[white] = pscore[white];
  313.     ptbl->escore[black] = pscore[black];
  314.     ptbl->hung[white] = hung[white];
  315.     ptbl->hung[black] = hung[black];
  316.     ptbl->score = score;
  317. #ifndef AMIGA
  318.     bcopy (svalue, &(ptbl->sscore), sizeof (svalue));
  319. #else
  320.     MoveMem128(svalue,&(ptbl->sscore));
  321.    /* MoveMem(svalue,&(ptbl->sscore),sizeof (svalue));*/
  322. #endif
  323. /*    bcopy (&(ptbl->sscore), svalue, sizeof (svalue)); */
  324. #if !defined CHESSTOOL && !defined XBOARD
  325.     EADD++;
  326. #endif
  327.     return;
  328. }
  329.  
  330. inline int
  331. CheckEETable (ARGSZ int side)
  332.  
  333. /* Get an evaluation from the transposition table */
  334. {
  335.     register struct etable *ptbl;
  336.     ptbl = &etab[side][hashkey % (ETABLE)];
  337.     if (hashbd == ptbl->ehashbd) return true;
  338.     return false;
  339. }
  340.  
  341. inline int
  342. ProbeEETable (short int side, short int *score)
  343.  
  344. /* Get an evaluation from the transposition table */
  345. {
  346.     register struct etable *ptbl;
  347.     ptbl = &etab[side][hashkey % (ETABLE)];
  348.     if (hashbd == ptbl->ehashbd)
  349.       {
  350.       pscore[white] = ptbl->escore[white];
  351.       pscore[black] = ptbl->escore[black];
  352. #ifndef AMIGA
  353.       bcopy (&(ptbl->sscore),svalue, sizeof (svalue));
  354. #else
  355.       MoveMem128(&(ptbl->sscore),svalue);
  356.      /* MoveMem (&(ptbl->sscore),svalue, sizeof (svalue));*/
  357. #endif
  358. /*      bcopy (svalue, &(ptbl->sscore), sizeof (svalue));*/
  359.       *score = ptbl->score;
  360.           hung[white] = ptbl->hung[white];
  361.           hung[black] = ptbl->hung[black];
  362. #if !defined CHESSTOOL && !defined XBOARD
  363.       EGET++;
  364. #endif
  365.       return true;
  366.       }
  367.     return false;
  368.  
  369. }
  370.  
  371. #endif
  372.  
  373.  
  374.  
  375. short dist_ (short, short, short, short);
  376. short kpkwv_ (short, short, short, short, short, short);
  377.  
  378. #ifndef PRE4PL67
  379.  
  380. short 
  381. kpkwv_ (short pf, short pr, short wf, short wr, short bf, short br)
  382. {
  383.  
  384.   /*
  385.    *  Don Beal's routine, which was originally in Fortran.  See AICC 2
  386.    */
  387.  
  388.   static short wbdd, mbpf, nbpf, blpu;
  389.   short dist_ (short, short, short, short);
  390.   static short brpu, mwpf, wlpu, wrpu, blpuu, brpuu, wlpuu, wrpuu, md,
  391.     bq, blpuuu, brpuuu, bsd, tbf, sgf, bpp, sdr, sgr, wsd, wsg, ppr, wpp;
  392.  
  393.   ppr = ((pr == 2)?3:pr); // was ?3:0
  394.   if (pf == 1)
  395.   { if (bf == 3)
  396.     { if (pr == 7 && wf == 1 && wr == 8 && br > 6) return(0);
  397.       if (pr == 6 && wf < 4 && wr == 6 && br == 8) return(1);
  398.     }
  399.  
  400.     if (bf == 1 && br > pr) return(0);
  401.     if (pr == 7 && bf > 2) return(1);
  402.     if (bf <= 3 && br - ppr > 1) return(0);
  403.     if (wf == 1 && bf == 3 && wr - pr == 1 && br - pr == 1) return(0);
  404.   }
  405.   bq = dist_ (bf, br, pf, 8);
  406.   if (bq > 8 - ppr) return(1);
  407.   mbpf = bf - pf;
  408.   if (mbpf < 0) mbpf = -mbpf;
  409.   bpp = dist_ (bf, br, pf, ppr);
  410.   wpp = dist_ (wf, wr, pf, ppr);
  411.   if (bpp - wpp < -1 && br - pr != mbpf) return(0);
  412.   if (pf == 1 && pr <= 3 && wf <= 2 && wr == 8 && bf == 4 && br >= 7) return(1);
  413.   if (!(pf != 2 || pr != 6 || bf != 1 || br != 8))
  414.   { if (wf <= 3 && wr == 6) return(0);
  415.     if (wf == 4 && wr == 8) return(0);
  416.   }
  417.   if (pr == 7)
  418.   { if (wr < 8 && wpp == 2 && bq == 0) return(1);
  419.     if (wr == 6 && wf == pf && bq == 0) return(1);
  420.     if (wr >= 6 && wpp <= 2 && bq != 0) return(1);
  421.   }
  422.   blpuu = dist_ (bf, br, pf - 1, pr + 2);
  423.   wbdd = dist_ (wf, wr, bf, br - 2);
  424.   brpuu = dist_ (bf, br, pf + 1, pr + 2);
  425.   if (pr == 6)
  426.   { if (dist_ (bf, br, pf + 1, pr) > 1 &&
  427.         brpuu > dist_ (wf, wr, pf + 1, pr)) return(1);
  428.     if (pf != 1)
  429.     { if (blpuu > dist_ (wf, wr, pf - 1, pr)) return(1);
  430.       if (br == 8 && mbpf == 1 && wbdd == 1) return(1);
  431.       if (br > 6 && nbpf == 2 && dist_ (wf, wr, bf, 5) <= 1) return(1);
  432.     }
  433.     else
  434.       if (wf == 1 && wr == 8 && bf == 2 && br == 6) return(0);
  435.   }
  436.   mwpf = wf - pf;
  437.   if (mwpf < 0) mwpf = -mwpf;
  438.   if (pr >= 5 && mwpf == 2 && wr == pr && bf == wf && br - pr == 2) return(1);
  439.   brpu = dist_ (bf, br, pf + 1, pr + 1);
  440.   wrpu = dist_ (wf, wr, pf + 1, pr + 1);
  441.   blpu = dist_ (bf, br, pf - 1, pr + 1);
  442.   wlpu = dist_ (wf, wr, pf - 1, pr + 1);
  443.   if (!(pf == 1 || pr != 5))
  444.   { if (mwpf <= 1 && wr - pr == 1) return(1);
  445.     if (wrpu == 1 && brpu > 1) return(1);
  446.     if (wr >= 4 && bf == wf && br - pr >= 2 && mbpf == 3) return(1);
  447.     if (wlpu == 1 && blpu > 1) return(1);
  448.   }
  449.   if (pr == 2 && br == 3 && mbpf > 1 && dist_ (wf, wr, bf, br + 2) <= 1) return(1);
  450.   if (wr - pr == 2 && br == pr && mbpf == 1 && mwpf > 1 &&
  451.       (wf - pf) * (bf - pf) > 0) return(0);
  452.   if (pf == 1 && wf == 1 && wr == br && bf > 3) return(1);
  453.   sgf = pf - 1;
  454.   if (wf >= pf) { sgf = pf + 1; }
  455.   sgr = wr - (mwpf - 1);
  456.   if (mwpf == 0 && wr > br) sgr = wr - 1;
  457.   wsg = dist_ (wf, wr, sgf, sgr);
  458.   if (wr - pr - mwpf > 0 && wr - br >= -1 && bpp - (wsg + (sgr - ppr))
  459.       >= -1 && dist_ (bf, br, sgf, sgr) > wsg) return(1);
  460.   md = mbpf - mwpf;
  461.   if (!(pf != 1 || bf <= 3))
  462.   { sdr = br + (bf - 3);
  463.     if (sdr > 8) sdr = 8;
  464.     if (wr > br + 1) sdr = br;
  465.     if (sdr > ppr)
  466.     { wsd = dist_ (wf, wr, 3, sdr);
  467.       bsd = dist_ (bf, br, 3, sdr);
  468.       if (bsd - wsd < -1) return(0);
  469.       if (bsd <= wsd && md <= 0) return(0);
  470.     }
  471.   }
  472.   brpuuu = dist_ (bf, br, pf + 1, pr + 3);
  473.   if (brpu > wrpu && brpuuu > wrpu && pr - wr != pf - wf) return(1);
  474.   if (brpuuu == 0 && wrpu == 1) return(1);
  475.   blpuuu = dist_ (bf, br, pf - 1, pr + 3);
  476.   if (pf != 1)
  477.   { if (blpu > wlpu && blpuuu > wlpu && pr - wr != wf - pf) return(1);
  478.     if (blpuuu == 0 && wlpu == 1) return(1);
  479.   }
  480.   wrpuu = dist_ (wf, wr, pf + 1, pr + 2);
  481.   if (brpuu > wrpuu) return(1);
  482.   wlpuu = dist_ (wf, wr, pf - 1, pr + 2);
  483.   if (pf > 1 && blpuu > wlpuu) return(1);
  484.   if (br == pr)
  485.   { if (mwpf <= 2 && wr - pr == -1 && mbpf != 2) return(1);
  486.     if (dist_ (wf, wr, bf - 1, br + 2) <= 1 && bf - pf > 1) return(1);
  487.     if (dist_ (wf, wr, bf + 1, br + 2) <= 1 && bf - pf < -1) return(1);
  488.   }
  489.   if (pf != 1)
  490.   { if (br == pr && mbpf > 1 && dist_ (wf, wr, pf, pr - 1) <= 1) return(1);
  491.     if (br - pr >= 3 && wbdd == 1) return(1);
  492.     if (wr - pr >= 2 && wr < br && md >= 0) return(1);
  493.     if (mwpf <= 2 && wr - pr >= 3 && bf != pf && wr - br <= 1) return(1);
  494.     if (wr >= pr && br - pr >= 5 && mbpf >= 3 && md >= -1 && ppr == 3) return(1);
  495.     if (md >= -1 && pr == 2 && br == 8) return(1);
  496.   }
  497.   tbf = bf - 1;
  498.   if (pf > bf) tbf = bf + 1;
  499.   if (mbpf > 1 && br == ppr && dist_ (wf, wr, tbf, wr + 2) <= 1) return(1);
  500.   if (br == pr && bf - pf == -2 && dist_ (wf, wr, pf + 2, pr - 1) <= 1) return(1);
  501.   if (pf > 2 && br == pr && bf - pf == 2 &&
  502.       dist_ (wf, wr, pf - 2, pr - 1) <= 1) return(1);
  503.   return(0);
  504. }                /* kpkwv_ */
  505.  
  506. short 
  507. kpkbv_ (short pf, short pr, short wf, short wr, short bf, short br)
  508. {
  509.   static short incf[8] =
  510.     {0, 1, 1, 1, 0, -1, -1, -1};
  511.   static short incr[8] =
  512.     {1, 1, 0, -1, -1, -1, 0, 1};
  513.  
  514.   short dist_ (short, short, short, short);
  515.   short kpkwv_ (short, short, short, short, short, short);
  516.   static short i, nm, nbf, nbr;
  517.  
  518.   nm = 0;
  519.   for (i = 0; i < 8; ++i)
  520.     {
  521.       nbf = bf + incf[i];
  522.       if (nbf < 1 || nbf > 8) continue;
  523.       nbr = br + incr[i];
  524.       if (nbr < 1 || nbr > 8) continue;
  525.       if (dist_ (nbf, nbr, wf, wr) < 2) continue;
  526.       if (nbf == pf && nbr == pr) return(0);
  527.       if (nbr == pr + 1 && (nbf == pf - 1 || nbf == pf + 1)) continue;
  528.       ++nm;
  529.       if (kpkwv_ (pf, pr, wf, wr, nbf, nbr) == 0) return(0);
  530.     }
  531.   if (nm > 0) return(-1);
  532.   return(0);
  533. }                /* kpkbv_ */
  534.  
  535. short 
  536. dist_ (short f1, short r1, short f2, short r2)
  537. {
  538.   short ts;
  539.   static short fd, rd;
  540.  
  541.   fd = f2 - f1;
  542.   if (fd < 0) fd = -fd;
  543.  
  544.   rd = r2 - r1;
  545.   if (rd < 0) rd = -rd;
  546.  
  547.  ts = ((rd > fd) ? rd : fd);
  548.  return(ts);
  549. }                /* dist_ */
  550.  
  551. inline
  552. int
  553. ScoreK1PK (short side,
  554.        short winner,
  555.        short loser,
  556.        short king1,
  557.        register short king2,
  558.        register short sq)
  559.  
  560.      /*
  561.       *  We call Don Beal's routine with the necessary parameters and determine
  562.       *  win/draw/loss.  Then we compute the real evaluation which is +-500 for
  563.       *  a win/loss and 10 for a draw, plus some points to lead the computer to
  564.       *  a decisive winning/drawing line.
  565.       */
  566.  
  567. {
  568. #ifdef WAY4PL64
  569.   short s;
  570. #endif
  571.   short win, sqc, sqr, k1c, k1r, k2c, k2r;
  572.   const int drawn = 10, won = 500;
  573.  
  574. #ifdef WAY4PL64
  575. #ifdef CACHE
  576.   if (ProbeEETable(side,&s)) return s;
  577. #endif
  578. #endif
  579.   sqc = column (sq) + 1;
  580.   sqr = row (sq) + 1;
  581.   k1c = column (king1) + 1;
  582.   k1r = row (king1) + 1;
  583.   k2c = column (king2) + 1;
  584.   k2r = row (king2) + 1;
  585.   if (winner == black)
  586.     {
  587.       sqr = 9 - sqr;
  588.       k1r = 9 - k1r;
  589.       k2r = 9 - k2r;
  590.     }
  591.   if (sqc > 4)
  592.     {
  593.       sqc = 9 - sqc;
  594.       k1c = 9 - k1c;
  595.       k2c = 9 - k2c;
  596.     }
  597.  
  598.   if (side == winner)
  599.     win = kpkwv_ (sqc, sqr, k1c, k1r, k2c, k2r);
  600.   else
  601.     win = kpkbv_ (sqc, sqr, k1c, k1r, k2c, k2r);
  602.  
  603. #ifdef WAY4PL64
  604.   if (!win)  s = drawn + 5 * distance (sq, king2) - 5*distance(king1,king2);
  605.   else       s = won + 50 * (sqr - 2) + 10*distance(sq,king2);
  606. #else
  607.   if (!win)
  608.     return drawn + 5 * distance (sq, king2);
  609.   else
  610.     return won + 50 * (sqr - 2);
  611. #endif
  612.  
  613. #ifdef WAY4PL64
  614. #ifdef CACHE 
  615.   if (PUTVAR) PutInEETable (side, s); 
  616. #endif 
  617.  
  618.   return s;
  619. #endif
  620. }
  621.  
  622. inline
  623. short
  624. ScoreLoneKing (short side)
  625.  
  626.      /*
  627.       * Static evaluation when loser has only a king and winner has no pawns or no
  628.       * pieces.
  629.       */
  630.  
  631. {
  632. //  short ts;
  633.   register short winner, loser, king1, king2, s, i;
  634.  
  635.   if (mtl[white] == valueK && mtl[black] == valueK)
  636.     return 0;
  637.   UpdateWeights ();
  638.   winner = ((mtl[white] > mtl[black]) ? white : black);
  639.   loser = winner ^ 1;
  640.   king1 = PieceList[winner][0];
  641.   king2 = PieceList[loser][0];
  642.  
  643.   s = 0;
  644.  
  645.   if (pmtl[winner] == 0)
  646.     {
  647.       if (emtl[winner] == valueB + valueN)
  648.     s = ScoreKBNK (winner, king1, king2);
  649.       else if (emtl[winner] == valueN + valueN)
  650.     s = 0;
  651.     else if (emtl[winner] < valueR)
  652.        s = 0;
  653.       else
  654.     s = 500 + emtl[winner] - DyingKing[king2] - 2 * distance (king1, king2);
  655.     }
  656.   else
  657.     {
  658.       if (pmtl[winner] == valueP)
  659.     s = ScoreK1PK (side, winner, loser, king1, king2, PieceList[winner][1]);
  660.       else
  661.     for (i = 1; i <= PieceCnt[winner]; i++)
  662.       s += ScoreKPK (side, winner, loser, king1, king2, PieceList[winner][i]);
  663.     }
  664.   if (side != winner)
  665.     s = 0 - s;
  666.   return(s);
  667. //  ts = ((side == winner) ? s : -s);
  668. //  return (ts);
  669. }
  670.  
  671. #else // old pre 4pl67 code
  672.  
  673. short dist_ (short f1, short r1, short f2, short r2)
  674. {
  675.   return distdata [ f1-9+8*r1 ][ f2-9+8*r2 ];
  676. }
  677.  
  678. short 
  679. kpkwv_ (short pf, short pr, short wf, short wr, short bf, short br)
  680. {
  681.  
  682.   /*
  683.    *  Don Beal's routine, which was originally in Fortran.  See AICC 2
  684.    */
  685.  
  686.  
  687.   const short drawn=0, win=1;
  688.   
  689.   short wbdd, mbpf, blpu;
  690.   short brpu, mwpf, wlpu, wrpu, blpuu, brpuu, wlpuu, wrpuu, md,
  691.     bq, blpuuu, brpuuu, bsd, tbf, sgf, bpp, sdr, sgr, wsd, wsg, ppr, wpp;
  692.  
  693.  
  694.   ppr = pr;
  695.   if (pr == 2) { ppr = 3; }
  696.   if (pf != 1) { goto L2; }
  697.   if (bf != 3) { goto L1; }
  698.   if (pr == 7 && wf == 1 && wr == 8 && br > 6) return drawn;
  699.   if (pr == 6 && wf < 4 && wr == 6 && br == 8) return win;
  700. L1:
  701.   if (bf == 1 && br > pr) return drawn;
  702.   if (pr == 7 && bf > 2) return win;
  703.   if (bf <= 3 && br - ppr > 1) return drawn;
  704.   if (wf == 1 && bf == 3 && wr - pr == 1 && br - pr == 1) return drawn;
  705. L2:
  706.   bq = dist_ (bf, br, pf, 8);
  707.   if (bq > 8 - ppr) return win;
  708.   mbpf = bf - pf;
  709.   if (mbpf < 0) { mbpf = -mbpf; }
  710.   bpp = dist_ (bf, br, pf, ppr);
  711.   wpp = dist_ (wf, wr, pf, ppr);
  712.   if (bpp - wpp < -1 && br - pr != mbpf) return drawn;
  713.   if (pf == 1 && pr <= 3 && wf <= 2 && wr == 8 && bf == 4 && br >= 7) return win;
  714.   if (pf != 2 || pr != 6 || bf != 1 || br != 8) { goto L3; }
  715.   if (wf <= 3 && wr == 6) return drawn;
  716.   if (wf == 4 && wr == 8) return drawn;
  717. L3:
  718.   if (pr != 7) { goto L4; }
  719.   if (wr < 8 && wpp == 2 && bq == 0) return win;
  720.   if (wr == 6 && wf == pf && bq == 0) return win;
  721.   if (wr >= 6 && wpp <= 2 && bq != 0) return win;
  722. L4:
  723.   blpuu = dist_ (bf, br, pf-1, pr+2);
  724.   wbdd = dist_ (wf, wr, bf, br-2);
  725.   brpuu = dist_ (bf, br, pf+1, pr+2);
  726.   if (pr != 6) { goto L6; }
  727.   if (dist_ (bf, br, pf+1, pr) > 1 && brpuu > dist_ (wf, wr, pf+1, pr)) return win;
  728.   if (pf == 1) { goto L5; }
  729.   if (blpuu > dist_ (wf, wr, pf-1, pr)) return win;
  730.   if (br == 8 && mbpf == 1 && wbdd == 1) return win;
  731.   if (br > 6 && mbpf == 2 && dist_ (wf, wr, bf, 5) <= 1) return win;
  732.   goto L6;
  733. L5:
  734.   if (wf == 1 && wr == 8 && bf == 2 && br == 6) return drawn;
  735. L6:
  736.   mwpf = wf - pf;
  737.   if (mwpf < 0) { mwpf = -mwpf; }
  738.   if (pr >= 5 && mwpf == 2 && wr == pr && bf == wf && br - pr == 2) return win;
  739.   brpu = dist_ (bf, br, pf+1, pr+1);
  740.   wrpu = dist_ (wf, wr, pf+1, pr+1);
  741.   blpu = dist_ (bf, br, pf-1, pr+1);
  742.   wlpu = dist_ (wf, wr, pf-1, pr+1);
  743.   if (pf == 1 || pr != 5) { goto L7; }
  744.   if (mwpf <= 1 && wr - pr == 1) return win;
  745.   if (wrpu == 1 && brpu > 1) return win;
  746.   if (wr >= 4 && bf == wf && br - pr >= 2 && mbpf == 3) return win;
  747.   if (wlpu == 1 && blpu > 1) return win;
  748. L7:
  749.   if (pr == 2 && br == 3 && mbpf > 1 && dist_ (wf, wr, bf, br+2) <= 1) return win;
  750.   if (wr - pr == 2 && br == pr && mbpf == 1 && mwpf > 1 && (wf - pf) *
  751.       (bf - pf) > 0) return drawn;
  752.   if (pf == 1 && wf == 1 && wr == br && bf > 3) return win;
  753.   sgf = pf - 1;
  754.   if (wf >= pf) { sgf = pf + 1; }
  755.   sgr = wr - (mwpf - 1);
  756.   if (mwpf == 0 && wr > br) { sgr = wr - 1; }
  757.   wsg = dist_ (wf, wr, sgf, sgr);
  758.   if (wr - pr - mwpf > 0 && wr - br >= -1 && bpp - (wsg + (sgr - ppr))
  759.       >= -1 && dist_ (bf, br, sgf, sgr) > wsg) return win;
  760.   md = mbpf - mwpf;
  761.   if (pf != 1 || bf <= 3) { goto L8; }
  762.   sdr = br + (bf - 3);
  763.   if (sdr > 8) { sdr = 8; }
  764.   if (wr > br + 1) { sdr = br; }
  765.   if (sdr <= ppr) { goto L8; }
  766.   wsd = dist_ (wf, wr, 3, sdr);
  767.   bsd = dist_ (bf, br, 3, sdr);
  768.   if (bsd - wsd < -1) return drawn;
  769.   if (bsd <= wsd && md <= 0) return drawn;
  770. L8:
  771.   brpuuu = dist_ (bf, br, pf+1, pr+3);
  772.   if (brpu > wrpu && brpuuu > wrpu && pr - wr != pf - wf) return win;
  773.   if (brpuuu == 0 && wrpu == 1) return win;
  774.   blpuuu = dist_ (bf, br, pf-1, pr+3);
  775.   if (pf == 1) { goto L9; }
  776.   if (blpu > wlpu && blpuuu > wlpu && pr - wr != wf - pf) return win;
  777.   if (blpuuu == 0 && wlpu == 1) return win;
  778. L9:
  779.   wrpuu = dist_ (wf, wr, pf+1, pr+2);
  780.   if (brpuu > wrpuu) return win;
  781.   wlpuu = dist_ (wf, wr, pf-1, pr+2);
  782.   if (pf > 1 && blpuu > wlpuu) return win;
  783.   if (br != pr) { goto L10; }
  784.   if (mwpf <= 2 && wr - pr == -1 && mbpf != 2) return win;
  785.   if (dist_ (wf, wr, bf-1, br+2) <= 1 && bf - pf > 1) return win;
  786.   if (dist_ (wf, wr, bf+1, br+2) <= 1 && bf - pf < -1) return win;
  787. L10:
  788.   if (pf == 1) { goto L11; }
  789.   if (br == pr && mbpf > 1 && dist_ (wf, wr, pf, pr-1) <= 1) return win;
  790.   if (br - pr >= 3 && wbdd == 1) return win;
  791.   if (wr - pr >= 2 && wr < br && md >= 0) return win;
  792.   if (mwpf <= 2 && wr - pr >= 3 && bf != pf && wr - br <= 1) return win;
  793.   if (wr >= pr && br - pr >= 5 && mbpf >= 3 && md >= -1 && ppr == 3) return win;
  794.   if (md >= -1 && pr == 2 && br == 8) return win;
  795. L11:
  796.   tbf = bf - 1;
  797.   if (pf > bf) { tbf = bf + 1; }
  798.   if (mbpf > 1 && br == ppr && dist_ (wf, wr, tbf, wr+2) <= 1) return win;
  799.   if (br == pr && bf - pf == -2 && dist_ (wf, wr, pf+2, pr-1) <= 1) return win;
  800.   if (pf > 2 && br == pr && bf - pf == 2 && dist_ (wf, wr, pf-2, pr-1) <= 1) return win;
  801.  
  802.   return drawn;
  803. }                /* kpkwv_ */
  804.  
  805. short 
  806. kpkbv_ (short pf, short pr, short wf, short wr, short bf, short br)
  807. {
  808.   /* Initialized data */
  809.  
  810.   static short incf[8] =
  811.   {0, 1, 1, 1, 0, -1, -1, -1};
  812.   static short incr[8] =
  813.   {1, 1, 0, -1, -1, -1, 0, 1};
  814.  
  815.   /* System generated locals */
  816.   short ret_val;
  817.  
  818.   /* Local variables */
  819.   static short i;
  820.   static short nm, nbf, nbr;
  821.  
  822.   ret_val = 0;
  823.   nm = 0;
  824.   for (i = 1; i <= 8; ++i)
  825.     {
  826.       nbf = bf + incf[i - 1];
  827.       if (nbf < 1 || nbf > 8) { goto L1; }
  828.       nbr = br + incr[i - 1];
  829.       if (nbr < 1 || nbr > 8) { goto L1; }
  830.       if (dist_ (nbf, nbr, wf, wr) < 2) { goto L1; }
  831.       if (nbf == pf && nbr == pr) { goto L2; }
  832.       if (nbr == pr + 1 && (nbf == pf - 1 || nbf == pf + 1)) { goto L1; }
  833.       ++nm;
  834.       if (kpkwv_ (pf, pr, wf, wr, nbf, nbr) == 0) { goto L2; }
  835.     L1:
  836.       ;
  837.     }
  838.   if (nm > 0) { ret_val = -1; }
  839. L2:
  840.   return ret_val;
  841. }                /* kpkbv_ */
  842.  
  843.  
  844. inline
  845. int
  846. ScoreK1PK (short int side,
  847.        short int winner,
  848.        short int loser,
  849.        short int king1,
  850.        register short int king2,
  851.        register short int sq)
  852.  
  853.      /*
  854.       *  We call Don Beal's routine with the necessary parameters and determine
  855.       *  win/draw/loss.  Then we compute the real evaluation which is +-500 for
  856.       *  a win/loss and 10 for a draw, plus some points to lead the computer to
  857.       *  a decisive winning/drawing line.
  858.       */
  859.  
  860. {
  861.   short s, win, sqc, sqr, k1c, k1r, k2c, k2r;
  862.   const int drawn = 10, won = 500;
  863.  
  864. #ifdef CACHE
  865.   if (ProbeEETable(side,&s)) return s;
  866. #endif
  867.  
  868.   sqc = column (sq) + 1;
  869.   sqr = row (sq) + 1;
  870.   k1c = column (king1) + 1;
  871.   k1r = row (king1) + 1;
  872.   k2c = column (king2) + 1;
  873.   k2r = row (king2) + 1;
  874.   if (winner == black)
  875.     {
  876.       sqr = 9 - sqr;
  877.       k1r = 9 - k1r;
  878.       k2r = 9 - k2r;
  879.     }
  880.   if (sqc > 4)
  881.     {
  882.       sqc = 9 - sqc;
  883.       k1c = 9 - k1c;
  884.       k2c = 9 - k2c;
  885.     }
  886.  
  887.   if (side == winner) win = kpkwv_ (sqc, sqr, k1c, k1r, k2c, k2r);
  888.   else                win = kpkbv_ (sqc, sqr, k1c, k1r, k2c, k2r);
  889.  
  890.   if (!win)  s = drawn + 5 * distance (sq, king2) - 5*distance(king1,king2);
  891.   else       s = won + 50 * (sqr - 2) + 10*distance(sq,king2);
  892. //  if (!win)  s = drawn + 5 * distance (sq, king2); // old 2.50 way
  893. //  else       s = won + 50 * (sqr - 2); // old 2.50 way
  894.  
  895. #ifdef CACHE 
  896.   if (PUTVAR) PutInEETable (side, s); 
  897. #endif 
  898.  
  899.   return s;
  900. }
  901.  
  902.  
  903. inline
  904. short int
  905. ScoreLoneKing (ARGSZ int side)
  906.  
  907. /*
  908.  * Static evaluation when loser has only a king and winner has no pawns or no
  909.  * pieces.
  910.  */
  911.  
  912. {
  913.     register short winner, loser, king1, king2, s, i;
  914.  
  915.   if (mtl[white] == valueK && mtl[black] == valueK)
  916.     return 0;
  917.     UpdateWeights ();
  918.     winner = ((mtl[white] > mtl[black]) ? white : black);
  919.     loser = winner ^ 1;
  920.     king1 = PieceList[winner][0];
  921.     king2 = PieceList[loser][0];
  922.  
  923.     s = 0;
  924.  
  925.   if (pmtl[winner] == 0)
  926.     {
  927.     if (emtl[winner] == valueB + valueN)
  928.       s = ScoreKBNK (winner, king1, king2);
  929.       else if (emtl[winner] == valueN + valueN || 
  930.                emtl[winner] == valueN || emtl[winner] == valueB)
  931.     s = 0; 
  932.       else
  933.     s = 500 + emtl[winner] - DyingKing[king2] - 2 * distance (king1, king2);
  934.     }
  935.   else {
  936.     if (pmtl[winner] == valueP)
  937.         s = ScoreK1PK (side, winner, loser, king1, king2, PieceList[winner][1]);
  938.       else for (i = 1; i <= PieceCnt[winner]; i++)
  939.         s += ScoreKPK (side, winner, loser, king1, king2, PieceList[winner][i]);
  940.     }
  941.  
  942.     if (side != winner)
  943.      s = 0 - s;
  944.     return(s);
  945. /*    return ((side == winner) ? s : -s);*/
  946. }
  947.  
  948. #endif // old eval pre 4pl67 way
  949.  
  950.  
  951. /* ............    POSITIONAL EVALUATION ROUTINES    ............ */
  952.  
  953. /*
  954.  * Inputs are:
  955.  * pmtl[side] - value of pawns
  956.  * mtl[side]  - value of all material
  957.  * emtl[side] - vaule of all material - value of pawns - value of king
  958.  * hung[side] - count of hung pieces
  959.  * Tscore[ply] - search tree score for ply
  960.  * ply
  961.  * Pscore[ply] - positional score for ply ply
  962.  * INCscore    - bonus score or penalty for certain positions
  963.  * slk - single lone king flag
  964.  * Sdepth - search goal depth
  965.  * xwndw - evaluation window about alpha/beta
  966.  * EWNDW - second evaluation window about alpha/beta
  967.  * ChkFlag[ply]- checking piece at level ply or 0 if no check
  968.  * PC1[column] - # of my pawns in this column
  969.  * PC2[column] - # of opponents pawns in column
  970.  * PieceCnt[side] - just what it says
  971.  */
  972. inline
  973. int
  974. ScoreKPK (short side,
  975.       short winner,
  976.       short loser,
  977.       short king1,
  978.       register short king2,
  979.       register short sq)
  980.  
  981. /*
  982.  * Score King and Pawns versus King endings.
  983.  */
  984.  
  985. {
  986.     register short s, r;
  987.  
  988.     s = ((PieceCnt[winner] == 1) ? 50 : 120);
  989.     if (winner == white)
  990.       {
  991.       r = row (sq) - ((side == loser) ? 1 : 0);
  992.       if (row (king2) >= r && distance (sq, king2) < 8 - r)
  993.           s += 10 * row (sq);
  994.       else
  995.           s = 500 + 50 * row (sq);
  996.       if (row (sq) < 6)
  997.           sq += 16;
  998.       else if (row (sq) == 6)
  999.           sq += 8;
  1000.       }
  1001.     else
  1002.       {
  1003.       r = row (sq) + ((side == loser) ? 1 : 0);
  1004.       if (row (king2) <= r && distance (sq, king2) < r + 1)
  1005.           s += 10 * (7 - row (sq));
  1006.       else
  1007.           s = 500 + 50 * (7 - row (sq));
  1008.       if (row (sq) > 1)
  1009.           sq -= 16;
  1010.       else if (row (sq) == 1)
  1011.           sq -= 8;
  1012.       }
  1013.     s += 8 * (taxicab (king2, sq) - taxicab (king1, sq));
  1014.     return (s);
  1015. }
  1016.  
  1017. inline
  1018. int
  1019. ScoreKBNK (short winner, short king1, short king2)
  1020.  
  1021.  
  1022. /*
  1023.  * Score King+Bishop+Knight versus King endings.  Works fine now.
  1024.  */
  1025.  
  1026. {
  1027.     register short s, Bsq, Nsq, KBNKsq = 0;
  1028.  
  1029.     if (board[PieceList[winner][1]] == bishop)
  1030.       {
  1031.         Bsq = PieceList[winner][1];
  1032.         Nsq = PieceList[winner][2];
  1033.       }
  1034.     else
  1035.       {
  1036.         Bsq = PieceList[winner][2];
  1037.         Nsq = PieceList[winner][1];
  1038.       }
  1039.  
  1040.     KBNKsq = (((row (Bsq) % 2) == (column (Bsq) % 2)) ? 0 : 7);
  1041.  
  1042.     s = emtl[winner] - 300;
  1043.     s += ((KBNKsq == 0) ? KBNK[king2] : KBNK[locn (row (king2), 7 - column (king2))]);
  1044.  
  1045. //  The following 2 lines are a fix for this version
  1046.    s -= (8*taxicab(king1,king2) + 2*distance(Nsq,king2) + 
  1047.                                     distance(Bsq,king2)); 
  1048.    s += KingEnding[king1];
  1049.     return (s);
  1050. }
  1051.  
  1052. int
  1053. evaluate (register short side,
  1054.       register short ply,
  1055.       register short depth,
  1056.           register short ext,
  1057.       register short alpha,
  1058.       register short beta,
  1059.       short INCscore,
  1060.       short *InChk)    /* output Check flag */
  1061.  
  1062. /*
  1063.  * Compute an estimate of the score by adding the positional score from the
  1064.  * previous ply to the material difference. If this score falls inside a
  1065.  * window which is 180 points wider than the alpha-beta window (or within a
  1066.  * 50 point window during quiescence search) call ScorePosition() to
  1067.  * determine a score, otherwise return the estimated score. If one side has
  1068.  * only a king and the other either has no pawns or no pieces then the
  1069.  * function ScoreLoneKing() is called.
  1070.  */
  1071.  
  1072. {
  1073.     register short xside;
  1074.     register short slk;
  1075.     short s;
  1076.  
  1077.     xside = side ^ 1;
  1078.     s = -Pscore[ply - 1] + mtl[side] - mtl[xside] - INCscore;
  1079.     hung[white] = hung[black] = 0;
  1080.     slk = ((mtl[white] == valueK && (pmtl[black] == 0 || emtl[black] == 0)) ||
  1081.       (mtl[black] == valueK && (pmtl[white] == 0 || emtl[white] == 0)));
  1082.  
  1083.           /* should we use the estimete or score the position */
  1084.     if ( !slk && (ply == 1 ||
  1085. #ifdef CACHE
  1086.         (CheckEETable (side)) ||
  1087. #endif
  1088.         (myneweval ? ((
  1089.         (ply==Sdepth || (!ext && depth == 0 && s>=alpha-30 && s<=beta+30)) ||
  1090.         (ext && (s >= (alpha - 30) && s <= (beta + 30)) )) )
  1091.         :
  1092.         ((Sdepth ==  ply) ||
  1093.         (ply > Sdepth && (s >= (alpha - 30) && s <= (beta + 30)) )) )
  1094.         ))
  1095.  
  1096.       {
  1097.       /* score the position */
  1098.       ataks (side, atak[side]);
  1099.       if (Anyatak (side, PieceList[xside][0])){
  1100.       ataks (xside, atak[xside]);
  1101.       ChkFlag[ply-1] = *InChk = Anyatak (xside, PieceList[side][0]);
  1102.           return (10001 - ply);
  1103.       }
  1104.       ataks (xside, atak[xside]);
  1105.       ChkFlag[ply-1] = *InChk = Anyatak (xside, PieceList[side][0]);
  1106.  
  1107. #ifndef BAREBONES 
  1108.       EvalNodes++;
  1109. #endif
  1110.     if(ply>4)PUTVAR=true;
  1111.           s = ScorePosition (side);
  1112.     PUTVAR=false;
  1113.       }
  1114.     else
  1115.       {
  1116.       /* use the estimate but look at check and slk */
  1117.        *InChk = SqAtakd (PieceList[side][0], xside);
  1118.        ChkFlag[ply - 1] = ((*InChk) ? Pindex[TOsquare] + 1 : 0);
  1119.        if (SqAtakd (PieceList[xside][0], side)){ return (10001 - ply); }
  1120. #ifdef DEBUG 
  1121.        if(debuglevel & 4096){
  1122.       printf("%lx %lx %d %d\n",hashbd,hashkey,ply,s);
  1123.       }
  1124. #endif
  1125.       if (slk){
  1126.         if(ply>4)PUTVAR=true;
  1127.               s = ScoreLoneKing (side);
  1128.         PUTVAR=false;}
  1129.       }
  1130.  
  1131.     Pscore[ply] = s - mtl[side] + mtl[xside];
  1132.     ChkFlag[ply - 1] = ((*InChk) ? Pindex[TOsquare] + 1 : 0);
  1133.     QueenCheck[ply - 1] =       /* tom@izf.tno.nl */
  1134.           ((*InChk) && board[TOsquare] == queen) ? TOsquare : 0;
  1135. #ifdef DEBUG 
  1136.        if(debuglevel & 4096){
  1137.     printf("%lx %lx %d %d\n",hashbd,hashkey,ply,s);
  1138.     }
  1139. #endif
  1140.     return (s);
  1141. }
  1142.  
  1143. inline
  1144. int
  1145. BRscan (register short sq, short *mob)
  1146.  
  1147. /*
  1148.  * Find Bishop and Rook mobility, XRAY attacks, and pins. Increment the
  1149.  * hung[] array if a pin is found.
  1150.  */
  1151. {
  1152.     register unsigned char *ppos, *pdir;
  1153.     register short s, mobx;
  1154.     register short u, pin;
  1155.     short piece, *Kf;
  1156.     mobx = s = 0;
  1157.     Kf = Kfield[c1];
  1158.     piece = board[sq];
  1159.     ppos = nextpos[piece][sq];
  1160.     pdir = nextdir[piece][sq];
  1161.     u = ppos[sq];
  1162.     pin = -1;            /* start new direction */
  1163.     do
  1164.       {
  1165.       s += Kf[u];
  1166.       if (color[u] == neutral)
  1167.         {
  1168.         mobx++;
  1169.         if (ppos[u] == pdir[u])
  1170.             pin = -1;    /* oops new direction */
  1171.         u = ppos[u];
  1172.         }
  1173.       else if (pin < 0)
  1174.         {
  1175.         if (board[u] == pawn || board[u] == king)
  1176.             u = pdir[u];
  1177.         else
  1178.           {
  1179.               if (ppos[u] != pdir[u])
  1180.               pin = u;    /* not on the edge and on to find a pin */
  1181.               u = ppos[u];
  1182.           }
  1183.         }
  1184.       else
  1185.         {
  1186.         if (color[u] == c2 && (board[u] > piece || atk2[u] == 0))
  1187.           {
  1188.               if (color[pin] == c2)
  1189.             {
  1190.                 s += PINVAL;
  1191.                 if (atk2[pin] == 0 || atk1[pin] > control[board[pin]] + 1)
  1192.                 ++hung[c2];
  1193.             }
  1194.               else
  1195.               s += XRAY;
  1196.           }
  1197.         pin = -1;    /* new direction */
  1198.         u = pdir[u];
  1199.         }
  1200.       }
  1201.     while (u != sq);
  1202.     *mob = mobx;
  1203.     return s;
  1204. }
  1205.  
  1206. inline
  1207. short
  1208. KingScan (register short sq)
  1209.  
  1210. /*
  1211.  * Assign penalties if king can be threatened by checks, if squares near the
  1212.  * king are controlled by the enemy (especially the queen), or if there are
  1213.  * no pawns near the king. 
  1214.     The following must be true: 
  1215.         board[sq] == king 
  1216.         c1 == color[sq] 
  1217.         c2 == otherside[c1]
  1218.  */
  1219.  
  1220. #define ScoreThreat \
  1221.     if (color[u] != c2)\
  1222.       if (atk1[u] == 0 || (atk2[u] & 0xFF) > 1) ++cnt;\
  1223.       else s -= 3
  1224.  
  1225. {
  1226.     register short cnt;
  1227.     register unsigned char *ppos, *pdir;
  1228.     register short s;
  1229.     register short u;
  1230.     short ok;
  1231.  
  1232.     s = 0;
  1233.     cnt = 0;
  1234.     if (HasBishop[c2] || HasQueen[c2])
  1235.       {
  1236.       ppos = nextpos[bishop][sq];
  1237.       pdir = nextdir[bishop][sq];
  1238.       u = ppos[sq];
  1239.       do
  1240.         {
  1241.         if (atk2[u] & ctlBQ)
  1242.             ScoreThreat;
  1243.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  1244.         }
  1245.       while (u != sq);
  1246.       }
  1247.     if (HasRook[c2] || HasQueen[c2])
  1248.       {
  1249.       ppos = nextpos[rook][sq];
  1250.       pdir = nextdir[rook][sq];
  1251.       u = ppos[sq];
  1252.       do
  1253.         {
  1254.         if (atk2[u] & ctlRQ)
  1255.             ScoreThreat;
  1256.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  1257.         }
  1258.       while (u != sq);
  1259.       }
  1260.     if (HasKnight[c2])
  1261.       {
  1262.       pdir = nextdir[knight][sq];
  1263.       u = pdir[sq];
  1264.       do
  1265.         {
  1266.         if (atk2[u] & ctlNN)
  1267.             ScoreThreat;
  1268.         u = pdir[u];
  1269.         }
  1270.       while (u != sq);
  1271.       }
  1272.     s += (KSFTY * KTHRT[cnt]) / 16;
  1273.  
  1274.     cnt = 0;
  1275.     ok = false;
  1276.     pdir = nextpos[king][sq];
  1277.     u = pdir[sq];
  1278.     do
  1279.       {
  1280.       if (board[u] == pawn)
  1281.           ok = true;
  1282.       if (atk2[u] > atk1[u])
  1283.         {
  1284.         ++cnt;
  1285.         if (atk2[u] & ctlQ)
  1286.             if (atk2[u] > ctlQ + 1 && atk1[u] < ctlQ)
  1287.             s -= 4 * KSFTY;
  1288.         }
  1289.       u = pdir[u];
  1290.       }
  1291.     while (u != sq);
  1292.     if (!ok)
  1293.     s -= KSFTY;
  1294.     if (cnt > 1)
  1295.     s -= (KSFTY);
  1296.     return (s);
  1297. }
  1298.  
  1299. inline
  1300. int
  1301. trapped (register short sq)
  1302.  
  1303. /*
  1304.  * See if the attacked piece has unattacked squares to move to. The following
  1305.  * must be true: c1 == color[sq] c2 == otherside[c1]
  1306.  */
  1307.  
  1308. {
  1309.     register short u;
  1310.     register unsigned char *ppos, *pdir;
  1311.     register short piece;
  1312.  
  1313.     piece = board[sq];
  1314.     ppos = nextpos[ptype[c1][piece]][sq];
  1315.     pdir = nextdir[ptype[c1][piece]][sq];
  1316.     if (piece == pawn)
  1317.       {
  1318.       u = ppos[sq];        /* follow no captures thread */
  1319.       if (color[u] == neutral)
  1320.         {
  1321.         if (atk1[u] >= atk2[u])
  1322.             return (false);
  1323.         if (atk2[u] < ctlP)
  1324.           {
  1325.               u = ppos[u];
  1326.               if (color[u] == neutral && atk1[u] >= atk2[u])
  1327.               return (false);
  1328.           }
  1329.         }
  1330.       u = pdir[sq];        /* follow captures thread */
  1331.       if (color[u] == c2)
  1332.           return (false);
  1333.       u = pdir[u];
  1334.       if (color[u] == c2)
  1335.           return (false);
  1336.       }
  1337.     else
  1338.       {
  1339.       u = ppos[sq];
  1340.       do
  1341.         {
  1342.         if (color[u] != c1)
  1343.             if (atk2[u] == 0 || board[u] >= piece)
  1344.             return (false);
  1345.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  1346.         }
  1347.       while (u != sq);
  1348.       }
  1349.     return (true);
  1350. }
  1351.  
  1352.  
  1353. static inline int
  1354. PawnValue (register short sq, short side)
  1355. /*
  1356.  * Calculate the positional value for a pawn on 'sq'.
  1357.  */
  1358.  
  1359. {
  1360.     register short fyle, rank;
  1361.     register short j, s, a1, a2, in_square, r, e;
  1362.  
  1363.     a1 = (atk1[sq] & 0x4FFF);
  1364.     a2 = (atk2[sq] & 0x4FFF);
  1365.     rank = row (sq);
  1366.     fyle = column (sq);
  1367.     s = 0;
  1368.     if (c1 == white)
  1369.       {
  1370.       s = Mwpawn[sq];
  1371.       if ((sq == 11 && color[19] != neutral) || (sq == 12 && color[20] != neutral)) s += PEDRNK2B;
  1372.       if ((fyle == 0 || PC1[fyle - 1] == 0) && (fyle == 7 || PC1[fyle + 1] == 0)) s += ISOLANI[fyle];
  1373.       else if (PC1[fyle] > 1) s += PDOUBLED;
  1374.  
  1375.       if (a1 < ctlP && atk1[sq + 8] < ctlP)
  1376.         {
  1377.         s += BACKWARD[a2 & 0xFF];
  1378.         if (PC2[fyle] == 0) s += PWEAKH;
  1379.         if (color[sq + 8] != neutral) s += PBLOK;
  1380.         }
  1381.       if(rank != 7 && color[sq+8] == black && board[sq+8] == pawn) s -= PCRASH;
  1382.       if (PC2[fyle] == 0)
  1383.         {
  1384.         r = rank - (side == black)?1:0;
  1385.         in_square = (row (bking) >= r && distance (sq, bking) < 8 - r);
  1386.         e = (a2 == 0 || side == white)? 0:1;
  1387.         for (j = sq + 8; j < 64; j += 8)
  1388.             if (atk2[j] >= ctlP) { e = 2; break; }
  1389.             else if (atk2[j] > 0 || color[j] != neutral) e = 1;
  1390.  
  1391.         if (e == 2) s += (stage * PassedPawn3[rank]) / 10;
  1392.         else if (in_square || e == 1) s += (stage * PassedPawn2[rank]) / 10;
  1393.         else if (emtl[black] > 0) s += (stage * PassedPawn1[rank]) / 10;
  1394.         else s += PassedPawn0[rank];
  1395.         }
  1396.       }
  1397.     else if (c1 == black)
  1398.       {
  1399.       s = Mbpawn[sq];
  1400.       if ((sq == 51 && color[43] != neutral) || (sq == 52 && color[44] != neutral)) s += PEDRNK2B;
  1401.  
  1402.       if ((fyle == 0 || PC1[fyle - 1] == 0) && (fyle == 7 || PC1[fyle + 1] == 0)) s += ISOLANI[fyle];
  1403.       else if (PC1[fyle] > 1) s += PDOUBLED;
  1404.  
  1405.       if (a1 < ctlP && atk1[sq - 8] < ctlP)
  1406.         {
  1407.         s += BACKWARD[a2 & 0xFF];
  1408.         if (PC2[fyle] == 0) s += PWEAKH;
  1409.         if (color[sq - 8] != neutral) s += PBLOK;
  1410.         }
  1411.       if(rank != 0 && color[sq+8] == white && board[sq+8] == pawn) s -= PCRASH;
  1412.       if (PC2[fyle] == 0)
  1413.         {
  1414.         r = rank + (side == white)?1:0;
  1415.         in_square = (row (wking) <= r && distance (sq, wking) < r + 1);
  1416.         e = (a2 == 0 || side == black)?0:1;
  1417.         for (j = sq - 8; j >= 0; j -= 8)
  1418.             if (atk2[j] >= ctlP) { e = 2; break; }
  1419.             else if (atk2[j] > 0 || color[j] != neutral) e = 1;
  1420.  
  1421.         if (e == 2) s += (stage * PassedPawn3[7 - rank]) / 10;
  1422.         else if (in_square || e == 1) s += (stage * PassedPawn2[7 - rank]) / 10;
  1423.         else if (emtl[white] > 0) s += (stage * PassedPawn1[7 - rank]) / 10;
  1424.         else s += PassedPawn0[7 - rank];
  1425.         }
  1426.       }
  1427.     if((rank >2 && rank < 6) && (fyle > 2 && fyle < 5)) s += PCENTER;
  1428.     if (a2 > 0)
  1429.       {
  1430.       if (a1 == 0 || a2 > ctlP + 1)
  1431.         {
  1432.         s += HUNGP;
  1433.         if (trapped (sq)) hung[c1] += 2;
  1434.         hung[c1]++;
  1435.         }
  1436.       else if (a2 > a1) s += ATAKD;
  1437.       }
  1438.     return (s);
  1439. }
  1440.  
  1441. inline
  1442. int
  1443. KnightValue (register short sq, short side)
  1444.  
  1445. /*
  1446.  * Calculate the positional value for a knight on 'sq'.
  1447.  */
  1448.  
  1449. {
  1450.     register short s, a2, a1;
  1451.  
  1452.     s = Mknight[c1][sq];
  1453.     a2 = (atk2[sq] & 0x4FFF);
  1454.     if (a2 > 0)
  1455.       {
  1456.       a1 = (atk1[sq] & 0x4FFF);
  1457.       if (a1 == 0 || a2 > ctlBN + 1)
  1458.         {
  1459.         s += HUNGP;
  1460.         if (trapped (sq))
  1461.             hung[c1] += 2;
  1462.         hung[c1]++;
  1463.         }
  1464.       else if (a2 >= ctlBN || a1 < ctlP)
  1465.           s += ATAKD;
  1466.       }
  1467.     return (s);
  1468. }
  1469.  
  1470. inline
  1471. int
  1472. BishopValue (register short sq, short side)
  1473.  
  1474. /*
  1475.  * Calculate the positional value for a bishop on 'sq'.
  1476.  */
  1477.  
  1478. {
  1479.     register short s;
  1480.     register short a2, a1;
  1481.     short mob;
  1482.  
  1483.     s = Mbishop[c1][sq];
  1484.     s += BRscan (sq, &mob);
  1485.     s += BMBLTY[mob];
  1486.     a2 = (atk2[sq] & 0x4FFF);
  1487.     if (a2 > 0)
  1488.       {
  1489.       a1 = (atk1[sq] & 0x4FFF);
  1490.       if (a1 == 0 || a2 > ctlBN + 1)
  1491.         {
  1492.         s += HUNGP;
  1493.         if (trapped (sq))
  1494.             hung[c1] += 2;
  1495.         hung[c1]++;
  1496.         }
  1497.       else if (a2 >= ctlBN || a1 < ctlP)
  1498.           s += ATAKD;
  1499.       }
  1500.     return (s);
  1501. }
  1502.  
  1503. inline
  1504. int
  1505. RookValue (register short sq, short side)
  1506.  
  1507. /*
  1508.  * Calculate the positional value for a rook on 'sq'.
  1509.  */
  1510.  
  1511. {
  1512.     register short s;
  1513.     register short fyle, a2, a1;
  1514.     short mob;
  1515.  
  1516.     s = RookBonus;
  1517.     s += BRscan (sq, &mob);
  1518.     s += RMBLTY[mob];
  1519.     fyle = column (sq);
  1520.     if (PC1[fyle] == 0)
  1521.     { s += RHOPN;
  1522.             if (PC2[fyle] == 0)
  1523.             s += RHOPNX;
  1524.         }
  1525.     if (pmtl[c2] > 100 && row (sq) == rank7[c1])
  1526.     s += 10;
  1527.     if (stage > 2)
  1528.     s += 14 - taxicab (sq, EnemyKing);
  1529.     a2 = (atk2[sq] & 0x4FFF);
  1530.     if (a2 > 0)
  1531.       {
  1532.       a1 = (atk1[sq] & 0x4FFF);
  1533.       if (a1 == 0 || a2 > ctlR + 1)
  1534.         {
  1535.         s += HUNGP;
  1536.         if (trapped (sq))
  1537.             hung[c1] += 2;
  1538.         hung[c1]++;
  1539.         }
  1540.       else if (a2 >= ctlR || a1 < ctlP)
  1541.           s += ATAKD;
  1542.       }
  1543.     return (s);
  1544. }
  1545.  
  1546. inline
  1547. int
  1548. QueenValue (register short sq, short side)
  1549.  
  1550. /*
  1551.  * Calculate the positional value for a queen on 'sq'.
  1552.  */
  1553.  
  1554. {
  1555.     register short s, a2, a1;
  1556.  
  1557.     s = ((distance (sq, EnemyKing) < 3) ? 12 : 0);
  1558.     if (stage > 2)
  1559.     s += 14 - taxicab (sq, EnemyKing);
  1560.     a2 = (atk2[sq] & 0x4FFF);
  1561.     if (a2 > 0)
  1562.       {
  1563.       a1 = (atk1[sq] & 0x4FFF);
  1564.       if (a1 == 0 || a2 > ctlQ + 1)
  1565.         {
  1566.         s += HUNGP;
  1567.         if (trapped (sq))
  1568.             hung[c1] += 2;
  1569.         hung[c1]++;
  1570.         }
  1571.       else if (a2 >= ctlQ || a1 < ctlP)
  1572.           s += ATAKD;
  1573.       }
  1574.     return (s);
  1575. }
  1576.  
  1577. inline
  1578. int
  1579. KingValue (register short sq, short side)
  1580.  
  1581. /*
  1582.  * Calculate the positional value for a king on 'sq'.
  1583.  */
  1584.  
  1585. {
  1586.     register short s;
  1587.     register short fyle;
  1588.     short a2, a1;
  1589.     s = (emtl[side ^ 1] > KINGPOSLIMIT) ? Mking[c1][sq] : Mking[c1][sq] / 2;
  1590.     if (KSFTY > 0)
  1591.     if (Developed[c2] || stage > 0)
  1592.         s += KingScan (sq);
  1593.     if (castld[c1])
  1594.     s += KCASTLD;
  1595.     else if (Mvboard[kingP[c1]])
  1596.     s += KMOVD;
  1597.  
  1598.     fyle = column (sq);
  1599.     if (PC1[fyle] == 0)
  1600.     s += KHOPN;
  1601.     if (PC2[fyle] == 0)
  1602.     s += KHOPNX;
  1603.     switch (fyle)
  1604.       {
  1605.       case 5:
  1606.       if (PC1[7] == 0)
  1607.           s += KHOPN;
  1608.       if (PC2[7] == 0)
  1609.           s += KHOPNX;
  1610.       /* Fall through */
  1611.       case 4:
  1612.       case 6:
  1613.       case 0:
  1614.       if (PC1[fyle + 1] == 0)
  1615.           s += KHOPN;
  1616.       if (PC2[fyle + 1] == 0)
  1617.           s += KHOPNX;
  1618.       break;
  1619.       case 2:
  1620.       if (PC1[0] == 0)
  1621.           s += KHOPN;
  1622.       if (PC2[0] == 0)
  1623.           s += KHOPNX;
  1624.       /* Fall through */
  1625.       case 3:
  1626.       case 1:
  1627.       case 7:
  1628.       if (PC1[fyle - 1] == 0)
  1629.           s += KHOPN;
  1630.       if (PC2[fyle - 1] == 0)
  1631.           s += KHOPNX;
  1632.       break;
  1633.       default:
  1634.       /* Impossible! */
  1635.       break;
  1636.       }
  1637.  
  1638.     a2 = (atk2[sq] & 0x4FFF);
  1639.     if (a2 > 0)
  1640.       {
  1641.       a1 = (atk1[sq] & 0x4FFF);
  1642.       if (a1 == 0 || a2 > ctlK + 1)
  1643.         {
  1644.         s += HUNGP;
  1645.         ++hung[c1];
  1646.         }
  1647.       else
  1648.           s += ATAKD;
  1649.       }
  1650.     return (s);
  1651. }
  1652.  
  1653.  
  1654.  
  1655.  
  1656. short
  1657. ScorePosition (register short side)
  1658.  
  1659. /*
  1660.  * Perform normal static evaluation of board position. A score is generated
  1661.  * for each piece and these are summed to get a score for each side.
  1662.  */
  1663.  
  1664. {
  1665.     register short score;
  1666.     register short sq, i, xside;
  1667.     short s;
  1668.  
  1669.     UpdateWeights ();
  1670.     xside = side ^ 1;
  1671.     hung[white] = hung[black] = pscore[white] = pscore[black] = 0;
  1672. #ifdef CACHE
  1673.     if (!(hashkey+hashbd) || !ProbeEETable (side, &s))
  1674.       {
  1675. #endif
  1676.       for (c1 = white; c1 <= black; c1++)
  1677.         {
  1678.         c2 = c1 ^ 1;
  1679.         /* atk1 is array of atacks on squares by my side */
  1680.         atk1 = atak[c1];
  1681.         /* atk2 is array of atacks on squares by other side */
  1682.         atk2 = atak[c2];
  1683.         /* same for PC1 and PC2 */
  1684.         PC1 = PawnCnt[c1];
  1685.         PC2 = PawnCnt[c2];
  1686.         for (i = PieceCnt[c1]; i >= 0; i--)
  1687.           {
  1688.               sq = PieceList[c1][i];
  1689.               switch (board[sq])
  1690.             {
  1691.             case pawn:
  1692.                 s = PawnValue (sq, side);
  1693.                 break;
  1694.             case knight:
  1695.                 s = KnightValue (sq, side);
  1696.                 break;
  1697.             case bishop:
  1698.                 s = BishopValue (sq, side);
  1699.                 break;
  1700.             case rook:
  1701.                 s = RookValue (sq, side);
  1702.                 break;
  1703.             case queen:
  1704.                 s = QueenValue (sq, side);
  1705.                 break;
  1706.             case king:
  1707.                 s = KingValue (sq, side);
  1708.                 break;
  1709.             default:
  1710.                 s = 0;
  1711.                 break;
  1712.             }
  1713.               pscore[c1] += s;
  1714.               svalue[sq] = s;
  1715.           }
  1716.         }
  1717.     if (hung[side] > 1)
  1718.     pscore[side] += HUNGX;
  1719.     if (hung[xside] > 1)
  1720.     pscore[xside] += HUNGX;
  1721.  
  1722.     score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10;
  1723. #ifndef NODITHER
  1724.     if (dither)
  1725.       {
  1726.       if (flag.hash)
  1727.           gsrand (starttime + (unsigned int) hashbd);
  1728.       score += urand () % dither;
  1729.       }
  1730. #endif
  1731.     if (score > 0 && pmtl[side] == 0)
  1732.     if (emtl[side] < valueR)
  1733.         score = 0;
  1734.     else if (score < valueR)
  1735.         score /= 2;
  1736.     if (score < 0 && pmtl[xside] == 0)
  1737.     if (emtl[xside] < valueR)
  1738.         score = 0;
  1739.     else if (-score < valueR)
  1740.         score /= 2;
  1741.  
  1742.     if (mtl[xside] == valueK && emtl[side] > valueB)
  1743.     score += 200;
  1744.     if (mtl[side] == valueK && emtl[xside] > valueB)
  1745.     score -= 200;
  1746. #ifdef CACHE
  1747.     if(PUTVAR)PutInEETable(side,score);
  1748. #endif
  1749.     return (score);
  1750. #ifdef CACHE
  1751. }
  1752. else {
  1753. return s;
  1754. }
  1755. #endif
  1756. }
  1757. static inline void
  1758. BlendBoard (const short a[64], const short b[64], short c[64])
  1759. {
  1760.     register int sq, s;
  1761.     s = 10 - stage;
  1762.     for (sq = 0; sq < 64; sq++)
  1763.     c[sq] = ((a[sq] * s) + (b[sq] * stage)) / 10;
  1764. }
  1765.  
  1766.  
  1767. static inline void
  1768. CopyBoard (const short a[64], short b[64])
  1769. {
  1770.     register short *sqa, *sqb;
  1771.     for (sqa = a, sqb = b; sqa < a + 64;)
  1772.     *sqb++ = *sqa++;
  1773. }
  1774.  
  1775.  
  1776. short __aligned PawnStorm = false;
  1777.  
  1778. void
  1779. ExaminePosition (void)
  1780.  
  1781. /*
  1782.  * This is done one time before the search is started. Set up arrays Mwpawn,
  1783.  * Mbpawn, Mknight, Mbishop, Mking which are used in the SqValue() function
  1784.  * to determine the positional value of each piece.
  1785.  */
  1786.  
  1787. {
  1788.     register short i, sq;
  1789.     register short fyle;
  1790.     short wpadv, bpadv, wstrong, bstrong, z, side, pp, j, k, val, Pd, rank;
  1791.  
  1792.     ataks (white, atak[white]);
  1793.     ataks (black, atak[black]);
  1794.     UpdateWeights ();
  1795.     HasKnight[white] = HasKnight[black] = 0;
  1796.     HasBishop[white] = HasBishop[black] = 0;
  1797.     HasRook[white] = HasRook[black] = 0;
  1798.     HasQueen[white] = HasQueen[black] = 0;
  1799.     for (side = white; side <= black; side++)
  1800.     for (i = PieceCnt[side]; i >= 0; i--)
  1801.         switch (board[PieceList[side][i]])
  1802.           {
  1803.           case knight:
  1804.           ++HasKnight[side];
  1805.           break;
  1806.           case bishop:
  1807.           ++HasBishop[side];
  1808.           break;
  1809.           case rook:
  1810.           ++HasRook[side];
  1811.           break;
  1812.           case queen:
  1813.           ++HasQueen[side];
  1814.           break;
  1815.           }
  1816.     if (!Developed[white])
  1817.     Developed[white] = (board[1] != knight && board[2] != bishop &&
  1818.                 board[5] != bishop && board[6] != knight);
  1819.     if (!Developed[black])
  1820.     Developed[black] = (board[57] != knight && board[58] != bishop &&
  1821.                 board[61] != bishop && board[62] != knight);
  1822.     if (!PawnStorm && stage < 5)
  1823.     PawnStorm = ((column (wking) < 3 && column (bking) > 4) ||
  1824.              (column (wking) > 4 && column (bking) < 3));
  1825.  
  1826.     CopyBoard (pknight, Mknight[white]);
  1827.     CopyBoard (pknight, Mknight[black]);
  1828.     CopyBoard (pbishop, Mbishop[white]);
  1829.     CopyBoard (pbishop, Mbishop[black]);
  1830.     BlendBoard (KingOpening, KingEnding, Mking[white]);
  1831.     BlendBoard (KingOpening, KingEnding, Mking[black]);
  1832.  
  1833.     for (sq = 0; sq < 64; sq++)
  1834.       {
  1835.       fyle = column (sq);
  1836.       rank = row (sq);
  1837.       wstrong = bstrong = true;
  1838.       for (i = sq; i < 64; i += 8)
  1839.           if (Patak (black, i))
  1840.         {
  1841.             wstrong = false;
  1842.             break;
  1843.         }
  1844.       for (i = sq; i >= 0; i -= 8)
  1845.           if (Patak (white, i))
  1846.         {
  1847.             bstrong = false;
  1848.             break;
  1849.         }
  1850.       wpadv = bpadv = PADVNCM;
  1851.       if ((fyle == 0 || PawnCnt[white][fyle - 1] == 0) && (fyle == 7 || PawnCnt[white][fyle + 1] == 0))
  1852.           wpadv = PADVNCI;
  1853.       if ((fyle == 0 || PawnCnt[black][fyle - 1] == 0) && (fyle == 7 || PawnCnt[black][fyle + 1] == 0))
  1854.           bpadv = PADVNCI;
  1855.       Mwpawn[sq] = (wpadv * PawnAdvance[sq]) / 10;
  1856.       Mbpawn[sq] = (bpadv * PawnAdvance[63 - sq]) / 10;
  1857.       Mwpawn[sq] += PawnBonus;
  1858.       Mbpawn[sq] += PawnBonus;
  1859.       if (Mvboard[kingP[white]])
  1860.         {
  1861.         if ((fyle < 3 || fyle > 4) && distance (sq, wking) < 3)
  1862.             Mwpawn[sq] += PAWNSHIELD;
  1863.         }
  1864.       else if (rank < 3 && (fyle < 2 || fyle > 5))
  1865.           Mwpawn[sq] += PAWNSHIELD / 2;
  1866.       if (Mvboard[kingP[black]])
  1867.         {
  1868.         if ((fyle < 3 || fyle > 4) && distance (sq, bking) < 3)
  1869.             Mbpawn[sq] += PAWNSHIELD;
  1870.         }
  1871.       else if (rank > 4 && (fyle < 2 || fyle > 5))
  1872.           Mbpawn[sq] += PAWNSHIELD / 2;
  1873.       if (PawnStorm)
  1874.         {
  1875.         if ((column (wking) < 4 && fyle > 4) || (column (wking) > 3 && fyle < 3))
  1876.             Mwpawn[sq] += 3 * rank - 21;
  1877.         if ((column (bking) < 4 && fyle > 4) || (column (bking) > 3 && fyle < 3))
  1878.             Mbpawn[sq] -= 3 * rank;
  1879.         }
  1880.       Mknight[white][sq] += 5 - distance (sq, bking);
  1881.       Mknight[white][sq] += 5 - distance (sq, wking);
  1882.       Mknight[black][sq] += 5 - distance (sq, wking);
  1883.       Mknight[black][sq] += 5 - distance (sq, bking);
  1884.       Mbishop[white][sq] += BishopBonus;
  1885.       Mbishop[black][sq] += BishopBonus;
  1886.       for (i = PieceCnt[black]; i >= 0; i--)
  1887.           if (distance (sq, PieceList[black][i]) < 3)
  1888.           Mknight[white][sq] += KNIGHTPOST;
  1889.       for (i = PieceCnt[white]; i >= 0; i--)
  1890.           if (distance (sq, PieceList[white][i]) < 3)
  1891.           Mknight[black][sq] += KNIGHTPOST;
  1892.       if (wstrong)
  1893.           Mknight[white][sq] += KNIGHTSTRONG;
  1894.       if (bstrong)
  1895.           Mknight[black][sq] += KNIGHTSTRONG;
  1896.       if (wstrong)
  1897.           Mbishop[white][sq] += BISHOPSTRONG;
  1898.       if (bstrong)
  1899.           Mbishop[black][sq] += BISHOPSTRONG;
  1900.  
  1901.       if (HasBishop[white] == 2)
  1902.           Mbishop[white][sq] += 8;
  1903.       if (HasBishop[black] == 2)
  1904.           Mbishop[black][sq] += 8;
  1905.       if (HasKnight[white] == 2)
  1906.           Mknight[white][sq] += 5;
  1907.       if (HasKnight[black] == 2)
  1908.           Mknight[black][sq] += 5;
  1909.  
  1910.       Kfield[white][sq] = Kfield[black][sq] = 0;
  1911.       if (distance (sq, wking) == 1)
  1912.           Kfield[black][sq] = KATAK;
  1913.       if (distance (sq, bking) == 1)
  1914.           Kfield[white][sq] = KATAK;
  1915.       Pd = 0;
  1916.       for (k = 0; k <= PieceCnt[white]; k++)
  1917.         {
  1918.         i = PieceList[white][k];
  1919.         if (board[i] == pawn)
  1920.           {
  1921.               pp = true;
  1922.               z = i + ((row (i) == 6) ? 8 : 16);
  1923.               for (j = i + 8; j < 64; j += 8)
  1924.               if (Patak (black, j) || board[j] == pawn)
  1925.                 {
  1926.                 pp = false;
  1927.                 break;
  1928.                 }
  1929.               Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  1930.           }
  1931.         }
  1932.       for (k = 0; k <= PieceCnt[black]; k++)
  1933.         {
  1934.         i = PieceList[black][k];
  1935.         if (board[i] == pawn)
  1936.           {
  1937.               pp = true;
  1938.               z = i - ((row (i) == 1) ? 8 : 16);
  1939.               for (j = i - 8; j >= 0; j -= 8)
  1940.               if (Patak (white, j) || board[j] == pawn)
  1941.                 {
  1942.                 pp = false;
  1943.                 break;
  1944.                 }
  1945.               Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  1946.           }
  1947.         }
  1948.       if (Pd != 0)
  1949.         {
  1950.         val = (Pd * stage2) / 10;
  1951.         Mking[white][sq] -= val;
  1952.         Mking[black][sq] -= val;
  1953.         }
  1954.       }
  1955. }
  1956.  
  1957. void
  1958. UpdateWeights (void)
  1959.  
  1960. /*
  1961.  * If material balance has changed, determine the values for the positional
  1962.  * evaluation terms.
  1963.  */
  1964.  
  1965. {
  1966.     register short s1;
  1967.  
  1968.     emtl[white] = mtl[white] - pmtl[white] - valueK;
  1969.     emtl[black] = mtl[black] - pmtl[black] - valueK;
  1970.     tmtl = emtl[white] + emtl[black];
  1971.     s1 = ((tmtl > 6600) ? 0 : ((tmtl < 1400) ? 10 : (6600 - tmtl) / 520));
  1972.     if (s1 != stage)
  1973.       {
  1974.       stage = s1;
  1975.       stage2 = ((tmtl > 3600) ? 0 : ((tmtl < 1400) ? 10 : (3600 - tmtl) / 220));
  1976.       PEDRNK2B = -15;    /* centre pawn on 2nd rank & blocked */
  1977.       PBLOK = -4;        /* blocked backward pawn */
  1978.       PDOUBLED = -14;    /* doubled pawn */
  1979.       PWEAKH = -4;        /* weak pawn on half open file */
  1980.       PAWNSHIELD = 10 - stage;    /* pawn near friendly king */
  1981.       PADVNCM = 10;        /* advanced pawn multiplier */
  1982.       PADVNCI = 7;        /* muliplier for isolated pawn */
  1983.       PawnBonus = stage;
  1984.  
  1985.       KNIGHTPOST = (stage + 2) / 3;    /* knight near enemy pieces */
  1986.       KNIGHTSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  1987.  
  1988.       BISHOPSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  1989.       BishopBonus = BBONUS * stage;
  1990.  
  1991.       RHOPN = 10;        /* rook on half open file */
  1992.       RHOPNX = 4;
  1993.       RookBonus = RBONUS * stage;
  1994.  
  1995.       XRAY = 8;        /* Xray attack on piece */
  1996.       PINVAL = 10;        /* Pin */
  1997.  
  1998.       KHOPN = (3 * stage - 30) / 2;    /* king on half open file */
  1999.       KHOPNX = KHOPN / 2;
  2000.       KCASTLD = 10 - stage;
  2001.       KMOVD = -40 / (stage + 1);    /* king moved before castling */
  2002.       KATAK = (10 - stage) / 2;    /* B,R attacks near enemy king */
  2003.       KSFTY = ((stage < 8) ? (KINGSAFETY - 4 * stage) : 0);
  2004.  
  2005.       ATAKD = -6;        /* defender > attacker */
  2006.       HUNGP = -12;        /* each hung piece */
  2007.       HUNGX = -18;        /* extra for >1 hung piece */
  2008.       }
  2009. }
  2010.  
  2011. #ifdef REALOLDEVAL // pre 4pl67 code
  2012. /* ............    POSITIONAL EVALUATION ROUTINES    ............ */
  2013.  
  2014. /*
  2015.  * Inputs are:
  2016.  * pmtl[side] - value of pawns
  2017.  * mtl[side]  - value of all material
  2018.  * emtl[side] - vaule of all material - value of pawns - value of king
  2019.  * hung[side] - count of hung pieces
  2020.  * Tscore[ply] - search tree score for ply
  2021.  * ply
  2022.  * Pscore[ply] - positional score for ply ply
  2023.  * INCscore    - bonus score or penalty for certain positions
  2024.  * slk - single lone king flag
  2025.  * Sdepth - search goal depth
  2026.  * xwndw - evaluation window about alpha/beta
  2027.  * EWNDW - second evaluation window about alpha/beta
  2028.  * ChkFlag[ply]- checking piece at level ply or 0 if no check
  2029.  */
  2030.  
  2031. inline
  2032. int
  2033. ScoreKPK (ARGSZ int side,
  2034.       ARGSZ int winner,
  2035.       ARGSZ int loser,
  2036.       ARGSZ int king1,
  2037.       ARGSZ int king2,
  2038.       ARGSZ int sq)
  2039.  
  2040. /*
  2041.  * Score King and Pawns versus King endings.
  2042.  */
  2043.  
  2044. {
  2045.     register short s, r;
  2046.  
  2047.     s = ((PieceCnt[winner] == 1) ? 50 : 120);
  2048.     if (winner == white)
  2049.       {
  2050.       r = row (sq) - ((side == loser) ? 1 : 0);
  2051.       if (row (king2) >= r && distance (sq, king2) < 8 - r)
  2052.           s += 10 * row (sq);
  2053.       else
  2054.           s = 500 + 50 * row (sq);
  2055.       if (row (sq) < 6)
  2056.           sq += 16;
  2057.       else if (row (sq) == 6)
  2058.           sq += 8;
  2059.       }
  2060.     else
  2061.       {
  2062.       r = row (sq) + ((side == loser) ? 1 : 0);
  2063.       if (row (king2) <= r && distance (sq, king2) < r + 1)
  2064.           s += 10 * (7 - row (sq));
  2065.       else
  2066.           s = 500 + 50 * (7 - row (sq));
  2067.       if (row (sq) > 1)
  2068.           sq -= 16;
  2069.       else if (row (sq) == 1)
  2070.           sq -= 8;
  2071.       }
  2072.     s += 8 * (taxicab (king2, sq) - taxicab (king1, sq));
  2073.     return (s);
  2074. }
  2075.  
  2076.  
  2077. inline
  2078. int
  2079. ScoreKBNK (ARGSZ int winner, ARGSZ int king1, ARGSZ int king2)
  2080.  
  2081.  
  2082. /*
  2083.  * Score King+Bishop+Knight versus King endings. This doesn't work all that
  2084.  * well but it's better than nothing.
  2085.  */
  2086.  
  2087. {
  2088.     register short s, sq, KBNKsq = 0;
  2089.  
  2090.     for (sq = 0; sq < 64; sq++)
  2091.     if (board[sq] == bishop)
  2092.         KBNKsq = (((row (sq) % 2) == (column (sq) % 2)) ? 0 : 7);
  2093.  
  2094.     s = emtl[winner] - 300;
  2095.     s += ((KBNKsq == 0) ? KBNK[king2] : KBNK[locn (row (king2), 7 - column (king2))]);
  2096.     s -= ((taxicab (king1, king2) + distance (PieceList[winner][1], king2) + distance (PieceList[winner][2], king2)));
  2097.     return (s);
  2098. }
  2099.  
  2100.  
  2101.  
  2102.  
  2103. int
  2104. evaluate (INTSIZE int side,
  2105.       INTSIZE int ply,
  2106.       INTSIZE int alpha,
  2107.       INTSIZE int beta,
  2108.       INTSIZE int INCscore,
  2109.       short int *InChk)    /* output Check flag */
  2110.  
  2111. /*
  2112.  * Compute an estimate of the score by adding the positional score from the
  2113.  * previous ply to the material difference. If this score falls inside a
  2114.  * window which is 180 points wider than the alpha-beta window (or within a
  2115.  * 50 point window during quiescence search) call ScorePosition() to
  2116.  * determine a score, otherwise return the estimated score. If one side has
  2117.  * only a king and the other either has no pawns or no pieces then the
  2118.  * function ScoreLoneKing() is called.
  2119.  */
  2120.  
  2121. {
  2122.     register short xside;
  2123.     register short int slk;
  2124.     short s;
  2125. /*    int HEVAL=false; seems useless to me! */
  2126.  
  2127.     xside = side ^ 1;
  2128.     s = -Pscore[ply - 1] + mtl[side] - mtl[xside] - INCscore;
  2129.     hung[white] = hung[black] = 0;
  2130.     slk = ((mtl[white] == valueK && (pmtl[black] == 0 || emtl[black] == 0)) ||
  2131.       (mtl[black] == valueK && (pmtl[white] == 0 || emtl[white] == 0)));
  2132.  
  2133.           /* should we use the estimete or score the position */
  2134.     if (!(slk) && (ply == 1 ||
  2135. #ifdef CACHE
  2136.         (/*HEVAL =*/ CheckEETable (side)) ||
  2137. #endif
  2138.     (Sdepth ==  ply) || 
  2139.         (ply > Sdepth && (s >= (alpha - 30) && s <= (beta + 30)) )))
  2140.       {
  2141.       /* score the position */
  2142.       ataks (side, atak[side]);
  2143.       if (Anyatak (side, PieceList[xside][0])){
  2144.       ataks (xside, atak[xside]);
  2145.       *InChk = Anyatak (xside, PieceList[side][0]);
  2146.           return (10001 - ply);
  2147.       }
  2148.       ataks (xside, atak[xside]);
  2149.       *InChk = Anyatak (xside, PieceList[side][0]);
  2150. #ifndef BAREBONES 
  2151.       EvalNodes++;
  2152. #endif
  2153.     if(ply>4)PUTVAR=true;
  2154.           s = ScorePosition (side);
  2155.     PUTVAR=false;
  2156.       }
  2157.     else
  2158.       {
  2159.       /* use the estimate but look at check and slk */
  2160.       *InChk = SqAtakd (PieceList[side][0], xside);
  2161.       if (SqAtakd (PieceList[xside][0], side)){
  2162.           return (10001 - ply);
  2163.       }
  2164.  
  2165.       if (slk) {
  2166.         if (ply>4) PUTVAR=true;
  2167.             s = ScoreLoneKing (side);
  2168.             PUTVAR=false;
  2169.             }
  2170.       }
  2171.  
  2172.     Pscore[ply] = s - mtl[side] + mtl[xside];
  2173.     ChkFlag[ply - 1] = ((*InChk) ? Pindex[TOsquare] + 1 : 0);
  2174.     return (s);
  2175. }
  2176.  
  2177. inline
  2178. int
  2179. BRscan (ARGSZ int sq, short int *mob)
  2180.  
  2181. /*
  2182.  * Find Bishop and Rook mobility, XRAY attacks, and pins. Increment the
  2183.  * hung[] array if a pin is found.
  2184.  */
  2185. {
  2186.     register unsigned char *ppos, *pdir;
  2187.     register short s, mobx;
  2188.     register short u, pin;
  2189.     short piece, *Kf;
  2190.     mobx = s = 0;
  2191.     Kf = Kfield[c1];
  2192.     piece = board[sq];
  2193.     ppos = nextpos[piece][sq];
  2194.     pdir = nextdir[piece][sq];
  2195.     u = ppos[sq];
  2196.     pin = -1;            /* start new direction */
  2197.     do
  2198.       {
  2199.       s += Kf[u];
  2200.       if (color[u] == neutral)
  2201.         {
  2202.         mobx++;
  2203.         if (ppos[u] == pdir[u])
  2204.             pin = -1;    /* oops new direction */
  2205.         u = ppos[u];
  2206.         }
  2207.       else if (pin < 0)
  2208.         {
  2209.         if (board[u] == pawn || board[u] == king)
  2210.             u = pdir[u];
  2211.         else
  2212.           {
  2213.               if (ppos[u] != pdir[u])
  2214.               pin = u;    /* not on the edge and on to find a pin */
  2215.               u = ppos[u];
  2216.           }
  2217.         }
  2218.       else
  2219.         {
  2220.         if (color[u] == c2 && (board[u] > piece || atk2[u] == 0))
  2221.           {
  2222.               if (color[pin] == c2)
  2223.             {
  2224.                 s += PINVAL;
  2225.                 if (atk2[pin] == 0 || atk1[pin] > control[board[pin]] + 1)
  2226.                 ++hung[c2];
  2227.             }
  2228.               else
  2229.               s += XRAY;
  2230.           }
  2231.         pin = -1;    /* new direction */
  2232.         u = pdir[u];
  2233.         }
  2234.       }
  2235.     while (u != sq);
  2236.     *mob = mobx;
  2237.     return s;
  2238. }
  2239.  
  2240. inline
  2241. short int
  2242. KingScan (ARGSZ int sq)
  2243.  
  2244. /*
  2245.  * Assign penalties if king can be threatened by checks, if squares near the
  2246.  * king are controlled by the enemy (especially the queen), or if there are
  2247.  * no pawns near the king. The following must be true: board[sq] == king c1
  2248.  * == color[sq] c2 == otherside[c1]
  2249.  */
  2250.  
  2251. #define ScoreThreat \
  2252.     if (color[u] != c2)\
  2253.       if (atk1[u] == 0 || (atk2[u] & 0xFF) > 1) ++cnt;\
  2254.       else s -= 3
  2255.  
  2256. {
  2257.     register short cnt;
  2258.     register unsigned char *ppos, *pdir;
  2259.     register short int s;
  2260.     register short u;
  2261.     short int ok;
  2262.  
  2263.     s = 0;
  2264.     cnt = 0;
  2265.     if (HasBishop[c2] || HasQueen[c2])
  2266.       {
  2267.       ppos = nextpos[bishop][sq];
  2268.       pdir = nextdir[bishop][sq];
  2269.       u = ppos[sq];
  2270.       do
  2271.         {
  2272.         if (atk2[u] & ctlBQ)
  2273.             ScoreThreat;
  2274.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  2275.         }
  2276.       while (u != sq);
  2277.       }
  2278.     if (HasRook[c2] || HasQueen[c2])
  2279.       {
  2280.       ppos = nextpos[rook][sq];
  2281.       pdir = nextdir[rook][sq];
  2282.       u = ppos[sq];
  2283.       do
  2284.         {
  2285.         if (atk2[u] & ctlRQ)
  2286.             ScoreThreat;
  2287.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  2288.         }
  2289.       while (u != sq);
  2290.       }
  2291.     if (HasKnight[c2])
  2292.       {
  2293.       pdir = nextdir[knight][sq];
  2294.       u = pdir[sq];
  2295.       do
  2296.         {
  2297.         if (atk2[u] & ctlNN)
  2298.             ScoreThreat;
  2299.         u = pdir[u];
  2300.         }
  2301.       while (u != sq);
  2302.       }
  2303.     s += (KSFTY * KTHRT[cnt]) / 16;
  2304.  
  2305.     cnt = 0;
  2306.     ok = false;
  2307.     pdir = nextpos[king][sq];
  2308.     u = pdir[sq];
  2309.     do
  2310.       {
  2311.       if (board[u] == pawn)
  2312.           ok = true;
  2313.       if (atk2[u] > atk1[u])
  2314.         {
  2315.         ++cnt;
  2316.         if (atk2[u] & ctlQ)
  2317.             if (atk2[u] > ctlQ + 1 && atk1[u] < ctlQ)
  2318.             s -= 4 * KSFTY;
  2319.         }
  2320.       u = pdir[u];
  2321.       }
  2322.     while (u != sq);
  2323.     if (!ok)
  2324.     s -= KSFTY;
  2325.     if (cnt > 1)
  2326.     s -= (KSFTY);
  2327.     return (s);
  2328. }
  2329.  
  2330. inline
  2331. int
  2332. trapped (ARGSZ int sq)
  2333.  
  2334. /*
  2335.  * See if the attacked piece has unattacked squares to move to. The following
  2336.  * must be true: c1 == color[sq] c2 == otherside[c1]
  2337.  */
  2338.  
  2339. {
  2340.     register short u;
  2341.     register unsigned char *ppos, *pdir;
  2342.     register short int piece;
  2343.  
  2344.     piece = board[sq];
  2345.     ppos = nextpos[ptype[c1][piece]][sq];
  2346.     pdir = nextdir[ptype[c1][piece]][sq];
  2347.     if (piece == pawn)
  2348.       {
  2349.       u = ppos[sq];        /* follow no captures thread */
  2350.       if (color[u] == neutral)
  2351.         {
  2352.         if (atk1[u] >= atk2[u])
  2353.             return (false);
  2354.         if (atk2[u] < ctlP)
  2355.           {
  2356.               u = ppos[u];
  2357.               if (color[u] == neutral && atk1[u] >= atk2[u])
  2358.               return (false);
  2359.           }
  2360.         }
  2361.       u = pdir[sq];        /* follow captures thread */
  2362.       if (color[u] == c2)
  2363.           return (false);
  2364.       u = pdir[u];
  2365.       if (color[u] == c2)
  2366.           return (false);
  2367.       }
  2368.     else
  2369.       {
  2370.       u = ppos[sq];
  2371.       do
  2372.         {
  2373.         if (color[u] != c1)
  2374.             if (atk2[u] == 0 || board[u] >= piece)
  2375.             return (false);
  2376.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  2377.         }
  2378.       while (u != sq);
  2379.       }
  2380.     return (true);
  2381. }
  2382.  
  2383.  
  2384. static inline int
  2385. PawnValue (ARGSZ int sq, ARGSZ int side)
  2386. /*
  2387.  * Calculate the positional value for a pawn on 'sq'.
  2388.  */
  2389.  
  2390. {
  2391.     register short fyle, rank;
  2392.     register short j, s, a1, a2, in_square, r, e;
  2393.  
  2394.     a1 = (atk1[sq] & 0x4FFF);
  2395.     a2 = (atk2[sq] & 0x4FFF);
  2396.     rank = row (sq);
  2397.     fyle = column (sq);
  2398.     s = 0;
  2399.     if (c1 == white)
  2400.       {
  2401.       s = Mwpawn[sq];
  2402.       if ((sq == 11 && color[19] != neutral)
  2403.           || (sq == 12 && color[20] != neutral))
  2404.           s += PEDRNK2B;
  2405.       if ((fyle == 0 || PC1[fyle - 1] == 0)
  2406.           && (fyle == 7 || PC1[fyle + 1] == 0))
  2407.           s += ISOLANI[fyle];
  2408.       else if (PC1[fyle] > 1)
  2409.           s += PDOUBLED;
  2410.       if (a1 < ctlP && atk1[sq + 8] < ctlP)
  2411.         {
  2412.         s += BACKWARD[a2 & 0xFF];
  2413.         if (PC2[fyle] == 0)
  2414.             s += PWEAKH;
  2415.         if (color[sq + 8] != neutral)
  2416.             s += PBLOK;
  2417.         }
  2418.       if (PC2[fyle] == 0)
  2419.         {
  2420.         if (side == black)
  2421.             r = rank - 1;
  2422.         else
  2423.             r = rank;
  2424.         in_square = (row (bking) >= r && distance (sq, bking) < 8 - r);
  2425.         if (a2 == 0 || side == white)
  2426.             e = 0;
  2427.         else
  2428.             e = 1;
  2429.         for (j = sq + 8; j < 64; j += 8)
  2430.             if (atk2[j] >= ctlP)
  2431.               {
  2432.               e = 2;
  2433.               break;
  2434.               }
  2435.             else if (atk2[j] > 0 || color[j] != neutral)
  2436.             e = 1;
  2437.         if (e == 2)
  2438.             s += (stage * PassedPawn3[rank]) / 10;
  2439.         else if (in_square || e == 1)
  2440.             s += (stage * PassedPawn2[rank]) / 10;
  2441.         else if (emtl[black] > 0)
  2442.             s += (stage * PassedPawn1[rank]) / 10;
  2443.         else
  2444.             s += PassedPawn0[rank];
  2445.         }
  2446.       }
  2447.     else if (c1 == black)
  2448.       {
  2449.       s = Mbpawn[sq];
  2450.       if ((sq == 51 && color[43] != neutral)
  2451.           || (sq == 52 && color[44] != neutral))
  2452.           s += PEDRNK2B;
  2453.       if ((fyle == 0 || PC1[fyle - 1] == 0) &&
  2454.           (fyle == 7 || PC1[fyle + 1] == 0))
  2455.           s += ISOLANI[fyle];
  2456.       else if (PC1[fyle] > 1)
  2457.           s += PDOUBLED;
  2458.       if (a1 < ctlP && atk1[sq - 8] < ctlP)
  2459.         {
  2460.         s += BACKWARD[a2 & 0xFF];
  2461.         if (PC2[fyle] == 0)
  2462.             s += PWEAKH;
  2463.         if (color[sq - 8] != neutral)
  2464.             s += PBLOK;
  2465.         }
  2466.       if (PC2[fyle] == 0)
  2467.         {
  2468.         if (side == white)
  2469.             r = rank + 1;
  2470.         else
  2471.             r = rank;
  2472.         in_square = (row (wking) <= r && distance (sq, wking) < r + 1);
  2473.         if (a2 == 0 || side == black)
  2474.             e = 0;
  2475.         else
  2476.             e = 1;
  2477.         for (j = sq - 8; j >= 0; j -= 8)
  2478.             if (atk2[j] >= ctlP)
  2479.               {
  2480.               e = 2;
  2481.               break;
  2482.               }
  2483.             else if (atk2[j] > 0 || color[j] != neutral)
  2484.             e = 1;
  2485.         if (e == 2)
  2486.             s += (stage * PassedPawn3[7 - rank]) / 10;
  2487.         else if (in_square || e == 1)
  2488.             s += (stage * PassedPawn2[7 - rank]) / 10;
  2489.         else if (emtl[white] > 0)
  2490.             s += (stage * PassedPawn1[7 - rank]) / 10;
  2491.         else
  2492.             s += PassedPawn0[7 - rank];
  2493.         }
  2494.       }
  2495.     if (a2 > 0)
  2496.       {
  2497.       if (a1 == 0 || a2 > ctlP + 1)
  2498.         {
  2499.         s += HUNGP;
  2500.         if (trapped (sq))
  2501.             hung[c1] += 2;
  2502.         hung[c1]++;
  2503.         }
  2504.       else if (a2 > a1)
  2505.           s += ATAKD;
  2506.       }
  2507.     return (s);
  2508. }
  2509.  
  2510. inline
  2511. int
  2512. KnightValue (ARGSZ int sq)
  2513.  
  2514. /*
  2515.  * Calculate the positional value for a knight on 'sq'.
  2516.  */
  2517.  
  2518. {
  2519.     register short s, a2, a1;
  2520.  
  2521.     s = Mknight[c1][sq];
  2522.     a2 = (atk2[sq] & 0x4FFF);
  2523.     if (a2 > 0)
  2524.       {
  2525.       a1 = (atk1[sq] & 0x4FFF);
  2526.       if (a1 == 0 || a2 > ctlBN + 1)
  2527.         {
  2528.         s += HUNGP;
  2529.         if (trapped (sq))
  2530.             hung[c1] += 2;
  2531.         hung[c1]++;
  2532.         }
  2533.       else if (a2 >= ctlBN || a1 < ctlP)
  2534.           s += ATAKD;
  2535.       }
  2536.     return (s);
  2537. }
  2538.  
  2539. inline
  2540. int
  2541. BishopValue (ARGSZ int sq)
  2542.  
  2543. /*
  2544.  * Calculate the positional value for a bishop on 'sq'.
  2545.  */
  2546.  
  2547. {
  2548.     register short s;
  2549.     register short a2, a1;
  2550.     short mob;
  2551.  
  2552.     s = Mbishop[c1][sq];
  2553.     s += BRscan (sq, &mob);
  2554.     s += BMBLTY[mob];
  2555.     a2 = (atk2[sq] & 0x4FFF);
  2556.     if (a2 > 0)
  2557.       {
  2558.       a1 = (atk1[sq] & 0x4FFF);
  2559.       if (a1 == 0 || a2 > ctlBN + 1)
  2560.         {
  2561.         s += HUNGP;
  2562.         if (trapped (sq))
  2563.             hung[c1] += 2;
  2564.         hung[c1]++;
  2565.         }
  2566.       else if (a2 >= ctlBN || a1 < ctlP)
  2567.           s += ATAKD;
  2568.       }
  2569.     return (s);
  2570. }
  2571.  
  2572. inline
  2573. int
  2574. RookValue (ARGSZ int sq)
  2575.  
  2576. /*
  2577.  * Calculate the positional value for a rook on 'sq'.
  2578.  */
  2579.  
  2580. {
  2581.     register short s;
  2582.     register short fyle, a2, a1;
  2583.     short mob;
  2584.  
  2585.     s = RookBonus;
  2586.     s += BRscan (sq, &mob);
  2587.     s += RMBLTY[mob];
  2588.     fyle = column (sq);
  2589.     if (PC1[fyle] == 0)
  2590.      {
  2591.     s += RHOPN;
  2592.             if (PC2[fyle] == 0)
  2593.             s += RHOPNX;
  2594.      }
  2595.     if (pmtl[c2] > 100 && row (sq) == rank7[c1])
  2596.     s += 10;
  2597.     if (stage > 2)
  2598.     s += 14 - taxicab (sq, EnemyKing);
  2599.     a2 = (atk2[sq] & 0x4FFF);
  2600.     if (a2 > 0)
  2601.       {
  2602.       a1 = (atk1[sq] & 0x4FFF);
  2603.       if (a1 == 0 || a2 > ctlR + 1)
  2604.         {
  2605.         s += HUNGP;
  2606.         if (trapped (sq))
  2607.             hung[c1] += 2;
  2608.         hung[c1]++;
  2609.         }
  2610.       else if (a2 >= ctlR || a1 < ctlP)
  2611.           s += ATAKD;
  2612.       }
  2613.     return (s);
  2614. }
  2615.  
  2616. inline
  2617. int
  2618. QueenValue (ARGSZ int sq)
  2619.  
  2620. /*
  2621.  * Calculate the positional value for a queen on 'sq'.
  2622.  */
  2623.  
  2624. {
  2625.     register short s, a2, a1;
  2626.  
  2627.     s = ((distance (sq, EnemyKing) < 3) ? 12 : 0);
  2628.     if (stage > 2)
  2629.     s += 14 - taxicab (sq, EnemyKing);
  2630.     a2 = (atk2[sq] & 0x4FFF);
  2631.     if (a2 > 0)
  2632.       {
  2633.       a1 = (atk1[sq] & 0x4FFF);
  2634.       if (a1 == 0 || a2 > ctlQ + 1)
  2635.         {
  2636.         s += HUNGP;
  2637.         if (trapped (sq))
  2638.             hung[c1] += 2;
  2639.         hung[c1]++;
  2640.         }
  2641.       else if (a2 >= ctlQ || a1 < ctlP)
  2642.           s += ATAKD;
  2643.       }
  2644.     return (s);
  2645. }
  2646.  
  2647. inline
  2648. int
  2649. KingValue (ARGSZ int sq, ARGSZ int side)
  2650.  
  2651. /*
  2652.  * Calculate the positional value for a king on 'sq'.
  2653.  */
  2654.  
  2655. {
  2656.     register short s;
  2657.     register short fyle;
  2658.     short int a2, a1;
  2659.     s = (emtl[side ^ 1] > KINGPOSLIMIT) ? Mking[c1][sq] : Mking[c1][sq] / 2;
  2660.     if (KSFTY > 0)
  2661.     if (Developed[c2] || stage > 0)
  2662.         s += KingScan (sq);
  2663.     if (castld[c1])
  2664.     s += KCASTLD;
  2665.     else if (Mvboard[kingP[c1]])
  2666.     s += KMOVD;
  2667.  
  2668.     fyle = column (sq);
  2669.     if (PC1[fyle] == 0)
  2670.     s += KHOPN;
  2671.     if (PC2[fyle] == 0)
  2672.     s += KHOPNX;
  2673.     switch (fyle)
  2674.       {
  2675.       case 5:
  2676.       if (PC1[7] == 0)
  2677.           s += KHOPN;
  2678.       if (PC2[7] == 0)
  2679.           s += KHOPNX;
  2680.       /* Fall through */
  2681.       case 4:
  2682.       case 6:
  2683.       case 0:
  2684.       if (PC1[fyle + 1] == 0)
  2685.           s += KHOPN;
  2686.       if (PC2[fyle + 1] == 0)
  2687.           s += KHOPNX;
  2688.       break;
  2689.       case 2:
  2690.       if (PC1[0] == 0)
  2691.           s += KHOPN;
  2692.       if (PC2[0] == 0)
  2693.           s += KHOPNX;
  2694.       /* Fall through */
  2695.       case 3:
  2696.       case 1:
  2697.       case 7:
  2698.       if (PC1[fyle - 1] == 0)
  2699.           s += KHOPN;
  2700.       if (PC2[fyle - 1] == 0)
  2701.           s += KHOPNX;
  2702.       break;
  2703.       default:
  2704.       /* Impossible! */
  2705.       break;
  2706.       }
  2707.  
  2708.     a2 = (atk2[sq] & 0x4FFF);
  2709.     if (a2 > 0)
  2710.       {
  2711.       a1 = (atk1[sq] & 0x4FFF);
  2712.       if (a1 == 0 || a2 > ctlK + 1)
  2713.         {
  2714.         s += HUNGP;
  2715.         ++hung[c1];
  2716.         }
  2717.       else
  2718.           s += ATAKD;
  2719.       }
  2720.     return (s);
  2721. }
  2722.  
  2723.  
  2724. short int
  2725. ScorePosition (register short int side)
  2726.  
  2727. /*
  2728.  * Perform normal static evaluation of board position. A score is generated
  2729.  * for each piece and these are summed to get a score for each side.
  2730.  */
  2731.  
  2732. {
  2733.     register short int score;
  2734.     register short sq, i, xside;
  2735.     short int s;
  2736.  
  2737.     UpdateWeights ();
  2738.     xside = side ^ 1;
  2739.     hung[white] = hung[black] = pscore[white] = pscore[black] = 0;
  2740. #ifdef CACHE
  2741.     if (!ProbeEETable (side, &s))
  2742.       {
  2743. #endif
  2744.       for (c1 = white; c1 <= black; c1++)
  2745.         {
  2746.         c2 = c1 ^ 1;
  2747.         /* atk1 is array of atacks on squares by my side */
  2748.         atk1 = atak[c1];
  2749.         /* atk2 is array of atacks on squares by other side */
  2750.         atk2 = atak[c2];
  2751.         /* same for PC1 and PC2 */
  2752.         PC1 = PawnCnt[c1];
  2753.         PC2 = PawnCnt[c2];
  2754.         for (i = PieceCnt[c1]; i >= 0; i--)
  2755.           {
  2756.               sq = PieceList[c1][i];
  2757.               switch (board[sq])
  2758.             {
  2759.             case pawn:
  2760.                 s = PawnValue (sq, side);
  2761.                 break;
  2762.             case knight:
  2763.                 s = KnightValue (sq);
  2764.                 break;
  2765.             case bishop:
  2766.                 s = BishopValue (sq);
  2767.                 break;
  2768.             case rook:
  2769.                 s = RookValue (sq);
  2770.                 break;
  2771.             case queen:
  2772.                 s = QueenValue (sq);
  2773.                 break;
  2774.             case king:
  2775.                 s = KingValue (sq, side);
  2776.                 break;
  2777.             default:
  2778.                 s = 0;
  2779.                 break;
  2780.             }
  2781.               pscore[c1] += s;
  2782.               svalue[sq] = s;
  2783.           }
  2784.         }
  2785.     if (hung[side] > 1)
  2786.     pscore[side] += HUNGX;
  2787.     if (hung[xside] > 1)
  2788.     pscore[xside] += HUNGX;
  2789.  
  2790.     score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10;
  2791.     if (dither)
  2792.       {
  2793.       if (flag.hash)
  2794.           gsrand (starttime + (unsigned int) hashbd);
  2795.       score += urand () % dither;
  2796.       }
  2797.  
  2798.     if (score > 0 && pmtl[side] == 0)
  2799.     if (emtl[side] < valueR)
  2800.         score = 0;
  2801.     else if (score < valueR)
  2802.         score /= 2;
  2803.     if (score < 0 && pmtl[xside] == 0)
  2804.     if (emtl[xside] < valueR)
  2805.         score = 0;
  2806.     else if (-score < valueR)
  2807.         score /= 2;
  2808.  
  2809.     if (mtl[xside] == valueK && emtl[side] > valueB)
  2810.     score += 200;
  2811.     if (mtl[side] == valueK && emtl[xside] > valueB)
  2812.     score -= 200;
  2813. #ifdef CACHE
  2814.     if(PUTVAR)PutInEETable(side,score);
  2815. #endif
  2816.     return (score);
  2817. #ifdef CACHE
  2818. }
  2819. else {
  2820. return s;
  2821. }
  2822. #endif
  2823. }
  2824.  
  2825.  
  2826. static inline void
  2827. BlendBoard (const short int a[64], const short int b[64], short int c[64])
  2828. {
  2829.     register int sq, s;
  2830.     s = 10 - stage;
  2831.     for (sq = 0; sq < 64; sq++)
  2832.     c[sq] = ((a[sq] * s) + (b[sq] * stage)) / 10;
  2833. }
  2834.  
  2835.  
  2836. static inline void
  2837. CopyBoard (const short int a[64], short int b[64])
  2838. {
  2839. #ifndef AMIGA
  2840.     register short *sqa, *sqb;
  2841.  
  2842.     for (sqa = (short *)a, sqb = b; sqa < a + 64;)
  2843.     *sqb++ = *sqa++;
  2844. #else
  2845.  MoveMem128(a,b);
  2846. /* MoveMem(a,b,64*sizeof(short));*/
  2847. #endif
  2848. }
  2849.  
  2850.  
  2851. void
  2852. ExaminePosition (void)
  2853.  
  2854. /*
  2855.  * This is done one time before the search is started. Set up arrays Mwpawn,
  2856.  * Mbpawn, Mknight, Mbishop, Mking which are used in the SqValue() function
  2857.  * to determine the positional value of each piece.
  2858.  */
  2859.  
  2860. {
  2861.     register short i, sq;
  2862.     register short fyle;
  2863.     short wpadv, bpadv, wstrong, bstrong, z, side, pp, j, k, val, Pd, rank;
  2864.     static short PawnStorm = false;
  2865.  
  2866.     ataks (white, atak[white]);
  2867.     ataks (black, atak[black]);
  2868.     UpdateWeights ();
  2869.     HasKnight[white] = HasKnight[black] = 0;
  2870.     HasBishop[white] = HasBishop[black] = 0;
  2871.     HasRook[white] = HasRook[black] = 0;
  2872.     HasQueen[white] = HasQueen[black] = 0;
  2873.     for (side = white; side <= black; side++)
  2874.     for (i = PieceCnt[side]; i >= 0; i--)
  2875.         switch (board[PieceList[side][i]])
  2876.           {
  2877.           case knight:
  2878.           ++HasKnight[side];
  2879.           break;
  2880.           case bishop:
  2881.           ++HasBishop[side];
  2882.           break;
  2883.           case rook:
  2884.           ++HasRook[side];
  2885.           break;
  2886.           case queen:
  2887.           ++HasQueen[side];
  2888.           break;
  2889.           }
  2890.     if (!Developed[white])
  2891.     Developed[white] = (board[1] != knight && board[2] != bishop &&
  2892.                 board[5] != bishop && board[6] != knight);
  2893.     if (!Developed[black])
  2894.     Developed[black] = (board[57] != knight && board[58] != bishop &&
  2895.                 board[61] != bishop && board[62] != knight);
  2896.     if (!PawnStorm && stage < 5)
  2897.     PawnStorm = ((column (wking) < 3 && column (bking) > 4) ||
  2898.              (column (wking) > 4 && column (bking) < 3));
  2899.  
  2900.     CopyBoard (pknight, Mknight[white]);
  2901.     CopyBoard (pknight, Mknight[black]);
  2902.     CopyBoard (pbishop, Mbishop[white]);
  2903.     CopyBoard (pbishop, Mbishop[black]);
  2904.     BlendBoard (KingOpening, KingEnding, Mking[white]);
  2905.     BlendBoard (KingOpening, KingEnding, Mking[black]);
  2906.  
  2907.     for (sq = 0; sq < 64; sq++)
  2908.       {
  2909.       fyle = column (sq);
  2910.       rank = row (sq);
  2911.       wstrong = bstrong = true;
  2912.       for (i = sq; i < 64; i += 8)
  2913.           if (Patak (black, i))
  2914.         {
  2915.             wstrong = false;
  2916.             break;
  2917.         }
  2918.       for (i = sq; i >= 0; i -= 8)
  2919.           if (Patak (white, i))
  2920.         {
  2921.             bstrong = false;
  2922.             break;
  2923.         }
  2924.       wpadv = bpadv = PADVNCM;
  2925.       if ((fyle == 0 || PawnCnt[white][fyle - 1] == 0) && (fyle == 7 || PawnCnt[white][fyle + 1] == 0))
  2926.           wpadv = PADVNCI;
  2927.       if ((fyle == 0 || PawnCnt[black][fyle - 1] == 0) && (fyle == 7 || PawnCnt[black][fyle + 1] == 0))
  2928.           bpadv = PADVNCI;
  2929.       Mwpawn[sq] = (wpadv * PawnAdvance[sq]) / 10;
  2930.       Mbpawn[sq] = (bpadv * PawnAdvance[63 - sq]) / 10;
  2931.       Mwpawn[sq] += PawnBonus;
  2932.       Mbpawn[sq] += PawnBonus;
  2933.       if (Mvboard[kingP[white]])
  2934.         {
  2935.         if ((fyle < 3 || fyle > 4) && distance (sq, wking) < 3)
  2936.             Mwpawn[sq] += PAWNSHIELD;
  2937.         }
  2938.       else if (rank < 3 && (fyle < 2 || fyle > 5))
  2939.           Mwpawn[sq] += PAWNSHIELD / 2;
  2940.       if (Mvboard[kingP[black]])
  2941.         {
  2942.         if ((fyle < 3 || fyle > 4) && distance (sq, bking) < 3)
  2943.             Mbpawn[sq] += PAWNSHIELD;
  2944.         }
  2945.       else if (rank > 4 && (fyle < 2 || fyle > 5))
  2946.           Mbpawn[sq] += PAWNSHIELD / 2;
  2947.       if (PawnStorm)
  2948.         {
  2949.         if ((column (wking) < 4 && fyle > 4) || (column (wking) > 3 && fyle < 3))
  2950.             Mwpawn[sq] += 3 * rank - 21;
  2951.         if ((column (bking) < 4 && fyle > 4) || (column (bking) > 3 && fyle < 3))
  2952.             Mbpawn[sq] -= 3 * rank;
  2953.         }
  2954.       Mknight[white][sq] += 5 - distance (sq, bking);
  2955.       Mknight[white][sq] += 5 - distance (sq, wking);
  2956.       Mknight[black][sq] += 5 - distance (sq, wking);
  2957.       Mknight[black][sq] += 5 - distance (sq, bking);
  2958.       Mbishop[white][sq] += BishopBonus;
  2959.       Mbishop[black][sq] += BishopBonus;
  2960.       for (i = PieceCnt[black]; i >= 0; i--)
  2961.           if (distance (sq, PieceList[black][i]) < 3)
  2962.           Mknight[white][sq] += KNIGHTPOST;
  2963.       for (i = PieceCnt[white]; i >= 0; i--)
  2964.           if (distance (sq, PieceList[white][i]) < 3)
  2965.           Mknight[black][sq] += KNIGHTPOST;
  2966.       if (wstrong)
  2967.           Mknight[white][sq] += KNIGHTSTRONG;
  2968.       if (bstrong)
  2969.           Mknight[black][sq] += KNIGHTSTRONG;
  2970.       if (wstrong)
  2971.           Mbishop[white][sq] += BISHOPSTRONG;
  2972.       if (bstrong)
  2973.           Mbishop[black][sq] += BISHOPSTRONG;
  2974.  
  2975.       if (HasBishop[white] == 2)
  2976.           Mbishop[white][sq] += 8;
  2977.       if (HasBishop[black] == 2)
  2978.           Mbishop[black][sq] += 8;
  2979.       if (HasKnight[white] == 2)
  2980.           Mknight[white][sq] += 5;
  2981.       if (HasKnight[black] == 2)
  2982.           Mknight[black][sq] += 5;
  2983.  
  2984.       Kfield[white][sq] = Kfield[black][sq] = 0;
  2985.       if (distance (sq, wking) == 1)
  2986.           Kfield[black][sq] = KATAK;
  2987.       if (distance (sq, bking) == 1)
  2988.           Kfield[white][sq] = KATAK;
  2989.       Pd = 0;
  2990.       for (k = 0; k <= PieceCnt[white]; k++)
  2991.         {
  2992.         i = PieceList[white][k];
  2993.         if (board[i] == pawn)
  2994.           {
  2995.               pp = true;
  2996.               z = i + ((row (i) == 6) ? 8 : 16);
  2997.               for (j = i + 8; j < 64; j += 8)
  2998.               if (Patak (black, j) || board[j] == pawn)
  2999.                 {
  3000.                 pp = false;
  3001.                 break;
  3002.                 }
  3003.               Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  3004.           }
  3005.         }
  3006.       for (k = 0; k <= PieceCnt[black]; k++)
  3007.         {
  3008.         i = PieceList[black][k];
  3009.         if (board[i] == pawn)
  3010.           {
  3011.               pp = true;
  3012.               z = i - ((row (i) == 1) ? 8 : 16);
  3013.               for (j = i - 8; j >= 0; j -= 8)
  3014.               if (Patak (white, j) || board[j] == pawn)
  3015.                 {
  3016.                 pp = false;
  3017.                 break;
  3018.                 }
  3019.               Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  3020.           }
  3021.         }
  3022.       if (Pd != 0)
  3023.         {
  3024.         val = (Pd * stage2) / 10;
  3025.         Mking[white][sq] -= val;
  3026.         Mking[black][sq] -= val;
  3027.         }
  3028.       }
  3029. }
  3030.  
  3031. void
  3032. UpdateWeights (void)
  3033.  
  3034. /*
  3035.  * If material balance has changed, determine the values for the positional
  3036.  * evaluation terms.
  3037.  */
  3038.  
  3039. {
  3040.     register short s1;
  3041.  
  3042.     emtl[white] = mtl[white] - pmtl[white] - valueK;
  3043.     emtl[black] = mtl[black] - pmtl[black] - valueK;
  3044.     tmtl = emtl[white] + emtl[black];
  3045.     s1 = ((tmtl > 6600) ? 0 : ((tmtl < 1400) ? 10 : (6600 - tmtl) / 520));
  3046.     if (s1 != stage)
  3047.       {
  3048.       stage = s1;
  3049.       stage2 = ((tmtl > 3600) ? 0 : ((tmtl < 1400) ? 10 : (3600 - tmtl) / 220));
  3050.       PEDRNK2B = -15;    /* centre pawn on 2nd rank & blocked */
  3051.       PBLOK = -4;        /* blocked backward pawn */
  3052.       PDOUBLED = -14;    /* doubled pawn */
  3053.       PWEAKH = -4;        /* weak pawn on half open file */
  3054.       PAWNSHIELD = 10 - stage;    /* pawn near friendly king */
  3055.       PADVNCM = 10;        /* advanced pawn multiplier */
  3056.       PADVNCI = 7;        /* muliplier for isolated pawn */
  3057.       PawnBonus = stage;
  3058.  
  3059.       KNIGHTPOST = (stage + 2) / 3;    /* knight near enemy pieces */
  3060.       KNIGHTSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  3061.  
  3062.       BISHOPSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  3063.       BishopBonus = BBONUS * stage;
  3064.  
  3065.       RHOPN = 10;        /* rook on half open file */
  3066.       RHOPNX = 4;
  3067.       RookBonus = RBONUS * stage;
  3068.  
  3069.       XRAY = 8;        /* Xray attack on piece */
  3070.       PINVAL = 10;        /* Pin */
  3071.  
  3072.       KHOPN = (3 * stage - 30) / 2;    /* king on half open file */
  3073.       KHOPNX = KHOPN / 2;
  3074.       KCASTLD = 10 - stage;
  3075.       KMOVD = -40 / (stage + 1);    /* king moved before castling */
  3076.       KATAK = (10 - stage) / 2;    /* B,R attacks near enemy king */
  3077.       KSFTY = ((stage < 8) ? (KINGSAFETY - 4 * stage) : 0);
  3078.  
  3079.       ATAKD = -6;        /* defender > attacker */
  3080.       HUNGP = -12;        /* each hung piece */
  3081.       HUNGX = -18;        /* extra for >1 hung piece */
  3082.       }
  3083. }
  3084.  
  3085. #endif // realold eval