[comp.sources.games] v03i040: gnuchess - Technology Chess program for GNU Unix, Part03/03

games-request@tekred.TEK.COM (01/13/88)

Submitted by: Stuart Cracraft <cracraft@venera.isi.edu>
Comp.sources.games: Volume 3, Issue 40
Archive-name: gnuchess/Part03



#! /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 3 (of 3)."
# Contents:  gnuchess.c2
# Wrapped by billr@tekred on Tue Jan 12 11:56:43 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\" \(39696 characters\)
sed "s/^X//" >gnuchess.c2 <<'END_OF_gnuchess.c2'
XInitializeStats()
X{
Xregister short i,loc;
X  epsquare = -1;
X  for (i = 0; i < 8; i++)
X    PawnCnt[white][i] = PawnCnt[black][i] = 0;
X  mtl[white] = mtl[black] = pmtl[white] = pmtl[black] = 0;
X  PieceCnt[white] = PieceCnt[black] = 0;
X  hashbd = hashkey = 0;
X  for (loc = 0; loc < 64; loc++)
X    if (color[loc] != neutral)
X      {
X        mtl[color[loc]] += value[board[loc]];
X        if (board[loc] == pawn)
X          {
X            pmtl[color[loc]] += valueP;
X            ++PawnCnt[color[loc]][col[loc]];
X          }
X        if (board[loc] == king) Pindex[loc] = 0;
X          else Pindex[loc] = ++PieceCnt[color[loc]];
X        PieceList[color[loc]][Pindex[loc]] = loc;
X        hashbd ^= hashcode[color[loc]][board[loc]][loc].bd;
X        hashkey ^= hashcode[color[loc]][board[loc]][loc].key;
X      }
X}
X
X
Xsort(p1,p2)
Xshort p1,p2;
X{
Xregister short p,p0,s;
Xstruct leaf temp;
X
X  s = 32000;
X  while (p1 < p2)
X    if (Tree[p1].score >= s) p1++;
X    else
X      {
X        s = Tree[p1].score; p0 = p1;
X        for (p = p1+1; p <= p2; p++)
X          if (Tree[p].score > s)
X            {
X              s = Tree[p].score; p0 = p;
X            }
X        if (p0 != p1)
X          {
X            temp = Tree[p1]; Tree[p1] = Tree[p0]; Tree[p0] = temp;
X          }
X        p1++;
X      }
X}
X
X
Xrepetition(cnt)
Xshort *cnt;
X
X/*
X    Check for draw by threefold repetition.
X*/
X
X{
Xregister short i,f,t;
Xshort c,b[64];
Xunsigned short m;
X  *cnt = c = 0;
X  for (i = 0; i < 64; b[i++] = 0);
X/*
X  bzero((char *)b,sizeof(b));
X  memset((char *)b,0,64*sizeof(short));
X*/
X  for (i = GameCnt; i > Game50; i--)
X    {
X      m = GameList[i].gmove; f = m>>8; t = m & 0xFF;
X      if (++b[f] == 0) c--; else c++;
X      if (--b[t] == 0) c--; else c++;
X      if (c == 0) (*cnt)++;
X    }
X}
X
X
Xint SqAtakd(sq,side)
Xshort sq,side;
X
X/*
X  Generate moves from 'sq' for each piece and see if the appropriate
X  piece with color 'side' is encountered.
X*/
X
X{
Xregister short i,u,m,d;
Xshort m0;
X
X  m0 = map[sq];
X  
X  if (HasPawn[side])
X    {
X      d = Dpwn[otherside[side]];
X      for (i = d; i <= d+1; i++)
X        if ((u = unmap[m0+Dir[i]]) >= 0)
X          if (board[u] == pawn && color[u] == side) return(true);
X    }
X      
X  if (HasKnight[side])
X    for (i = 8; i <= 15; i++)
X      if ((u = unmap[m0+Dir[i]]) >= 0)
X        if (board[u] == knight && color[u] == side) return(true);
X      
X  if (HasRook[side] || HasQueen[side])
X    for (i = 0; i <= 3; i++)
X      {
X        d = Dir[i]; m = m0+d; u = unmap[m];
X        while (u >= 0)
X          if (color[u] == neutral)
X            {
X              m += d; u = unmap[m];
X            }
X          else if (color[u] == side && sweep1[board[u]]) return(true);
X          else break;
X      }
X    
X  if (HasBishop[side] || HasQueen[side])
X    for (i = 4; i <= 7; i++)
X      {
X        d = Dir[i]; m = m0+d; u = unmap[m];
X        while (u >= 0)
X          if (color[u] == neutral)
X            {
X              m += d; u = unmap[m];
X            }
X          else if (color[u] == side && sweep2[board[u]]) return(true);
X          else break;
X      }
X    
X  if (distance(sq,PieceList[side][0]) == 1) return(true);
X    
X  return(false);
X}
X
X
Xataks(side,a)
Xshort side,a[];
X
X/*
X    Fill array atak[][] with info about ataks to a square.  Bits 8-15
X    are set if the piece (king..pawn) ataks the square. Bits 0-7
X    contain a count of total ataks to the square.
X*/
X
X{
Xregister short u,m,d,c;
Xshort j,piece,i,m0,loc;
X 
X  for (u = 0; u < 64; a[u++] = 0);
X/*
X  memset((char *)a,0,64*sizeof(short));
X  bzero((char *)a,sizeof(a));
X*/
X  Dstart[pawn] = Dpwn[side]; Dstop[pawn] = Dstart[pawn] + 1;
X  for (i = 0; i <= PieceCnt[side]; i++)
X    {
X      loc = PieceList[side][i];
X      piece = board[loc]; m0 = map[loc]; c = control[piece];
X      if (sweep[piece])
X        for (j = Dstart[piece]; j <= Dstop[piece]; j++)
X          {
X            d = Dir[j]; m = m0+d; u = unmap[m];
X            while (u >= 0)
X              {
X                a[u] = ++a[u] | c;
X                if (color[u] == neutral)
X                  {
X                    m += d; u = unmap[m];
X                  }
X                else break;
X              }
X          }
X      else
X        for (j = Dstart[piece]; j <= Dstop[piece]; j++)
X          if ((u = unmap[m0+Dir[j]]) >= 0)
X            a[u] = ++a[u] | c;
X    }
X}
X
X  
Xint castle(side,kf,kt,iop)
Xshort side,kf,kt,iop;
X{
Xshort i,rf,rt,c1,c2,t0,xside;
X
X  xside = otherside[side];
X  if (kt > kf)
X    {
X      rf = kf+3; rt = kt-1; c1 = kf; c2 = rf;
X    }
X  else
X    {
X      rf = kf-4; rt = kt+1; c1 = rf; c2 = kf;
X    }
X  if (iop == 0)
X    {
X      if (board[kf] != king || board[rf] != rook || color[rf] != side)
X        return(false);
X      for (i = c1+1; i < c2; i++)
X        if (color[i] != neutral) return(false);
X      for (i = c1; i <= c2; i++)
X        if (SqAtakd(i,xside)) return(false); 
X    }
X  else
X    {
X      if (iop == 1) castld[side] = true; else castld[side] = false;
X      if (iop == 2)
X        {
X          t0 = kt; kt = kf; kf = t0;
X          t0 = rt; rt = rf; rf = t0;
X        }
X      board[kt] = king; color[kt] = side; Pindex[kt] = 0;
X      board[kf] = no_piece; color[kf] = neutral;
X      board[rt] = rook; color[rt] = side; Pindex[rt] = Pindex[rf];
X      board[rf] = no_piece; color[rf] = neutral;
X      PieceList[side][Pindex[kt]] = kt;
X      PieceList[side][Pindex[rt]] = rt;
X      UpdateHashbd(side,king,kf,kt);
X      UpdateHashbd(side,rook,rf,rt);
X    }
X  return(true);
X}
X
X
Xen_passant(xside,f,t,iop)
Xshort xside,f,t,iop;
X{
Xshort l;
X  if (t > f) l = t-8; else l = t+8;
X  if (iop == 1)
X    {
X      board[l] = no_piece; color[l] = neutral;
X    }
X  else 
X    {
X      board[l] = pawn; color[l] = xside;
X    }
X  InitializeStats();
X}
X
X
XLinkMove(ply,f,t,xside)
Xshort ply,f,t,xside;
X
X/*
X    Add a move to the tree.  Assign a bonus to order the moves
X    as follows:
X      1. Principle variation
X      2. Capture of last moved piece
X      3. Other captures (major pieces first)
X      4. Killer moves
X      5. "history" killers    
X*/
X
X{
Xregister short s;
Xregister unsigned short mv;
Xstruct leaf *node;
X
X  node = &Tree[TrPnt[ply+1]];
X  ++TrPnt[ply+1];
X  node->flags = node->reply = 0;
X  node->f = f; node->t = t; mv = (f<<8) + t;
X  s = 0;
X  if (mv == PV || mv == Swag0) s = 2000;
X  else if (mv == Swag1) s = 80;
X  else if (mv == Swag2) s = 70;
X  else if (mv == Swag3) s = 60;
X  else if (mv == Swag4) s = 40;
X  else if (mv == Swag5) s = 30;
X  if (color[t] != neutral)
X    {
X      node->flags |= capture;
X      if (t == TOsquare) s += 800;
X      s += value[board[t]] - board[f];
X    }
X  if (board[f] == pawn)
X    {
X      if (row[t] == 0 || row[t] == 7)
X        {
X          node->flags |= promote;
X          s += 500;
X        }
X      else if (row[t] == 1 || row[t] == 6)
X        {
X          node->flags |= pwnthrt;
X          s += 500;
X        }
X      else if (t == epsquare) node->flags |= epmask;
X    }
X  if (InChk)
X    {
X      if (board[f] == king)
X        if (SqAtakd(t,xside)) s -= 200; else s += 400;
X      if (mv == Qkillr[ply]) s += 200;
X    }
X  s += history[otherside[xside]-1][f][t];
X  node->score = s-20000;
X}
X
X
XGenMoves(ply,loc,side,xside)
Xshort ply,loc,side,xside;
X
X/*
X     Generate moves for a piece. The from square is mapped onto a 12 by 
X     12 board and offsets (taken from array Dir[]) are added to the 
X     mapped location. Array unmap[] maps the move back onto array 
X     board[] (yielding a value of -1 if the to square is off the board). 
X     This process is repeated for bishops, rooks, and queens until a 
X     piece is encountered or the the move falls off the board. Legal 
X     moves are then linked into the tree. 
X*/
X    
X{
Xregister short m,u,d;
Xshort i,m0,piece; 
X
X  piece = board[loc]; m0 = map[loc];
X  if (sweep[piece])
X    for (i = Dstart[piece]; i <= Dstop[piece]; i++)
X      {
X        d = Dir[i]; m = m0+d; u = unmap[m];
X        while (u >= 0)
X          if (color[u] == neutral)
X            {
X              LinkMove(ply,loc,u,xside);
X              m += d; u = unmap[m];
X            }
X          else if (color[u] == xside)
X            {
X              LinkMove(ply,loc,u,xside);
X              break;
X            }
X          else break;
X      }
X  else if (piece == pawn)
X    {
X      if (side == white && color[loc+8] == neutral)
X        {
X          LinkMove(ply,loc,loc+8,xside);
X          if (row[loc] == 1)
X            if (color[loc+16] == neutral)
X              LinkMove(ply,loc,loc+16,xside);
X        }
X      else if (side == black && color[loc-8] == neutral)
X        {
X          LinkMove(ply,loc,loc-8,xside);
X          if (row[loc] == 6)
X            if (color[loc-16] == neutral)
X              LinkMove(ply,loc,loc-16,xside);
X        }
X      for (i = Dstart[piece]; i <= Dstop[piece]; i++)
X        if ((u = unmap[m0+Dir[i]]) >= 0)
X          if (color[u] == xside || u == epsquare)
X            LinkMove(ply,loc,u,xside);
X    }
X  else
X    {
X      for (i = Dstart[piece]; i <= Dstop[piece]; i++)
X        if ((u = unmap[m0+Dir[i]]) >= 0)
X          if (color[u] != side)
X            LinkMove(ply,loc,u,xside);
X    }
X}
X
X
XMoveList(side,ply)
Xshort side,ply;
X
X/*
X    Fill the array Tree[] with all available moves for side to
X    play. Array TrPnt[ply] contains the index into Tree[]
X    of the first move at a ply.
X*/
X    
X{
Xregister short i;
Xshort xside,f;
X
X  xside = otherside[side];
X  Swag0 = killr0[ply]; Swag1 = killr1[ply]; Swag2 = killr2[ply];
X  Swag3 = killr3[ply]; Swag4 = Swag5 = 0;
X  if (ply > 2)
X    {
X      Swag4 = killr1[ply-2];
X      Swag5 = killr3[ply-2];
X    }
X  TrPnt[ply+1] = TrPnt[ply];
X  Dstart[pawn] = Dpwn[side]; Dstop[pawn] = Dstart[pawn] + 1;
X  for (i = PieceCnt[side]; i >= 0; i--)
X    GenMoves(ply,PieceList[side][i],side,xside);
X  if (kingmoved[side] == 0)
X    {
X      f = PieceList[side][0];
X      if (castle(side,f,f+2,0))
X        {
X          LinkMove(ply,f,f+2,xside);
X          Tree[TrPnt[ply+1]-1].flags |= cstlmask;
X        }
X      if (castle(side,f,f-2,0))
X        {
X          LinkMove(ply,f,f-2,xside);
X          Tree[TrPnt[ply+1]-1].flags |= cstlmask;
X        }
X    }
X  sort(TrPnt[ply],TrPnt[ply+1]-1);
X}
X
X
X#define LinkCapture\
X{\
X  node = &Tree[TrPnt[ply+1]];\
X  ++TrPnt[ply+1];\
X  node->f = loc; node->t = u;\
X  node->reply = 0;\
X  node->flags = capture;\
X  node->score = value[board[u]] + svalue[board[u]] - piece;\
X  if (piece == pawn && (u < 8 || u > 55))\
X    {\
X      node->flags |= promote;\
X      node->score = valueQ;\
X    }\
X}
X
X
XCaptureList(side,xside,ply)
Xshort side,xside,ply;
X
X/*
X    Generate a list of captures similiarly to GenMoves.
X*/
X
X{
Xregister short m,u,d;
Xshort loc,i,j,m0,piece;
Xstruct leaf *node;
X
X  TrPnt[ply+1] = TrPnt[ply];
X  Dstart[pawn] = Dpwn[side]; Dstop[pawn] = Dstart[pawn] + 1;
X  for (i = 0; i <= PieceCnt[side]; i++)
X    { 
X      loc = PieceList[side][i];
X      piece = board[loc]; m0 = map[loc];
X      if (sweep[piece])
X        for (j = Dstart[piece]; j <= Dstop[piece]; j++)
X          {
X            d = Dir[j]; m = m0+d; u = unmap[m];
X            while (u >= 0)
X              if (color[u] == neutral)
X                {
X                  m += d; u = unmap[m];
X                }
X              else
X                {
X                  if (color[u] == xside) LinkCapture;
X                  break;
X                }
X          }
X      else
X        {
X          for (j = Dstart[piece]; j <= Dstop[piece]; j++)
X            if ((u = unmap[m0+Dir[j]]) >= 0)
X              if (color[u] == xside) LinkCapture;
X          if (piece == pawn && row[loc] == rank7[side])
X            {
X              if (side == white) u = loc+8; else u = loc-8;
X              if (color[u] == neutral) LinkCapture;
X            }
X        }
X   }
X  sort(TrPnt[ply],TrPnt[ply+1]-1);
X}
X
X
XMakeMove(side,node,tempb,tempc,temps)
Xshort side,*tempc,*tempb,*temps;
Xstruct leaf *node;
X
X/*
X    Update Arrays board[], color[], and Pindex[] to reflect the new
X    board position obtained after making the move pointed to by
X    node.  Also update miscellaneous stuff that changes when a move
X    is made.
X*/
X    
X{
Xregister short f,t;
Xshort xside;
X
X  xside = otherside[side];
X  f = node->f; t = node->t; epsquare = -1;
X  TOsquare = t; cptrval = 0;
X  GameList[++GameCnt].gmove = (f<<8) + t;
X  if (node->flags & cstlmask)
X    {
X      GameList[GameCnt].piece = no_piece;
X      GameList[GameCnt].color = side;
X      castle(side,f,t,1);
X    }
X  else
X    {
X      *tempc = color[t]; *tempb = board[t]; *temps = svalue[t];
X      GameList[GameCnt].piece = *tempb;
X      GameList[GameCnt].color = *tempc;
X      if (*tempc != neutral)
X        {
X          UpdatePieceList(*tempc,t,1);
X          if (*tempb == pawn) --PawnCnt[*tempc][col[t]];
X          if (board[f] == pawn)
X            {
X              --PawnCnt[side][col[f]];
X              ++PawnCnt[side][col[t]];
X            }
X          mtl[xside] -= value[*tempb];
X          if (*tempb == pawn) pmtl[xside] -= valueP;
X          UpdateHashbd(xside,*tempb,-1,t);
X          cptrval = *temps;
X        }
X      color[t] = color[f]; board[t] = board[f]; svalue[t] = svalue[f];
X      Pindex[t] = Pindex[f]; PieceList[side][Pindex[t]] = t;
X      color[f] = neutral; board[f] = no_piece;
X      if (board[t] == pawn)
X        if (t-f == 16) epsquare = f+8;
X        else if (f-t == 16) epsquare = f-8;
X      if (node->flags & promote)
X        {
X          board[t] = queen;
X          --PawnCnt[side][col[t]];
X          mtl[side] += valueQ - valueP;
X          pmtl[side] -= valueP;
X          HasQueen[side] = true;
X          cptrval -= svalue[f];
X          UpdateHashbd(side,pawn,f,-1);
X          UpdateHashbd(side,queen,f,-1);
X        } 
X      if (board[t] == king) ++kingmoved[side];
X      if (node->flags & epmask) en_passant(xside,f,t,1);
X      else UpdateHashbd(side,board[t],f,t);
X    }
X}
X
X
XUnmakeMove(side,node,tempb,tempc,temps)
Xshort side,*tempc,*tempb,*temps;
Xstruct leaf *node;
X
X/*
X    Take back the move pointed to by node.
X*/
X
X{
Xregister short f,t;
Xshort xside;
X
X  xside = otherside[side];
X  f = node->f; t = node->t; epsquare = -1;
X  GameCnt--;
X  if (node->flags & cstlmask) castle(side,f,t,2);
X  else
X    {
X      color[f] = color[t]; board[f] = board[t]; svalue[f] = svalue[t];
X      Pindex[f] = Pindex[t]; PieceList[side][Pindex[f]] = f;
X      color[t] = *tempc; board[t] = *tempb; svalue[t] = *temps;
X      if (node->flags & promote)
X        {
X          board[f] = pawn;
X          ++PawnCnt[side][col[t]];
X          mtl[side] += valueP - valueQ;
X          pmtl[side] += valueP;
X          UpdateHashbd(side,queen,-1,t);
X          UpdateHashbd(side,pawn,-1,t);
X        } 
X      if (*tempc != neutral)
X        {
X          UpdatePieceList(*tempc,t,2);
X          if (*tempb == pawn) ++PawnCnt[*tempc][col[t]];
X          if (board[f] == pawn)
X            {
X              --PawnCnt[side][col[t]];
X              ++PawnCnt[side][col[f]];
X            }
X          mtl[xside] += value[*tempb];
X          if (*tempb == pawn) pmtl[xside] += valueP;
X          UpdateHashbd(xside,*tempb,-1,t);
X        }
X      if (board[f] == king) --kingmoved[side];
X      if (node->flags & epmask) en_passant(xside,f,t,2);
X      else UpdateHashbd(side,board[f],f,t);
X    }
X}
X
X
Xdistance(a,b)
Xshort a,b;
X{
Xshort d1,d2;
X
X  d1 = absv(col[a]-col[b]);
X  d2 = absv(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}
X
X
XUpdateWeights()
X{
Xshort 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 > 5700) stage = 0;
X      else if (tmtl < 1300) stage = 10;
X      else stage = (5700-tmtl) / 440;
X      
X      PEDRNK2B = -15;         /* centre pawn on 2nd rank & blocked */
X      PBKWRD = -6;            /* backward pawns */
X      PWEAKA  = -3;           /* each attack to weak pawn */
X      PWEAKH  = -3;           /* weak pawn on half open file */
X      PAWNSHIELD = 10-stage;  /* pawn near friendly king */
X      PADVNCM =  (10+stage)/2;    /* advanced pawn multiplier */
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      
X      RHOPN    = 10;          /* rook on half open file */
X      RHOPNX   = 4;
X      
X      XRAY     = 8;           /* Xray attack on major piece */
X      
X      KHOPN    = (3*stage-30) / 2; /* king on half open file */
X      KHOPNX   = KHOPN / 2;
X      KCASTLD  = 10 / (stage+1);   /* king castled */
X      KMOVD    = -40 / (stage+1);  /* king moved before castling */
X      KATAK    = 5;                /* B,R attacks near enemy king */
X      if (stage < 8) KSFTY = 8-stage; else KSFTY = 0;
X      
X      ATAKD    = -6;          /* defender > attacker */
X      HUNGP    = -8;          /* each hung piece */
X      HUNGX    = -10;         /* extra for >1 hung piece */
X    }
X}
X
X
XExaminePosition()
X/*
X  This is done one time before the search is started.
X  Set up arrays Mwpawn, Mbpawn, Mknight, Mbishop, Mking which are used
X  in the SqValue() function to determine the positional value of each
X  piece.
X*/
X{
Xregister short i,sq;
Xshort r,wpadv,bpadv,z,side,pp,j;
Xlong stage2,tpmtl,Pd,val;
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  stage2 = stage*stage; tpmtl = pmtl[white] + pmtl[black];
X  HasPawn[white] = HasPawn[black] = false;
X  HasKnight[white] = HasKnight[black] = false;
X  HasBishop[white] = HasBishop[black] = false;
X  HasRook[white] = HasRook[black] = false;
X  HasQueen[white] = HasQueen[black] = false;
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] = true; break;
X          case knight : HasKnight[side] = true; break;
X          case bishop : HasBishop[side] = true; break;
X          case rook : HasRook[side] = true; break;
X          case queen : HasQueen[side] = true; 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    
X  for (sq = 0; sq < 64; sq++)
X    {
X      WeakSq[white][sq] = WeakSq[black][sq] = true;
X      for (i = sq; i >= 0; i -= 8)
X        if (atak[white][i] >= ctlP) WeakSq[white][sq] = false;
X      for (i = sq; i < 64; i += 8)
X        if (atak[black][i] >= ctlP) WeakSq[black][sq] = false;
X      Kfield[white][sq] = Kfield[black][sq] = 0;
X    }
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  if (!Developed[white])
X    {
X       Mknight[white][1] -= 5;
X       Mbishop[white][2] -= 5;
X       Mbishop[white][5] -= 5;
X       Mknight[white][6] -= 5;
X    }
X  if (!Developed[black])
X    {
X       Mknight[black][57] -= 5;
X       Mbishop[black][58] -= 5;
X       Mbishop[black][61] -= 5;
X       Mknight[black][62] -= 5;
X    }
X    
X  for (sq = 0; sq < 64; sq++)
X    {
X      wpadv = bpadv = PADVNCM;
X      Mwpawn[sq] = (wpadv*PawnAdvance[sq]) / 10;
X      Mbpawn[sq] = (bpadv*PawnAdvance[63-sq]) / 10;
X      if (distance(sq,wking) < 3 && (col[sq] < 3 || col[sq] > 4))
X        Mwpawn[sq] += PAWNSHIELD;
X      if (distance(sq,bking) < 3 && (col[sq] < 3 || col[sq] > 4))
X        Mbpawn[sq] += PAWNSHIELD;
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] += stage;
X      Mbishop[black][sq] += stage;
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 (WeakSq[black][sq]) Mknight[white][sq] += KNIGHTSTRONG;
X      if (WeakSq[white][sq]) Mknight[black][sq] += KNIGHTSTRONG;
X      if (WeakSq[black][sq]) Mbishop[white][sq] += BISHOPSTRONG;
X      if (WeakSq[white][sq]) Mbishop[black][sq] += BISHOPSTRONG;
X      
X      Pd = 0;
X      for (i = 0; i < 64; i++)
X        if (board[i] == pawn)
X          {
X            if (color[i] == white)
X              {
X                r = row[i]+3; 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 (!WeakSq[black][j]) pp = false;
X              }
X            else
X              {
X                r = 10-row[i]; 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 (!WeakSq[white][j]) pp = false;
X              }
X            if (pp) r *= 4;
X            Pd += r*distance(sq,z);
X          }
X      if (tpmtl > 0)
X        {
X          val = (Pd*stage2) / (2*tpmtl);
X          Mking[white][sq] -= (short)val;
X          Mking[black][sq] -= (short)val;
X        }
X
X      if (distance(sq,wking) == 1) Kfield[black][sq] += KATAK;
X      if (distance(sq,bking) == 1) Kfield[white][sq] += KATAK;
X    }
X}
X
X
Xint trapped(loc,piece)
Xshort loc,piece;
X/*
X  See if the attacked piece has unattacked squares to move to.
X  If it is trapped, increment the hung[] array so that the search
X  will be extended.
X*/
X{
Xregister short u,m,d;
Xshort i,m0;
X
X  m0 = map[loc];
X  if (sweep[piece])
X    for (i = Dstart[piece]; i <= Dstop[piece]; i++)
X      {
X        d = Dir[i]; m = m0+d; u = unmap[m];
X        while (u >= 0)
X          if (color[u] == c1) break;
X          else if (atak[c2][u] == 0 || board[u] >= piece) return(false);
X          else if (color[u] == c2) break;
X          else
X            {
X              m += d; u = unmap[m];
X            }
X      }
X  else if (piece == pawn)
X    {
X       if (c1 == white) u = loc+8; else u = loc-8;
X       if (color[u] == neutral && atak[c1][u] >= atak[c2][u])
X         return(false);
X       for (i = 0; i <= 1; i++)
X         if ((u = unmap[m0+Dir[Dpwn[c1]+i]]) >= 0)
X           if (color[u] == c2) return(false);
X    }
X  else
X    {
X      for (i = Dstart[piece]; i <= Dstop[piece]; i++)
X        if ((u = unmap[m0+Dir[i]]) >= 0)
X          if (color[u] != c1)
X            if (atak[c2][u] == 0 || board[u] >= piece) return(false);
X    }
X  return(true);
X}
X
X
X#define ScoreThreat\
X  if (color[u] != c2)\
X    if (atak[c1][u] == 0 || (atak[c2][u] & 0xFF) > 1) ++cnt;\
X    else *s -= 3
X
X
XKingScan(loc,s)
Xshort loc,*s;
X/*
X  Assign penalty if king can be threatened by checks or if
X  squares adjacent to the king have a bad attack/defence balance.
X*/
X{
Xregister short m,u,d;
Xshort i,m0,cnt,z;
X
X  cnt = z = 0;
X  m0 = map[loc];
X  if (HasBishop[c2] || HasQueen[c2])
X    for (i = Dstart[bishop]; i <= Dstop[bishop]; i++)
X      {
X        d = Dir[i]; m = m0+d; u = unmap[m];
X        if (u >= 0 && atak[c2][u] > atak[c1][u]) z++;
X        while (u >= 0)
X          {
X            if (atak[c2][u] & ctlBQ) ScoreThreat;
X            if (color[u] != neutral) break;
X            m += d; u = unmap[m];
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; u = unmap[m];
X        if (u >= 0 && atak[c2][u] > atak[c1][u]) z++;
X        while (u >= 0)
X          {
X            if (atak[c2][u] & ctlRQ) ScoreThreat;
X            if (color[u] != neutral) break;
X            m += d; u = unmap[m];
X          }
X      }
X  if (HasKnight[c2])
X    for (i = Dstart[knight]; i <= Dstop[knight]; i++)
X      if ((u = unmap[m0+Dir[i]]) >= 0) 
X        if (atak[c2][u] & ctlNN) ScoreThreat;
X
X  if (z > 2) cnt++;
X  *s += (KSFTY*Kthreat[cnt]) / 8;
X}
X
X
XBRscan(loc,s,mob)
Xshort loc,*s,*mob;
X/*
X  Find B,R mobility, XRAY attacks, and pins.
X  Increment the hung[] array if a pin is found.
X*/
X{
Xregister short m,u,d;
Xshort j,m0,s0,piece,pin;
X
X  *mob = 0;
X  piece = board[loc]; m0 = map[loc];
X  for (j = Dstart[piece]; j <= Dstop[piece]; j++)
X    {
X      s0 = 2;
X      d = Dir[j]; m = m0+d; u = unmap[m];
X      while (u >= 0)
X        {
X          *s += Kfield[c1][u];
X          if (color[u] == neutral)
X            {
X              *mob += s0;
X              m += d; u = unmap[m];
X            }
X          else if (board[u] == pawn) break;
X          else if (s0 == 2)
X            {
X              pin = u; s0 = 1;
X              m += d; u = unmap[m];
X            }
X          else if (color[u] == c2 && (board[u] > piece || atak[c2][u] == 0))
X            {
X              *s += XRAY;
X              if (color[pin] == c2)
X                if (atak[c2][pin] == 0 ||
X                    atak[c1][pin] > control[board[pin]]+1)
X                  ++hung[c2];
X              break;
X            }
X          else break;
X        }
X    }
X}
X
X
Xint SqValue(loc,side)
X
X/* Calculate the positional value for the piece on 'loc'. */
X
Xshort loc,side;
X{
Xregister short j,rank,column;
Xshort s,piece,a1,a2,e,m0,u,in_square,r,mob;
X
X  piece = board[loc];
X  a1 = (atak[c1][loc] & 0x4FFF); a2 = (atak[c2][loc] & 0x4FFF);
X  rank = row[loc]; column = col[loc];
X  s = 0;
X  if (piece == pawn && c1 == white)
X    {
X      s = Mwpawn[loc];
X      if (loc == 11 || loc == 12)
X        if (color[loc+8] != neutral) s += PEDRNK2B;
X      if ((column == 0 || PawnCnt[white][column-1] == 0) &&
X          (column == 7 || PawnCnt[white][column+1] == 0))
X        s += ISOLANI[column];
X      else if (PawnCnt[white][column] > 1) s += DOUBLED[column];
X      if (a1 < ctlP && atak[white][loc+8] < ctlP)
X        {
X          s += PBKWRD;
X          s += PWEAKA * (a2 & 0xFF);
X          if (PawnCnt[black][column] == 0) s += PWEAKH;
X          if (color[loc+8] != neutral) s -= 3;
X        }
X      if (PawnCnt[black][column] == 0)
X        {
X          if (side == black) r = rank-1; else r = rank;
X          in_square = (row[bking] >= r && distance(loc,bking) < 8-r);
X          if (a2 == 0 || side == white) e = 0; else e = 1;
X          for (j = loc+8; j < 64; j += 8)
X            if (atak[black][j] >= ctlP) j = 99;
X            else if (atak[black][j] > 0 || color[j] != neutral) e = 1; 
X          if (j == 99) s += (stage*passed_pawn3[rank]) / 10;
X          else
X            {
X              if (in_square || e == 1) s += (stage*passed_pawn2[rank]) / 10;
X              else s += (stage*passed_pawn1[rank]) / 10;
X              if (color[loc+8] != neutral) s -= 8;
X            }
X        }
X    }
X  else if (piece == pawn && c1 == black)
X    {
X      s = Mbpawn[loc];
X      if (loc == 51 || loc == 52)
X        if (color[loc-8] != neutral) s += PEDRNK2B;
X      if ((column == 0 || PawnCnt[black][column-1] == 0) &&
X          (column == 7 || PawnCnt[black][column+1] == 0))
X        s += ISOLANI[column];
X      else if (PawnCnt[black][column] > 1) s += DOUBLED[column];
X      if (a1 < ctlP && atak[black][loc-8] < ctlP)
X        {
X          s += PBKWRD;
X          s += PWEAKA * (a2 & 0xFF);
X          if (PawnCnt[white][column] == 0) s += PWEAKH;
X          if (color[loc-8] != neutral) s -= 3;
X        }
X      if (PawnCnt[white][column] == 0)
X        {
X          if (side == white) r = rank+1; else r = rank;
X          in_square = (row[wking] <= r && distance(loc,wking) < r+1);
X          if (a2 == 0 || side == black) e = 0; else e = 1;
X          for (j = loc-8; j >= 0; j -= 8)
X            if (atak[white][j] >= ctlP) j = -99;
X            else if (atak[white][j] > 0 || color[j] != neutral) e = 1;
X          if (j == -99) s += (stage*passed_pawn3[7-rank]) / 10;
X          else
X            {
X              if (in_square || e == 1) s += (stage*passed_pawn2[7-rank]) / 10;
X              else s += (stage*passed_pawn1[7-rank]) / 10;
X              if (color[loc-8] != neutral) s -= 8;
X            }
X        }
X    }
X  else if (piece == knight)
X    {
X      s = Mknight[c1][loc];
X    }
X  else if (piece == bishop)
X    {
X      s = Mbishop[c1][loc];
X      BRscan(loc,&s,&mob);
X      s += BMBLTY[mob];
X    }
X  else if (piece == rook)
X    {
X      if (PawnCnt[c1][column] == 0) s += RHOPN;
X      if (PawnCnt[c2][column] == 0) s += RHOPNX;
X      BRscan(loc,&s,&mob);
X      if (stage < 3) s += RMBLTY[mob] / 2;
X      else
X        {
X          s += RMBLTY[mob];
X          if (c1 == white) s += 14 - taxicab(loc,bking);
X          else s += 14 - taxicab(loc,wking);
X        }
X    }
X  else if (piece == queen)
X    {
X      if (stage > 3)
X        if (c1 == white) s += 14 - taxicab(loc,bking);
X        else s += 14 - taxicab(loc,wking);
X    }
X  else if (piece == king)
X    {
X      if (Developed[c2] && KSFTY > 0) KingScan(loc,&s);
X      if (castld[c1]) s += KCASTLD;
X      else if (kingmoved[c1] > 0) s += KMOVD;
X
X      if (PawnCnt[c1][column] == 0) s += KHOPN;
X      if (PawnCnt[c2][column] == 0) s += KHOPNX;
X      if (column == 1 || column == 2 || column == 3 || column == 7)
X        {
X          if (PawnCnt[c1][column-1] == 0) s += KHOPN;
X          if (PawnCnt[c2][column-1] == 0) s += KHOPNX;
X        }
X      if (column == 4 || column == 5 || column == 6 || column == 0)
X        {
X          if (PawnCnt[c1][column+1] == 0) s += KHOPN;
X          if (PawnCnt[c2][column+1] == 0) s += KHOPNX;
X        }
X
X      if (stage < 8) s += Mking[c1][loc];
X      else
X        {
X          e = Mking[c1][loc];
X          m0 = map[loc];
X          for (j = Dstart[king]; j <= Dstop[king]; j++)
X            if ((u = unmap[m0+Dir[j]]) >= 0)
X              if (atak[c2][u] == 0)
X                if (Mking[c1][u] > e) e = Mking[c1][u];
X          s += (Mking[c1][loc] + e) / 2;
X        }
X    }
X  if (a2 > 0) 
X    if (a1 == 0 || a2 > control[piece]+1)
X      {
X        s += HUNGP;
X        ++hung[c1];
X        if (piece != king && trapped(loc,piece)) ++hung[c1];
X      }
X    else if (a2 > a1) s += ATAKD;
X  return(s);
X}
X
X
XScoreLoneKing(side,score)
Xshort side,*score;
X/* 
X   static evaluation when loser has only a king and winner has no pawns
X   and mating material.
X*/
X{
Xshort winner,loser,s;
X
X  UpdateWeights();
X  if (mtl[white] > mtl[black]) winner = white; else winner = black;
X  loser = otherside[winner];
X  if (emtl[winner] <= valueB) *score = 0;
X  else
X    {
X      s = 4995 + emtl[winner] -
X      DyingKing[PieceList[loser][0]] -
X      2*distance(PieceList[winner][0],PieceList[loser][0]);
X      if (side == winner) *score = s; else *score = -s;
X    }
X}
X
X
XScorePosition(side,score)
Xshort side,*score;
X
X/* Perform static evaluation of board position.  */
X
X{
Xregister short loc,i;
Xshort s,xside,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      for (i = 0; i <= PieceCnt[c1]; i++)
X        {
X          loc = PieceList[c1][i];
X          s = SqValue(loc,side);
X          pscore[c1] += s;
X          svalue[loc] = s;
X        }
X    }
X  if (hung[side] > 1) pscore[side] += HUNGX;
X  if (hung[xside] > 1) pscore[xside] += HUNGX;
X  *score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10;
X  if (randflag) *score += rand() % 5;
X  if (*score > 0 && pmtl[side] == 0 && emtl[side] <= valueB)
X    *score = 0;
X  if (*score < 0 && pmtl[xside] == 0 && emtl[xside] <= valueB)
X    *score = 0;
X  if (mtl[xside] == valueK && emtl[side] > valueB) *score += 200;
X  if (mtl[side] == valueK && emtl[xside] > valueB) *score -= 200;
X}
X
X
X#define UpdateSearchStatus\
X{\
X  if (post)\
X    {\
X      algbr(node->f,node->t,false);\
X      gotoXY(65,1); printz("%5s ",mvstr1);\
X    }\
X  if (pnt > TrPnt[1])\
X    {\
X      d = best-Zscore; e = best-node->score;\
X      if (Sdepth == 1) ExtraTime = 10;\
X      else if (best < alpha)\
X        {\
X          if (alpha - best > 800) ExtraTime = 5*ResponseTime;\
X          else ExtraTime = 3*ResponseTime;\
X        }\
X      else if (d > -zwndw && e > 4*zwndw) ExtraTime = -ResponseTime/3;\
X      else if (d > -zwndw) ExtraTime = 0;\
X      else if (d > -3*zwndw) ExtraTime = ResponseTime;\
X      else if (d > -9*zwndw) ExtraTime = 3*ResponseTime;\
X      else ExtraTime = 5*ResponseTime;\
X    }\
X}
X
X
Xint evaluate(side,xside,ply,depth,alpha,beta)
Xshort side,xside,ply,depth,alpha,beta;
X
X/*
X   Compute an estimate of the score by adding the positional score
X   from the previous ply to the material difference.  If in the
X   quiescence search return this estimate, otherwise call
X   ScorePosition() to determine the score.
X*/
X
X{
Xshort s;
X
X  hung[white] = hung[black] = 0;
X  slk = ((mtl[white] == valueK && pmtl[black] == 0) ||
X         (mtl[black] == valueK && pmtl[white] == 0));
X  s = -Pscore[ply-1] - cptrval + mtl[side] - mtl[xside];
X  if (ply == 1 || slk ||
X     (ply == Sdepth+1 && s-250 < beta) ||
X     (ply == Sdepth+2 && s-prune < beta) ||
X     (ply == Sdepth+3 && board[TOsquare] == pawn && s-prune < beta)) 
X    {
X      EvalNodes++;
X      ataks(side,atak[side]);
X      ataks(xside,atak[xside]);
X      if (atak[side][PieceList[xside][0]] > 0) s = 10001-ply;
X      else if (slk) ScoreLoneKing(side,&s);
X      else ScorePosition(side,&s);
X      InChk = (atak[xside][PieceList[side][0]] > 0);
X    }
X  else
X    {
X      if (CptrFlag[ply-1] && board[TOsquare] == pawn) s += 10;
X      if (SqAtakd(PieceList[xside][0],side)) s = 10001-ply;
X      InChk = SqAtakd(PieceList[side][0],xside);
X    }
X  Pscore[ply] = s - mtl[side] + mtl[xside];
X  if (InChk) ChkFlag[ply-1] = Pindex[TOsquare];
X  else ChkFlag[ply-1] = 0;
X  Threat[ply-1] = (hung[side] > 1 && ply == Sdepth+1);
X  return(s);
X}
X
X
Xint FoundInTTable(side,depth,alpha,beta,score)
Xshort side,depth,*alpha,*beta,*score;
X{
Xshort hindx;
X  if (!hashflag) return(false);
X  if (side == white) hashkey |= 1; else hashkey &= 0xFFFE;
X  hindx = (hashkey & (ttblsz-1));
X  ptbl = (ttable+hindx);
X  if (ptbl->depth >= depth && ptbl->hashbd == hashbd)
X    {
X      HashCnt++;
X      PV = ptbl->reply;
X      if (ptbl->flags & truescore)
X        {
X          *score = ptbl->score;
X          return(true);
X        }
X/*
X      else if (ptbl->flags & upperbound)
X        {
X          if (ptbl->score < *alpha)
X            {
X              *score = ptbl->score;
X              return(true); 
X            }
X        }
X*/
X      else if (ptbl->flags & lowerbound)
X        {
X          if (ptbl->score > *alpha) *alpha = ptbl->score;
X        }
X    }
X  return(false);
X}
X
X
XPutInTTable(side,score,depth,alpha,beta,reply)
Xshort side,score,depth,alpha,beta;
Xunsigned short reply;
X{
Xshort hindx;
X  if (side == white) hashkey |= 1; else hashkey &= 0xFFFE;
X  hindx = (hashkey & (ttblsz-1));
X  ptbl = (ttable+hindx);
X  ptbl->hashbd = hashbd;
X  ptbl->depth = depth;
X  ptbl->score = score; 
X  ptbl->reply = reply;
X  ptbl->flags = 0;
X  if (score < alpha)
X    ptbl->flags |= upperbound;
X  else if (score > beta)
X    ptbl->flags |= lowerbound;
X  else ptbl->flags |= truescore;
X}
X
X
Xint search(side,ply,depth,alpha,beta,bstline,rpt)
Xshort side,ply,depth,alpha,beta,*rpt;
Xunsigned short bstline[];
X
X/*
X   Perform an alpha-beta search to determine the score for the 
X   current board position. If depth <= 0 only capturing moves are 
X   generated and searched, otherwise all moves are processed. The 
X   search depth is modified for check evasions, some forcing checks 
X   and for certain threats. Extensions may continue for up to 11 
X   ply beyond the nominal search depth. 
X*/
X
X{
X#define cut (cf && score+node->score < alpha)
X
Xregister short j;
Xshort best,tempb,tempc,temps,xside,pnt,pbst,d,e,cf,score,in_check,xdepth,rcnt;
Xunsigned short mv,nxtline[maxdepth];
Xstruct leaf *node,tmp;
X
X  NodeCnt++;
X  xside = otherside[side];
X  xdepth = depth;
X  
X  if (ply <= Sdepth+1) repetition(rpt); else *rpt = 0;
X  if (*rpt >= 2) return(0);
X
X  score = evaluate(side,xside,ply,depth,alpha,beta);
X  in_check = InChk;
X  if (score > 9000) return(score);
X  
X  if (in_check && depth > 0) ++depth;
X  else if (depth < 1 && score >= alpha &&
X          (in_check || PawnThreat[ply-1] || Threat[ply-1]))
X    depth = 1;
X  else if (depth < 1 && score <= beta && ply < Sdepth+4 &&
X           ply > 4 && ChkFlag[ply-2] && ChkFlag[ply-4] &&
X           ChkFlag[ply-2] != ChkFlag[ply-4])
X    depth = 1;
X  if (depth > 0)
X    {
X      if (FoundInTTable(side,depth,&alpha,&beta,&score))
X        return(score);
X      if (alpha > beta) return(alpha);
X    }
X    
X  if (Sdepth == 1) d = 7; else d = 11;
X  if (ply > Sdepth+d || (depth < 1 && score > beta)) return(score);
X
X  if (ply > 1)
X    if (depth > 0) MoveList(side,ply);
X    else CaptureList(side,xside,ply);
X    
X  if (TrPnt[ply] == TrPnt[ply+1]) return(score);
X    
X  cf = (depth < 1 && !ChkFlag[ply-2] && !slk);
X
X  if (depth > 0) best = -12000; else best = score;
X  if (best > alpha) alpha = best;
X  
X  for (pnt = pbst = TrPnt[ply];
X       pnt < TrPnt[ply+1] && best <= beta && !timeout;
X       pnt++)
X    {
X      node = &Tree[pnt];
X      nxtline[ply+1] = 0;
X      
X      if (cut) continue;
X      if (ply == 1) UpdateSearchStatus;
X
X      if (!(node->flags & exact))
X        {
X          MakeMove(side,node,&tempb,&tempc,&temps);
X          CptrFlag[ply] = (node->flags & capture);
X          PawnThreat[ply] = (node->flags & pwnthrt);
X          Tscore[ply] = node->score;
X          PV = node->reply;
X          node->score = -search(xside,ply+1,depth-1,-beta,-alpha,
X                                nxtline,&rcnt);
X          if (absv(node->score) > 9000) node->flags |= exact;
X          else if (rcnt == 1)
X            if (node->score > contempt[side]+20) node->score -= 20;
X            else if (node->score < contempt[side]-20) node->score += 20;
X          if (rcnt >= 2 || GameCnt-Game50 > 99 ||
X             (node->score == 9999-ply && !ChkFlag[ply]))
X            {
X              node->flags |= draw; node->flags |= exact;
X              node->score = contempt[side];
X            }
X          node->reply = nxtline[ply+1];
X          UnmakeMove(side,node,&tempb,&tempc,&temps);
X        }
X      if (node->score > best && !timeout)
X        {
X          if (depth > 0)
X            if (node->score > alpha && !(node->flags & exact))
X              node->score += depth;
X          best = node->score; pbst = pnt;
X          if (best > alpha) alpha = best;
X          for (j = ply+1; nxtline[j] > 0; j++) bstline[j] = nxtline[j];
X          bstline[j] = 0;
X          bstline[ply] = (node->f<<8) + node->t;
X          if (ply == 1)
X            {
X              if (post) post_move(node);
X              if (best == alpha)
X                {
X                  tmp = Tree[pnt];
X                  for (j = pnt-1; j >= 0; j--) Tree[j+1] = Tree[j];
X                  Tree[0] = tmp;
X                }
X              if (Sdepth > 2)
X                if (best > beta) ShowResults('+');
X                else if (best < alpha) ShowResults('-');
X                else ShowResults('&');
X            }
X        }
X      if (NodeCnt > ETnodes) ElapsedTime(0);
X    }
X  if (ply == 1) node = &Tree[0]; else node = &Tree[pbst];
X  mv = (node->f<<8) + node->t;
X  if (ply <= Sdepth && *rpt == 0 && !timeout && hashflag)
X    PutInTTable(side,best,xdepth,alpha,beta,bstline[ply+1]);
X  if (depth > 0)
X    if (history[side-1][node->f][node->t] < 180)
X      history[side-1][node->f][node->t] += depth;
X  if (node->t != (GameList[GameCnt].gmove & 0xFF))
X    if (best <= beta) killr3[ply] = mv;
X    else if (mv != killr1[ply])
X      {
X        killr2[ply] = killr1[ply];
X        killr1[ply] = mv;
X      }
X  if (in_check && best > -9000) Qkillr[ply] = mv;
X  if (best > 9000) killr0[ply] = mv; else killr0[ply] = 0;
X  if (timeout || (best < alpha && -Tscore[ply-1] < best))
X    best = -Tscore[ply-1];
X  return(best);
X}
X
END_OF_gnuchess.c2
if test 39696 -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 3 \(of 3\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 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