[comp.sources.games] v04i040: gnuchess2 - latest version of the GNU Chess program, Part04/04

games@tekred.TEK.COM (06/11/88)

Submitted by: John Stanback <jhs@hpltbm.HP.COM>
Comp.sources.games: Volume 4, Issue 40
Archive-name: gnuchess2/Part04


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 4 (of 4)."
# Contents:  gnuchess.c2
# Wrapped by billr@saab on Fri Jun 10 17:01:32 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f gnuchess.c2 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"gnuchess.c2\"
else
echo shar: Extracting \"gnuchess.c2\" \(19818 characters\)
sed "s/^X//" >gnuchess.c2 <<'END_OF_gnuchess.c2'
X
X/* ............    POSITIONAL EVALUATION ROUTINES    ............ */
X
XScorePosition(side,score)
Xshort side,*score;
X
X/*
X   Perform normal static evaluation of board position. A score is 
X   generated for each piece and these are summed to get a score for each 
X   side. 
X*/
X
X{
Xregister short sq,s,i,xside;
Xshort pscore[3];
X
X  wking = PieceList[white][0]; bking = PieceList[black][0];
X  UpdateWeights();
X  xside = otherside[side];
X  pscore[white] = pscore[black] = 0;
X
X  for (c1 = white; c1 <= black; c1++)
X    {
X      c2 = otherside[c1];
X      if (c1 == white) EnemyKing = bking; else EnemyKing = wking;
X      atk1 = atak[c1]; atk2 = atak[c2];
X      PC1 = PawnCnt[c1]; PC2 = PawnCnt[c2];
X      for (i = 0; i <= PieceCnt[c1]; i++)
X        {
X          sq = PieceList[c1][i];
X          s = SqValue(sq,side);
X          pscore[c1] += s;
X          svalue[sq] = s;
X        }
X    }
X  if (hung[side] > 1) pscore[side] += HUNGX;
X  if (hung[xside] > 1) pscore[xside] += HUNGX;
X  
X  *score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10;
X  if (dither) *score += rand() % dither;
X  
X  if (*score > 0 && pmtl[side] == 0)
X    if (emtl[side] < valueR) *score = 0;
X    else if (*score < valueR) *score /= 2;
X  if (*score < 0 && pmtl[xside] == 0)
X    if (emtl[xside] < valueR) *score = 0;
X    else if (-*score < valueR) *score /= 2;
X    
X  if (mtl[xside] == valueK && emtl[side] > valueB) *score += 200;
X  if (mtl[side] == valueK && emtl[xside] > valueB) *score -= 200;
X}
X
X
XScoreLoneKing(side,score)
Xshort side,*score;
X
X/* 
X   Static evaluation when loser has only a king and winner has no pawns
X   or no pieces.
X*/
X
X{
Xregister short winner,loser,king1,king2,s,i;
X
X  UpdateWeights();
X  if (mtl[white] > mtl[black]) winner = white; else winner = black;
X  loser = otherside[winner];
X  king1 = PieceList[winner][0]; king2 = PieceList[loser][0];
X  
X  s = 0;
X  
X  if (pmtl[winner] > 0)
X    for (i = 1; i <= PieceCnt[winner]; i++)
X      s += ScoreKPK(side,winner,loser,king1,king2,PieceList[winner][i]);
X      
X  else if (emtl[winner] == valueB+valueN)
X    s = ScoreKBNK(winner,king1,king2);
X    
X  else if (emtl[winner] > valueB)
X    s = 500 + emtl[winner] - 2*KingEnding[king2] - 2*distance(king1,king2);
X    
X  if (side == winner) *score = s; else *score = -s;
X}
X
X
Xint ScoreKPK(side,winner,loser,king1,king2,sq)
Xshort side,winner,loser,king1,king2,sq;
X
X/*
X   Score King and Pawns versus King endings.
X*/
X
X{
Xregister short s,r;
X  
X  if (PieceCnt[winner] == 1) s = 50; else s = 120;
X  if (winner == white)
X    {
X      if (side == loser) r = row[sq]-1; else r = row[sq];
X      if (row[king2] >= r && distance(sq,king2) < 8-r) s += 10*row[sq];
X      else s = 500+50*row[sq];
X      if (row[sq] < 6) sq += 16; else sq += 8;
X    }
X  else
X    {
X      if (side == loser) r = row[sq]+1; else r = row[sq];
X      if (row[king2] <= r && distance(sq,king2) < r+1) s += 10*(7-row[sq]);
X      else s = 500+50*(7-row[sq]);
X      if (row[sq] > 1) sq -= 16; else sq -= 8;
X    }
X  s += 8*(taxicab(king2,sq) - taxicab(king1,sq));
X  return(s);
X}
X
X
Xint ScoreKBNK(winner,king1,king2)
Xshort winner,king1,king2;
X
X/*
X   Score King+Bishop+Knight versus King endings.
X   This doesn't work all that well but it's better than nothing.
X*/
X
X{
Xregister short s;
X  s = emtl[winner] - 300;
X  if (KBNKsq == 0) s += KBNK[king2];
X  else s += KBNK[locn[row[king2]][7-column[king2]]];
X  s -= taxicab(king1,king2);
X  s -= distance(PieceList[winner][1],king2);
X  s -= distance(PieceList[winner][2],king2);
X  return(s);
X}
X
X
XSqValue(sq,side)
Xshort sq,side;
X
X/*
X   Calculate the positional value for the piece on 'sq'.
X*/
X
X{
Xregister short j,fyle,rank,a1,a2;
Xshort s,piece,in_square,r,mob,e,c;
X
X  piece = board[sq];
X  a1 = (atk1[sq] & 0x4FFF); a2 = (atk2[sq] & 0x4FFF);
X  rank = row[sq]; fyle = column[sq];
X  s = 0;
X  if (piece == pawn && c1 == white)
X    {
X      s = Mwpawn[sq];
X      if (sq == 11 || sq == 12)
X        if (color[sq+8] != neutral) s += PEDRNK2B;
X      if ((fyle == 0 || PC1[fyle-1] == 0) &&
X          (fyle == 7 || PC1[fyle+1] == 0))
X        s += ISOLANI[fyle];
X      else if (PC1[fyle] > 1) s += PDOUBLED;
X      if (a1 < ctlP && atk1[sq+8] < ctlP)
X        {
X          s += BACKWARD[a2 & 0xFF];
X          if (PC2[fyle] == 0) s += PWEAKH;
X          if (color[sq+8] != neutral) s += PBLOK;
X        }
X      if (PC2[fyle] == 0)
X        {
X          if (side == black) r = rank-1; else r = rank;
X          in_square = (row[bking] >= r && distance(sq,bking) < 8-r);
X          if (a2 == 0 || side == white) e = 0; else e = 1;
X          for (j = sq+8; j < 64; j += 8)
X            if (atk2[j] >= ctlP) { e = 2; break; }
X            else if (atk2[j] > 0 || color[j] != neutral) e = 1;
X          if (e == 2) s += (stage*PassedPawn3[rank]) / 10;
X          else if (in_square || e == 1) s += (stage*PassedPawn2[rank]) / 10;
X          else if (emtl[black] > 0) s += (stage*PassedPawn1[rank]) / 10;
X          else s += PassedPawn0[rank];
X        }
X    }
X  else if (piece == pawn && c1 == black)
X    {
X      s = Mbpawn[sq];
X      if (sq == 51 || sq == 52)
X        if (color[sq-8] != neutral) s += PEDRNK2B;
X      if ((fyle == 0 || PC1[fyle-1] == 0) &&
X          (fyle == 7 || PC1[fyle+1] == 0))
X        s += ISOLANI[fyle];
X      else if (PC1[fyle] > 1) s += PDOUBLED;
X      if (a1 < ctlP && atk1[sq-8] < ctlP)
X        {
X          s += BACKWARD[a2 & 0xFF];
X          if (PC2[fyle] == 0) s += PWEAKH;
X          if (color[sq-8] != neutral) s += PBLOK;
X        }
X      if (PC2[fyle] == 0)
X        {
X          if (side == white) r = rank+1; else r = rank;
X          in_square = (row[wking] <= r && distance(sq,wking) < r+1);
X          if (a2 == 0 || side == black) e = 0; else e = 1;
X          for (j = sq-8; j >= 0; j -= 8)
X            if (atk2[j] >= ctlP) { e = 2; break; }
X            else if (atk2[j] > 0 || color[j] != neutral) e = 1;
X          if (e == 2) s += (stage*PassedPawn3[7-rank]) / 10;
X          else if (in_square || e == 1) s += (stage*PassedPawn2[7-rank]) / 10;
X          else if (emtl[white] > 0) s += (stage*PassedPawn1[7-rank]) / 10;
X          else s += PassedPawn0[7-rank];
X        }
X    }
X  else if (piece == knight)
X    {
X      s = Mknight[c1][sq];
X    }
X  else if (piece == bishop)
X    {
X      s = Mbishop[c1][sq];
X      BRscan(sq,&s,&mob);
X      s += BMBLTY[mob];
X    }
X  else if (piece == rook)
X    {
X      s += RookBonus;
X      BRscan(sq,&s,&mob);
X      s += RMBLTY[mob];
X      if (PC1[fyle] == 0) s += RHOPN;
X      if (PC2[fyle] == 0) s += RHOPNX;
X      if (rank == rank7[c1] && pmtl[c2] > 100) s += 10;
X      if (stage > 2) s += 14 - taxicab(sq,EnemyKing);
X    }
X  else if (piece == queen)
X    {
X      if (stage > 2) s += 14 - taxicab(sq,EnemyKing);
X      if (distance(sq,EnemyKing) < 3) s += 12;
X    }
X  else if (piece == king)
X    {
X      s = Mking[c1][sq];
X      if (KSFTY > 0)
X        if (Developed[c2] || stage > 0) KingScan(sq,&s);
X      if (castld[c1]) s += KCASTLD;
X      else if (kingmoved[c1]) s += KMOVD;
X
X      if (PC1[fyle] == 0) s += KHOPN;
X      if (PC2[fyle] == 0) s += KHOPNX;
X      if (fyle == 1 || fyle == 2 || fyle == 3 || fyle == 7)
X        {
X          if (PC1[fyle-1] == 0) s += KHOPN;
X          if (PC2[fyle-1] == 0) s += KHOPNX;
X        }
X      if (fyle == 4 || fyle == 5 || fyle == 6 || fyle == 0)
X        {
X          if (PC1[fyle+1] == 0) s += KHOPN;
X          if (PC2[fyle+1] == 0) s += KHOPNX;
X        }
X      if (fyle == 2)
X        {
X          if (PC1[0] == 0) s += KHOPN;
X          if (PC2[0] == 0) s += KHOPNX;
X        }
X      if (fyle == 5)
X        {
X          if (PC1[7] == 0) s += KHOPN;
X          if (PC2[7] == 0) s += KHOPNX;
X        }
X    }
X    
X  if (a2 > 0) 
X    {
X      c = (control[piece] & 0x4FFF);
X      if (a1 == 0 || a2 > c+1)
X        {
X          s += HUNGP;
X          ++hung[c1];
X          if (piece != king && trapped(sq,piece)) ++hung[c1];
X        }
X      else if (piece != pawn || a2 > a1)
X        if (a2 >= c || a1 < ctlP) s += ATAKD;
X    }
X  return(s);
X}
X
X
XKingScan(sq,s)
Xshort sq,*s;
X
X/*
X   Assign penalties if king can be threatened by checks, if squares
X   near the king are controlled by the enemy (especially the queen),
X   or if there are no pawns near the king.
X*/
X
X#define ScoreThreat\
X  if (color[u] != c2)\
X    if (atk1[u] == 0 || (atk2[u] & 0xFF) > 1) ++cnt;\
X    else *s -= 3
X
X{
Xregister short m,u,d,i,m0,cnt,ok;
X
X  cnt = 0;
X  m0 = map[sq];
X  if (HasBishop[c2] || HasQueen[c2])
X    for (i = Dstart[bishop]; i <= Dstop[bishop]; i++)
X      {
X        d = Dir[i]; m = m0+d;
X        while (!(m & 0x88))
X          {
X            u = unmap[m];
X            if (atk2[u] & ctlBQ) ScoreThreat;
X            if (color[u] != neutral) break;
X            m += d;
X          }
X      }
X  if (HasRook[c2] || HasQueen[c2])
X    for (i = Dstart[rook]; i <= Dstop[rook]; i++)
X      {
X        d = Dir[i]; m = m0+d;
X        while (!(m & 0x88))
X          {
X            u = unmap[m];
X            if (atk2[u] & ctlRQ) ScoreThreat;
X            if (color[u] != neutral) break;
X            m += d;
X          }
X      }
X  if (HasKnight[c2])
X    for (i = Dstart[knight]; i <= Dstop[knight]; i++)
X      if (!((m = m0+Dir[i]) & 0x88))
X        {
X          u = unmap[m];
X          if (atk2[u] & ctlNN) ScoreThreat;
X        }
X  *s += (KSFTY*Kthreat[cnt]) / 16;
X
X  cnt = 0; ok = false;
X  m0 = map[sq];
X  for (i = Dstart[king]; i <= Dstop[king]; i++)
X    if (!((m = m0+Dir[i]) & 0x88))
X      {
X        u = unmap[m];
X        if (board[u] == pawn) ok = true;
X        if (atk2[u] > atk1[u])
X          {
X            ++cnt;
X            if (atk2[u] & ctlQ)
X              if (atk2[u] > ctlQ+1 && atk1[u] < ctlQ) *s -= 4*KSFTY;
X          }
X      }
X  if (!ok) *s -= KSFTY;
X  if (cnt > 1) *s -= KSFTY;
X}
X
X
XBRscan(sq,s,mob)
Xshort sq,*s,*mob;
X
X/*
X   Find Bishop and Rook mobility, XRAY attacks, and pins. Increment the 
X   hung[] array if a pin is found. 
X*/
X
X{
Xregister short m,u,d,m0,j,piece,pin;
Xshort *Kf; 
X
X  Kf = Kfield[c1];
X  *mob = 0;
X  m0 = map[sq]; piece = board[sq];
X  for (j = Dstart[piece]; j <= Dstop[piece]; j++)
X    {
X      pin = -1;
X      d = Dir[j]; m = m0+d;
X      while (!(m & 0x88))
X        {
X          u = unmap[m]; *s += Kf[u];
X          if (color[u] == neutral)
X            {
X              (*mob)++;
X              m += d;
X            }
X          else if (pin < 0)
X            {
X              if (board[u] == pawn || board[u] == king) break;
X              pin = u;
X              m += d;
X            }
X          else if (color[u] == c2 && (board[u] > piece || atk2[u] == 0))
X            {
X              if (color[pin] == c2)
X                {
X                  *s += PINVAL;
X                  if (atk2[pin] == 0 ||
X                      atk1[pin] > control[board[pin]]+1)
X                    ++hung[c2];
X                }
X              else *s += XRAY;
X              break;
X            }
X          else break;
X        }
X    }
X}
X
X
Xint trapped(sq,piece)
Xshort sq,piece;
X
X/*
X   See if the attacked piece has unattacked squares to move to.
X*/
X
X{
Xregister short u,m,d,i,m0;
X
X  m0 = map[sq];
X  if (sweep[piece])
X    for (i = Dstart[piece]; i <= Dstop[piece]; i++)
X      {
X        d = Dir[i]; m = m0+d;
X        while (!(m & 0x88))
X          {
X            u = unmap[m];
X            if (color[u] == c1) break;
X            if (atk2[u] == 0 || board[u] >= piece) return(false);
X            if (color[u] == c2) break;
X            m += d;
X          }
X      }
X  else if (piece == pawn)
X    {
X      if (c1 == white) u = sq+8; else u = sq-8;
X      if (color[u] == neutral && atk1[u] >= atk2[u])
X        return(false);
X      if (!((m = m0+Dir[Dpwn[c1]]) & 0x88))
X        if (color[unmap[m]] == c2) return(false);
X      if (!((m = m0+Dir[Dpwn[c1]+1]) & 0x88))
X        if (color[unmap[m]] == c2) return(false);
X    }
X  else
X    {
X      for (i = Dstart[piece]; i <= Dstop[piece]; i++)
X        if (!((m = m0+Dir[i]) & 0x88))
X          {
X            u = unmap[m];
X            if (color[u] != c1)
X              if (atk2[u] == 0 || board[u] >= piece) return(false);
X          }
X    }
X  return(true);
X}
X
X
XExaminePosition()
X
X/*
X   This is done one time before the search is started. Set up arrays 
X   Mwpawn, Mbpawn, Mknight, Mbishop, Mking which are used in the 
X   SqValue() function to determine the positional value of each piece. 
X*/
X
X{
Xregister short i,sq;
Xshort wpadv,bpadv,wstrong,bstrong,z,side,pp,j,val,Pd,fyle,rank;
X
X  wking = PieceList[white][0]; bking = PieceList[black][0];
X  ataks(white,atak[white]); ataks(black,atak[black]);
X  Zwmtl = Zbmtl = 0;
X  UpdateWeights();
X  HasPawn[white] = HasPawn[black] = 0;
X  HasKnight[white] = HasKnight[black] = 0;
X  HasBishop[white] = HasBishop[black] = 0;
X  HasRook[white] = HasRook[black] = 0;
X  HasQueen[white] = HasQueen[black] = 0;
X  for (side = white; side <= black; side++)
X    for (i = 0; i <= PieceCnt[side]; i++)
X      switch (board[PieceList[side][i]])
X        {
X          case pawn : ++HasPawn[side]; break;
X          case knight : ++HasKnight[side]; break;
X          case bishop : ++HasBishop[side]; break;
X          case rook : ++HasRook[side]; break;
X          case queen : ++HasQueen[side]; break;
X        }
X  if (!Developed[white])
X    Developed[white] = (board[1] != knight && board[2] != bishop &&
X                        board[5] != bishop && board[6] != knight);
X  if (!Developed[black])
X    Developed[black] = (board[57] != knight && board[58] != bishop &&
X                        board[61] != bishop && board[62] != knight);
X  if (!PawnStorm && stage < 5)
X    PawnStorm = ((column[wking] < 3 && column[bking] > 4) ||
X                 (column[wking] > 4 && column[bking] < 3));
X  
X  CopyBoard(pknight,Mknight[white]);
X  CopyBoard(pknight,Mknight[black]);
X  CopyBoard(pbishop,Mbishop[white]);
X  CopyBoard(pbishop,Mbishop[black]);
X  BlendBoard(KingOpening,KingEnding,Mking[white]);
X  BlendBoard(KingOpening,KingEnding,Mking[black]);
X  
X  for (sq = 0; sq < 64; sq++)
X    {
X      fyle = column[sq]; rank = row[sq];
X      wstrong = bstrong = true;
X      for (i = sq; i < 64; i += 8)
X        if (atak[black][i] >= ctlP) wstrong = false;
X      for (i = sq; i >= 0; i -= 8)
X        if (atak[white][i] >= ctlP) bstrong = false;
X      wpadv = bpadv = PADVNCM;
X      if ((fyle == 0 || PawnCnt[white][fyle-1] == 0) &&
X          (fyle == 7 || PawnCnt[white][fyle+1] == 0)) wpadv = PADVNCI;
X      if ((fyle == 0 || PawnCnt[black][fyle-1] == 0) &&
X          (fyle == 7 || PawnCnt[black][fyle+1] == 0)) bpadv = PADVNCI;
X      Mwpawn[sq] = (wpadv*PawnAdvance[sq]) / 10;
X      Mbpawn[sq] = (bpadv*PawnAdvance[63-sq]) / 10;
X      Mwpawn[sq] += PawnBonus; Mbpawn[sq] += PawnBonus;
X      if (castld[white] || kingmoved[white])
X        {
X          if ((fyle < 3 || fyle > 4) && distance(sq,wking) < 3)
X            Mwpawn[sq] += PAWNSHIELD;
X        }
X      else if (rank < 3 && (fyle < 2 || fyle > 5))
X        Mwpawn[sq] += PAWNSHIELD / 2;
X      if (castld[black] || kingmoved[black])
X        {
X          if ((fyle < 3 || fyle > 4) && distance(sq,bking) < 3)
X            Mbpawn[sq] += PAWNSHIELD;
X        }
X      else if (rank > 4 && (fyle < 2 || fyle > 5))
X        Mbpawn[sq] += PAWNSHIELD / 2;
X      if (PawnStorm)
X        {
X          if ((column[wking] < 4 && fyle > 4) ||
X              (column[wking] > 3 && fyle < 3)) Mwpawn[sq] += 3*rank - 21;
X          if ((column[bking] < 4 && fyle > 4) ||
X              (column[bking] > 3 && fyle < 3)) Mbpawn[sq] -= 3*rank;
X        }
X        
X      Mknight[white][sq] += 5 - distance(sq,bking);
X      Mknight[white][sq] += 5 - distance(sq,wking);
X      Mknight[black][sq] += 5 - distance(sq,wking);
X      Mknight[black][sq] += 5 - distance(sq,bking);
X      Mbishop[white][sq] += BishopBonus;
X      Mbishop[black][sq] += BishopBonus;
X      for (i = 0; i <= PieceCnt[black]; i++)
X        if (distance(sq,PieceList[black][i]) < 3)
X          Mknight[white][sq] += KNIGHTPOST;
X      for (i = 0; i <= PieceCnt[white]; i++)
X        if (distance(sq,PieceList[white][i]) < 3)
X          Mknight[black][sq] += KNIGHTPOST;
X      if (wstrong) Mknight[white][sq] += KNIGHTSTRONG;
X      if (bstrong) Mknight[black][sq] += KNIGHTSTRONG;
X      if (wstrong) Mbishop[white][sq] += BISHOPSTRONG;
X      if (bstrong) Mbishop[black][sq] += BISHOPSTRONG;
X      
X      if (HasBishop[white] == 2) Mbishop[white][sq] += 8;
X      if (HasBishop[black] == 2) Mbishop[black][sq] += 8;
X      if (HasKnight[white] == 2) Mknight[white][sq] += 5;
X      if (HasKnight[black] == 2) Mknight[black][sq] += 5;
X      
X      if (board[sq] == bishop)
X        if (rank % 2 == fyle % 2) KBNKsq = 0; else KBNKsq = 7;
X        
X      Kfield[white][sq] = Kfield[black][sq] = 0;
X      if (distance(sq,wking) == 1) Kfield[black][sq] = KATAK;
X      if (distance(sq,bking) == 1) Kfield[white][sq] = KATAK;
X      
X      Pd = 0;
X      for (i = 0; i < 64; i++)
X        if (board[i] == pawn)
X          {
X            if (color[i] == white)
X              {
X                pp = true;
X                if (row[i] == 6) z = i+8; else z = i+16;
X                for (j = i+8; j < 64; j += 8)
X                  if (atak[black][j] > ctlP || board[j] == pawn) pp = false;
X              }
X            else
X              {
X                pp = true;
X                if (row[i] == 1) z = i-8; else z = i-16;
X                for (j = i-8; j >= 0; j -= 8)
X                  if (atak[white][j] > ctlP || board[j] == pawn) pp = false;
X              }
X            if (pp) Pd += 5*taxicab(sq,z); else Pd += taxicab(sq,z);
X          }
X      if (Pd != 0)
X        {
X          val = (Pd*stage2) / 10;
X          Mking[white][sq] -= val;
X          Mking[black][sq] -= val;
X        }
X    }
X}
X
X
XUpdateWeights()
X
X/* 
X   If material balance has changed, determine the values for the 
X   positional evaluation terms. 
X*/
X
X{
Xregister short tmtl;
X
X  if (mtl[white] != Zwmtl || mtl[black] != Zbmtl)
X    {
X      Zwmtl = mtl[white]; Zbmtl = mtl[black];
X      emtl[white] = Zwmtl - pmtl[white] - valueK;
X      emtl[black] = Zbmtl - pmtl[black] - valueK;
X      tmtl = emtl[white] + emtl[black];
X      if (tmtl > 6600) stage = 0;
X      else if (tmtl < 1400) stage = 10;
X      else stage = (6600-tmtl) / 520;
X      if (tmtl > 3600) stage2 = 0;
X      else if (tmtl < 1400) stage2 = 10;
X      else stage2 = (3600-tmtl) / 220;
X      
X      PEDRNK2B = -15;         /* centre pawn on 2nd rank & blocked */
X      PBLOK = -4;             /* blocked backward pawn */
X      PDOUBLED = -14;         /* doubled pawn */
X      PWEAKH  = -4;           /* weak pawn on half open file */
X      PAWNSHIELD = 10-stage;  /* pawn near friendly king */
X      PADVNCM =  10;          /* advanced pawn multiplier */
X      PADVNCI = 7;            /* muliplier for isolated pawn */
X      PawnBonus = stage;
X      
X      KNIGHTPOST = (stage+2)/3;   /* knight near enemy pieces */
X      KNIGHTSTRONG = (stage+6)/2; /* occupies pawn hole */
X      
X      BISHOPSTRONG = (stage+6)/2; /* occupies pawn hole */
X      BishopBonus = 2*stage;
X      
X      RHOPN    = 10;          /* rook on half open file */
X      RHOPNX   = 4;
X      RookBonus = 6*stage;
X      
X      XRAY     = 8;           /* Xray attack on piece */
X      PINVAL   = 10;          /* Pin */
X      
X      KHOPN    = (3*stage-30) / 2; /* king on half open file */
X      KHOPNX   = KHOPN / 2;
X      KCASTLD  = 10 - stage;
X      KMOVD    = -40 / (stage+1);  /* king moved before castling */
X      KATAK    = (10-stage) / 2;   /* B,R attacks near enemy king */
X      if (stage < 8) KSFTY = 16-2*stage; else KSFTY = 0;
X      
X      ATAKD    = -6;          /* defender > attacker */
X      HUNGP    = -8;          /* each hung piece */
X      HUNGX    = -12;         /* extra for >1 hung piece */
X    }
X}
X
X
Xint distance(a,b)
Xshort a,b;
X{
Xregister short d1,d2;
X
X  d1 = abs(column[a]-column[b]);
X  d2 = abs(row[a]-row[b]);
X  if (d1 > d2) return(d1); else return(d2);
X}
X
X
XBlendBoard(a,b,c)
Xshort a[64],b[64],c[64];
X{
Xregister int sq;
X  for (sq = 0; sq < 64; sq++)
X    c[sq] = (a[sq]*(10-stage) + b[sq]*stage) / 10;
X}
X
X
XCopyBoard(a,b)
Xshort a[64],b[64];
X{
Xregister int sq;
X  for (sq = 0; sq < 64; sq++)
X    b[sq] = a[sq];
X}
END_OF_gnuchess.c2
if test 19818 -ne `wc -c <gnuchess.c2`; then
    echo shar: \"gnuchess.c2\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 4 \(of 4\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 4 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0