home *** CD-ROM | disk | FTP | other *** search
/ Power Bytes: Board & Strategy Games / PB2.ISO / chess / eval.c < prev    next >
C/C++ Source or Header  |  1991-06-16  |  36KB  |  1,335 lines

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