home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume4 / gnuchess2 / part04 / gnuchess.c2
Text File  |  1988-06-10  |  20KB  |  683 lines

  1.  
  2. /* ............    POSITIONAL EVALUATION ROUTINES    ............ */
  3.  
  4. ScorePosition(side,score)
  5. short side,*score;
  6.  
  7. /*
  8.    Perform normal static evaluation of board position. A score is 
  9.    generated for each piece and these are summed to get a score for each 
  10.    side. 
  11. */
  12.  
  13. {
  14. register short sq,s,i,xside;
  15. short pscore[3];
  16.  
  17.   wking = PieceList[white][0]; bking = PieceList[black][0];
  18.   UpdateWeights();
  19.   xside = otherside[side];
  20.   pscore[white] = pscore[black] = 0;
  21.  
  22.   for (c1 = white; c1 <= black; c1++)
  23.     {
  24.       c2 = otherside[c1];
  25.       if (c1 == white) EnemyKing = bking; else EnemyKing = wking;
  26.       atk1 = atak[c1]; atk2 = atak[c2];
  27.       PC1 = PawnCnt[c1]; PC2 = PawnCnt[c2];
  28.       for (i = 0; i <= PieceCnt[c1]; i++)
  29.         {
  30.           sq = PieceList[c1][i];
  31.           s = SqValue(sq,side);
  32.           pscore[c1] += s;
  33.           svalue[sq] = s;
  34.         }
  35.     }
  36.   if (hung[side] > 1) pscore[side] += HUNGX;
  37.   if (hung[xside] > 1) pscore[xside] += HUNGX;
  38.   
  39.   *score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10;
  40.   if (dither) *score += rand() % dither;
  41.   
  42.   if (*score > 0 && pmtl[side] == 0)
  43.     if (emtl[side] < valueR) *score = 0;
  44.     else if (*score < valueR) *score /= 2;
  45.   if (*score < 0 && pmtl[xside] == 0)
  46.     if (emtl[xside] < valueR) *score = 0;
  47.     else if (-*score < valueR) *score /= 2;
  48.     
  49.   if (mtl[xside] == valueK && emtl[side] > valueB) *score += 200;
  50.   if (mtl[side] == valueK && emtl[xside] > valueB) *score -= 200;
  51. }
  52.  
  53.  
  54. ScoreLoneKing(side,score)
  55. short side,*score;
  56.  
  57. /* 
  58.    Static evaluation when loser has only a king and winner has no pawns
  59.    or no pieces.
  60. */
  61.  
  62. {
  63. register short winner,loser,king1,king2,s,i;
  64.  
  65.   UpdateWeights();
  66.   if (mtl[white] > mtl[black]) winner = white; else winner = black;
  67.   loser = otherside[winner];
  68.   king1 = PieceList[winner][0]; king2 = PieceList[loser][0];
  69.   
  70.   s = 0;
  71.   
  72.   if (pmtl[winner] > 0)
  73.     for (i = 1; i <= PieceCnt[winner]; i++)
  74.       s += ScoreKPK(side,winner,loser,king1,king2,PieceList[winner][i]);
  75.       
  76.   else if (emtl[winner] == valueB+valueN)
  77.     s = ScoreKBNK(winner,king1,king2);
  78.     
  79.   else if (emtl[winner] > valueB)
  80.     s = 500 + emtl[winner] - 2*KingEnding[king2] - 2*distance(king1,king2);
  81.     
  82.   if (side == winner) *score = s; else *score = -s;
  83. }
  84.  
  85.  
  86. int ScoreKPK(side,winner,loser,king1,king2,sq)
  87. short side,winner,loser,king1,king2,sq;
  88.  
  89. /*
  90.    Score King and Pawns versus King endings.
  91. */
  92.  
  93. {
  94. register short s,r;
  95.   
  96.   if (PieceCnt[winner] == 1) s = 50; else s = 120;
  97.   if (winner == white)
  98.     {
  99.       if (side == loser) r = row[sq]-1; else r = row[sq];
  100.       if (row[king2] >= r && distance(sq,king2) < 8-r) s += 10*row[sq];
  101.       else s = 500+50*row[sq];
  102.       if (row[sq] < 6) sq += 16; else sq += 8;
  103.     }
  104.   else
  105.     {
  106.       if (side == loser) r = row[sq]+1; else r = row[sq];
  107.       if (row[king2] <= r && distance(sq,king2) < r+1) s += 10*(7-row[sq]);
  108.       else s = 500+50*(7-row[sq]);
  109.       if (row[sq] > 1) sq -= 16; else sq -= 8;
  110.     }
  111.   s += 8*(taxicab(king2,sq) - taxicab(king1,sq));
  112.   return(s);
  113. }
  114.  
  115.  
  116. int ScoreKBNK(winner,king1,king2)
  117. short winner,king1,king2;
  118.  
  119. /*
  120.    Score King+Bishop+Knight versus King endings.
  121.    This doesn't work all that well but it's better than nothing.
  122. */
  123.  
  124. {
  125. register short s;
  126.   s = emtl[winner] - 300;
  127.   if (KBNKsq == 0) s += KBNK[king2];
  128.   else s += KBNK[locn[row[king2]][7-column[king2]]];
  129.   s -= taxicab(king1,king2);
  130.   s -= distance(PieceList[winner][1],king2);
  131.   s -= distance(PieceList[winner][2],king2);
  132.   return(s);
  133. }
  134.  
  135.  
  136. SqValue(sq,side)
  137. short sq,side;
  138.  
  139. /*
  140.    Calculate the positional value for the piece on 'sq'.
  141. */
  142.  
  143. {
  144. register short j,fyle,rank,a1,a2;
  145. short s,piece,in_square,r,mob,e,c;
  146.  
  147.   piece = board[sq];
  148.   a1 = (atk1[sq] & 0x4FFF); a2 = (atk2[sq] & 0x4FFF);
  149.   rank = row[sq]; fyle = column[sq];
  150.   s = 0;
  151.   if (piece == pawn && c1 == white)
  152.     {
  153.       s = Mwpawn[sq];
  154.       if (sq == 11 || sq == 12)
  155.         if (color[sq+8] != neutral) s += PEDRNK2B;
  156.       if ((fyle == 0 || PC1[fyle-1] == 0) &&
  157.           (fyle == 7 || PC1[fyle+1] == 0))
  158.         s += ISOLANI[fyle];
  159.       else if (PC1[fyle] > 1) s += PDOUBLED;
  160.       if (a1 < ctlP && atk1[sq+8] < ctlP)
  161.         {
  162.           s += BACKWARD[a2 & 0xFF];
  163.           if (PC2[fyle] == 0) s += PWEAKH;
  164.           if (color[sq+8] != neutral) s += PBLOK;
  165.         }
  166.       if (PC2[fyle] == 0)
  167.         {
  168.           if (side == black) r = rank-1; else r = rank;
  169.           in_square = (row[bking] >= r && distance(sq,bking) < 8-r);
  170.           if (a2 == 0 || side == white) e = 0; else e = 1;
  171.           for (j = sq+8; j < 64; j += 8)
  172.             if (atk2[j] >= ctlP) { e = 2; break; }
  173.             else if (atk2[j] > 0 || color[j] != neutral) e = 1;
  174.           if (e == 2) s += (stage*PassedPawn3[rank]) / 10;
  175.           else if (in_square || e == 1) s += (stage*PassedPawn2[rank]) / 10;
  176.           else if (emtl[black] > 0) s += (stage*PassedPawn1[rank]) / 10;
  177.           else s += PassedPawn0[rank];
  178.         }
  179.     }
  180.   else if (piece == pawn && c1 == black)
  181.     {
  182.       s = Mbpawn[sq];
  183.       if (sq == 51 || sq == 52)
  184.         if (color[sq-8] != neutral) s += PEDRNK2B;
  185.       if ((fyle == 0 || PC1[fyle-1] == 0) &&
  186.           (fyle == 7 || PC1[fyle+1] == 0))
  187.         s += ISOLANI[fyle];
  188.       else if (PC1[fyle] > 1) s += PDOUBLED;
  189.       if (a1 < ctlP && atk1[sq-8] < ctlP)
  190.         {
  191.           s += BACKWARD[a2 & 0xFF];
  192.           if (PC2[fyle] == 0) s += PWEAKH;
  193.           if (color[sq-8] != neutral) s += PBLOK;
  194.         }
  195.       if (PC2[fyle] == 0)
  196.         {
  197.           if (side == white) r = rank+1; else r = rank;
  198.           in_square = (row[wking] <= r && distance(sq,wking) < r+1);
  199.           if (a2 == 0 || side == black) e = 0; else e = 1;
  200.           for (j = sq-8; j >= 0; j -= 8)
  201.             if (atk2[j] >= ctlP) { e = 2; break; }
  202.             else if (atk2[j] > 0 || color[j] != neutral) e = 1;
  203.           if (e == 2) s += (stage*PassedPawn3[7-rank]) / 10;
  204.           else if (in_square || e == 1) s += (stage*PassedPawn2[7-rank]) / 10;
  205.           else if (emtl[white] > 0) s += (stage*PassedPawn1[7-rank]) / 10;
  206.           else s += PassedPawn0[7-rank];
  207.         }
  208.     }
  209.   else if (piece == knight)
  210.     {
  211.       s = Mknight[c1][sq];
  212.     }
  213.   else if (piece == bishop)
  214.     {
  215.       s = Mbishop[c1][sq];
  216.       BRscan(sq,&s,&mob);
  217.       s += BMBLTY[mob];
  218.     }
  219.   else if (piece == rook)
  220.     {
  221.       s += RookBonus;
  222.       BRscan(sq,&s,&mob);
  223.       s += RMBLTY[mob];
  224.       if (PC1[fyle] == 0) s += RHOPN;
  225.       if (PC2[fyle] == 0) s += RHOPNX;
  226.       if (rank == rank7[c1] && pmtl[c2] > 100) s += 10;
  227.       if (stage > 2) s += 14 - taxicab(sq,EnemyKing);
  228.     }
  229.   else if (piece == queen)
  230.     {
  231.       if (stage > 2) s += 14 - taxicab(sq,EnemyKing);
  232.       if (distance(sq,EnemyKing) < 3) s += 12;
  233.     }
  234.   else if (piece == king)
  235.     {
  236.       s = Mking[c1][sq];
  237.       if (KSFTY > 0)
  238.         if (Developed[c2] || stage > 0) KingScan(sq,&s);
  239.       if (castld[c1]) s += KCASTLD;
  240.       else if (kingmoved[c1]) s += KMOVD;
  241.  
  242.       if (PC1[fyle] == 0) s += KHOPN;
  243.       if (PC2[fyle] == 0) s += KHOPNX;
  244.       if (fyle == 1 || fyle == 2 || fyle == 3 || fyle == 7)
  245.         {
  246.           if (PC1[fyle-1] == 0) s += KHOPN;
  247.           if (PC2[fyle-1] == 0) s += KHOPNX;
  248.         }
  249.       if (fyle == 4 || fyle == 5 || fyle == 6 || fyle == 0)
  250.         {
  251.           if (PC1[fyle+1] == 0) s += KHOPN;
  252.           if (PC2[fyle+1] == 0) s += KHOPNX;
  253.         }
  254.       if (fyle == 2)
  255.         {
  256.           if (PC1[0] == 0) s += KHOPN;
  257.           if (PC2[0] == 0) s += KHOPNX;
  258.         }
  259.       if (fyle == 5)
  260.         {
  261.           if (PC1[7] == 0) s += KHOPN;
  262.           if (PC2[7] == 0) s += KHOPNX;
  263.         }
  264.     }
  265.     
  266.   if (a2 > 0) 
  267.     {
  268.       c = (control[piece] & 0x4FFF);
  269.       if (a1 == 0 || a2 > c+1)
  270.         {
  271.           s += HUNGP;
  272.           ++hung[c1];
  273.           if (piece != king && trapped(sq,piece)) ++hung[c1];
  274.         }
  275.       else if (piece != pawn || a2 > a1)
  276.         if (a2 >= c || a1 < ctlP) s += ATAKD;
  277.     }
  278.   return(s);
  279. }
  280.  
  281.  
  282. KingScan(sq,s)
  283. short sq,*s;
  284.  
  285. /*
  286.    Assign penalties if king can be threatened by checks, if squares
  287.    near the king are controlled by the enemy (especially the queen),
  288.    or if there are no pawns near the king.
  289. */
  290.  
  291. #define ScoreThreat\
  292.   if (color[u] != c2)\
  293.     if (atk1[u] == 0 || (atk2[u] & 0xFF) > 1) ++cnt;\
  294.     else *s -= 3
  295.  
  296. {
  297. register short m,u,d,i,m0,cnt,ok;
  298.  
  299.   cnt = 0;
  300.   m0 = map[sq];
  301.   if (HasBishop[c2] || HasQueen[c2])
  302.     for (i = Dstart[bishop]; i <= Dstop[bishop]; i++)
  303.       {
  304.         d = Dir[i]; m = m0+d;
  305.         while (!(m & 0x88))
  306.           {
  307.             u = unmap[m];
  308.             if (atk2[u] & ctlBQ) ScoreThreat;
  309.             if (color[u] != neutral) break;
  310.             m += d;
  311.           }
  312.       }
  313.   if (HasRook[c2] || HasQueen[c2])
  314.     for (i = Dstart[rook]; i <= Dstop[rook]; i++)
  315.       {
  316.         d = Dir[i]; m = m0+d;
  317.         while (!(m & 0x88))
  318.           {
  319.             u = unmap[m];
  320.             if (atk2[u] & ctlRQ) ScoreThreat;
  321.             if (color[u] != neutral) break;
  322.             m += d;
  323.           }
  324.       }
  325.   if (HasKnight[c2])
  326.     for (i = Dstart[knight]; i <= Dstop[knight]; i++)
  327.       if (!((m = m0+Dir[i]) & 0x88))
  328.         {
  329.           u = unmap[m];
  330.           if (atk2[u] & ctlNN) ScoreThreat;
  331.         }
  332.   *s += (KSFTY*Kthreat[cnt]) / 16;
  333.  
  334.   cnt = 0; ok = false;
  335.   m0 = map[sq];
  336.   for (i = Dstart[king]; i <= Dstop[king]; i++)
  337.     if (!((m = m0+Dir[i]) & 0x88))
  338.       {
  339.         u = unmap[m];
  340.         if (board[u] == pawn) ok = true;
  341.         if (atk2[u] > atk1[u])
  342.           {
  343.             ++cnt;
  344.             if (atk2[u] & ctlQ)
  345.               if (atk2[u] > ctlQ+1 && atk1[u] < ctlQ) *s -= 4*KSFTY;
  346.           }
  347.       }
  348.   if (!ok) *s -= KSFTY;
  349.   if (cnt > 1) *s -= KSFTY;
  350. }
  351.  
  352.  
  353. BRscan(sq,s,mob)
  354. short sq,*s,*mob;
  355.  
  356. /*
  357.    Find Bishop and Rook mobility, XRAY attacks, and pins. Increment the 
  358.    hung[] array if a pin is found. 
  359. */
  360.  
  361. {
  362. register short m,u,d,m0,j,piece,pin;
  363. short *Kf; 
  364.  
  365.   Kf = Kfield[c1];
  366.   *mob = 0;
  367.   m0 = map[sq]; piece = board[sq];
  368.   for (j = Dstart[piece]; j <= Dstop[piece]; j++)
  369.     {
  370.       pin = -1;
  371.       d = Dir[j]; m = m0+d;
  372.       while (!(m & 0x88))
  373.         {
  374.           u = unmap[m]; *s += Kf[u];
  375.           if (color[u] == neutral)
  376.             {
  377.               (*mob)++;
  378.               m += d;
  379.             }
  380.           else if (pin < 0)
  381.             {
  382.               if (board[u] == pawn || board[u] == king) break;
  383.               pin = u;
  384.               m += d;
  385.             }
  386.           else if (color[u] == c2 && (board[u] > piece || atk2[u] == 0))
  387.             {
  388.               if (color[pin] == c2)
  389.                 {
  390.                   *s += PINVAL;
  391.                   if (atk2[pin] == 0 ||
  392.                       atk1[pin] > control[board[pin]]+1)
  393.                     ++hung[c2];
  394.                 }
  395.               else *s += XRAY;
  396.               break;
  397.             }
  398.           else break;
  399.         }
  400.     }
  401. }
  402.  
  403.  
  404. int trapped(sq,piece)
  405. short sq,piece;
  406.  
  407. /*
  408.    See if the attacked piece has unattacked squares to move to.
  409. */
  410.  
  411. {
  412. register short u,m,d,i,m0;
  413.  
  414.   m0 = map[sq];
  415.   if (sweep[piece])
  416.     for (i = Dstart[piece]; i <= Dstop[piece]; i++)
  417.       {
  418.         d = Dir[i]; m = m0+d;
  419.         while (!(m & 0x88))
  420.           {
  421.             u = unmap[m];
  422.             if (color[u] == c1) break;
  423.             if (atk2[u] == 0 || board[u] >= piece) return(false);
  424.             if (color[u] == c2) break;
  425.             m += d;
  426.           }
  427.       }
  428.   else if (piece == pawn)
  429.     {
  430.       if (c1 == white) u = sq+8; else u = sq-8;
  431.       if (color[u] == neutral && atk1[u] >= atk2[u])
  432.         return(false);
  433.       if (!((m = m0+Dir[Dpwn[c1]]) & 0x88))
  434.         if (color[unmap[m]] == c2) return(false);
  435.       if (!((m = m0+Dir[Dpwn[c1]+1]) & 0x88))
  436.         if (color[unmap[m]] == c2) return(false);
  437.     }
  438.   else
  439.     {
  440.       for (i = Dstart[piece]; i <= Dstop[piece]; i++)
  441.         if (!((m = m0+Dir[i]) & 0x88))
  442.           {
  443.             u = unmap[m];
  444.             if (color[u] != c1)
  445.               if (atk2[u] == 0 || board[u] >= piece) return(false);
  446.           }
  447.     }
  448.   return(true);
  449. }
  450.  
  451.  
  452. ExaminePosition()
  453.  
  454. /*
  455.    This is done one time before the search is started. Set up arrays 
  456.    Mwpawn, Mbpawn, Mknight, Mbishop, Mking which are used in the 
  457.    SqValue() function to determine the positional value of each piece. 
  458. */
  459.  
  460. {
  461. register short i,sq;
  462. short wpadv,bpadv,wstrong,bstrong,z,side,pp,j,val,Pd,fyle,rank;
  463.  
  464.   wking = PieceList[white][0]; bking = PieceList[black][0];
  465.   ataks(white,atak[white]); ataks(black,atak[black]);
  466.   Zwmtl = Zbmtl = 0;
  467.   UpdateWeights();
  468.   HasPawn[white] = HasPawn[black] = 0;
  469.   HasKnight[white] = HasKnight[black] = 0;
  470.   HasBishop[white] = HasBishop[black] = 0;
  471.   HasRook[white] = HasRook[black] = 0;
  472.   HasQueen[white] = HasQueen[black] = 0;
  473.   for (side = white; side <= black; side++)
  474.     for (i = 0; i <= PieceCnt[side]; i++)
  475.       switch (board[PieceList[side][i]])
  476.         {
  477.           case pawn : ++HasPawn[side]; break;
  478.           case knight : ++HasKnight[side]; break;
  479.           case bishop : ++HasBishop[side]; break;
  480.           case rook : ++HasRook[side]; break;
  481.           case queen : ++HasQueen[side]; break;
  482.         }
  483.   if (!Developed[white])
  484.     Developed[white] = (board[1] != knight && board[2] != bishop &&
  485.                         board[5] != bishop && board[6] != knight);
  486.   if (!Developed[black])
  487.     Developed[black] = (board[57] != knight && board[58] != bishop &&
  488.                         board[61] != bishop && board[62] != knight);
  489.   if (!PawnStorm && stage < 5)
  490.     PawnStorm = ((column[wking] < 3 && column[bking] > 4) ||
  491.                  (column[wking] > 4 && column[bking] < 3));
  492.   
  493.   CopyBoard(pknight,Mknight[white]);
  494.   CopyBoard(pknight,Mknight[black]);
  495.   CopyBoard(pbishop,Mbishop[white]);
  496.   CopyBoard(pbishop,Mbishop[black]);
  497.   BlendBoard(KingOpening,KingEnding,Mking[white]);
  498.   BlendBoard(KingOpening,KingEnding,Mking[black]);
  499.   
  500.   for (sq = 0; sq < 64; sq++)
  501.     {
  502.       fyle = column[sq]; rank = row[sq];
  503.       wstrong = bstrong = true;
  504.       for (i = sq; i < 64; i += 8)
  505.         if (atak[black][i] >= ctlP) wstrong = false;
  506.       for (i = sq; i >= 0; i -= 8)
  507.         if (atak[white][i] >= ctlP) bstrong = false;
  508.       wpadv = bpadv = PADVNCM;
  509.       if ((fyle == 0 || PawnCnt[white][fyle-1] == 0) &&
  510.           (fyle == 7 || PawnCnt[white][fyle+1] == 0)) wpadv = PADVNCI;
  511.       if ((fyle == 0 || PawnCnt[black][fyle-1] == 0) &&
  512.           (fyle == 7 || PawnCnt[black][fyle+1] == 0)) bpadv = PADVNCI;
  513.       Mwpawn[sq] = (wpadv*PawnAdvance[sq]) / 10;
  514.       Mbpawn[sq] = (bpadv*PawnAdvance[63-sq]) / 10;
  515.       Mwpawn[sq] += PawnBonus; Mbpawn[sq] += PawnBonus;
  516.       if (castld[white] || kingmoved[white])
  517.         {
  518.           if ((fyle < 3 || fyle > 4) && distance(sq,wking) < 3)
  519.             Mwpawn[sq] += PAWNSHIELD;
  520.         }
  521.       else if (rank < 3 && (fyle < 2 || fyle > 5))
  522.         Mwpawn[sq] += PAWNSHIELD / 2;
  523.       if (castld[black] || kingmoved[black])
  524.         {
  525.           if ((fyle < 3 || fyle > 4) && distance(sq,bking) < 3)
  526.             Mbpawn[sq] += PAWNSHIELD;
  527.         }
  528.       else if (rank > 4 && (fyle < 2 || fyle > 5))
  529.         Mbpawn[sq] += PAWNSHIELD / 2;
  530.       if (PawnStorm)
  531.         {
  532.           if ((column[wking] < 4 && fyle > 4) ||
  533.               (column[wking] > 3 && fyle < 3)) Mwpawn[sq] += 3*rank - 21;
  534.           if ((column[bking] < 4 && fyle > 4) ||
  535.               (column[bking] > 3 && fyle < 3)) Mbpawn[sq] -= 3*rank;
  536.         }
  537.         
  538.       Mknight[white][sq] += 5 - distance(sq,bking);
  539.       Mknight[white][sq] += 5 - distance(sq,wking);
  540.       Mknight[black][sq] += 5 - distance(sq,wking);
  541.       Mknight[black][sq] += 5 - distance(sq,bking);
  542.       Mbishop[white][sq] += BishopBonus;
  543.       Mbishop[black][sq] += BishopBonus;
  544.       for (i = 0; i <= PieceCnt[black]; i++)
  545.         if (distance(sq,PieceList[black][i]) < 3)
  546.           Mknight[white][sq] += KNIGHTPOST;
  547.       for (i = 0; i <= PieceCnt[white]; i++)
  548.         if (distance(sq,PieceList[white][i]) < 3)
  549.           Mknight[black][sq] += KNIGHTPOST;
  550.       if (wstrong) Mknight[white][sq] += KNIGHTSTRONG;
  551.       if (bstrong) Mknight[black][sq] += KNIGHTSTRONG;
  552.       if (wstrong) Mbishop[white][sq] += BISHOPSTRONG;
  553.       if (bstrong) Mbishop[black][sq] += BISHOPSTRONG;
  554.       
  555.       if (HasBishop[white] == 2) Mbishop[white][sq] += 8;
  556.       if (HasBishop[black] == 2) Mbishop[black][sq] += 8;
  557.       if (HasKnight[white] == 2) Mknight[white][sq] += 5;
  558.       if (HasKnight[black] == 2) Mknight[black][sq] += 5;
  559.       
  560.       if (board[sq] == bishop)
  561.         if (rank % 2 == fyle % 2) KBNKsq = 0; else KBNKsq = 7;
  562.         
  563.       Kfield[white][sq] = Kfield[black][sq] = 0;
  564.       if (distance(sq,wking) == 1) Kfield[black][sq] = KATAK;
  565.       if (distance(sq,bking) == 1) Kfield[white][sq] = KATAK;
  566.       
  567.       Pd = 0;
  568.       for (i = 0; i < 64; i++)
  569.         if (board[i] == pawn)
  570.           {
  571.             if (color[i] == white)
  572.               {
  573.                 pp = true;
  574.                 if (row[i] == 6) z = i+8; else z = i+16;
  575.                 for (j = i+8; j < 64; j += 8)
  576.                   if (atak[black][j] > ctlP || board[j] == pawn) pp = false;
  577.               }
  578.             else
  579.               {
  580.                 pp = true;
  581.                 if (row[i] == 1) z = i-8; else z = i-16;
  582.                 for (j = i-8; j >= 0; j -= 8)
  583.                   if (atak[white][j] > ctlP || board[j] == pawn) pp = false;
  584.               }
  585.             if (pp) Pd += 5*taxicab(sq,z); else Pd += taxicab(sq,z);
  586.           }
  587.       if (Pd != 0)
  588.         {
  589.           val = (Pd*stage2) / 10;
  590.           Mking[white][sq] -= val;
  591.           Mking[black][sq] -= val;
  592.         }
  593.     }
  594. }
  595.  
  596.  
  597. UpdateWeights()
  598.  
  599. /* 
  600.    If material balance has changed, determine the values for the 
  601.    positional evaluation terms. 
  602. */
  603.  
  604. {
  605. register short tmtl;
  606.  
  607.   if (mtl[white] != Zwmtl || mtl[black] != Zbmtl)
  608.     {
  609.       Zwmtl = mtl[white]; Zbmtl = mtl[black];
  610.       emtl[white] = Zwmtl - pmtl[white] - valueK;
  611.       emtl[black] = Zbmtl - pmtl[black] - valueK;
  612.       tmtl = emtl[white] + emtl[black];
  613.       if (tmtl > 6600) stage = 0;
  614.       else if (tmtl < 1400) stage = 10;
  615.       else stage = (6600-tmtl) / 520;
  616.       if (tmtl > 3600) stage2 = 0;
  617.       else if (tmtl < 1400) stage2 = 10;
  618.       else stage2 = (3600-tmtl) / 220;
  619.       
  620.       PEDRNK2B = -15;         /* centre pawn on 2nd rank & blocked */
  621.       PBLOK = -4;             /* blocked backward pawn */
  622.       PDOUBLED = -14;         /* doubled pawn */
  623.       PWEAKH  = -4;           /* weak pawn on half open file */
  624.       PAWNSHIELD = 10-stage;  /* pawn near friendly king */
  625.       PADVNCM =  10;          /* advanced pawn multiplier */
  626.       PADVNCI = 7;            /* muliplier for isolated pawn */
  627.       PawnBonus = stage;
  628.       
  629.       KNIGHTPOST = (stage+2)/3;   /* knight near enemy pieces */
  630.       KNIGHTSTRONG = (stage+6)/2; /* occupies pawn hole */
  631.       
  632.       BISHOPSTRONG = (stage+6)/2; /* occupies pawn hole */
  633.       BishopBonus = 2*stage;
  634.       
  635.       RHOPN    = 10;          /* rook on half open file */
  636.       RHOPNX   = 4;
  637.       RookBonus = 6*stage;
  638.       
  639.       XRAY     = 8;           /* Xray attack on piece */
  640.       PINVAL   = 10;          /* Pin */
  641.       
  642.       KHOPN    = (3*stage-30) / 2; /* king on half open file */
  643.       KHOPNX   = KHOPN / 2;
  644.       KCASTLD  = 10 - stage;
  645.       KMOVD    = -40 / (stage+1);  /* king moved before castling */
  646.       KATAK    = (10-stage) / 2;   /* B,R attacks near enemy king */
  647.       if (stage < 8) KSFTY = 16-2*stage; else KSFTY = 0;
  648.       
  649.       ATAKD    = -6;          /* defender > attacker */
  650.       HUNGP    = -8;          /* each hung piece */
  651.       HUNGX    = -12;         /* extra for >1 hung piece */
  652.     }
  653. }
  654.  
  655.  
  656. int distance(a,b)
  657. short a,b;
  658. {
  659. register short d1,d2;
  660.  
  661.   d1 = abs(column[a]-column[b]);
  662.   d2 = abs(row[a]-row[b]);
  663.   if (d1 > d2) return(d1); else return(d2);
  664. }
  665.  
  666.  
  667. BlendBoard(a,b,c)
  668. short a[64],b[64],c[64];
  669. {
  670. register int sq;
  671.   for (sq = 0; sq < 64; sq++)
  672.     c[sq] = (a[sq]*(10-stage) + b[sq]*stage) / 10;
  673. }
  674.  
  675.  
  676. CopyBoard(a,b)
  677. short a[64],b[64];
  678. {
  679. register int sq;
  680.   for (sq = 0; sq < 64; sq++)
  681.     b[sq] = a[sq];
  682. }
  683.