home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 7 Games / 07-Games.zip / PMCHESSR.ZIP / EVAL.C < prev    next >
C/C++ Source or Header  |  1990-11-29  |  35KB  |  1,333 lines

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