home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 1 / FFMCD01.bin / bbs / libdisks / d700t799 / disk790.lha / UChess / UChessSrc.lha / eval.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-17  |  34.3 KB  |  1,448 lines

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