⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gnuchess.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
UpdateHashbd(side,piece,f,t)short side,piece,f,t;/*   hashbd contains a 32 bit "signature" of the board position. hashkey    contains a 16 bit code used to address the hash table. When a move is    made, XOR'ing the hashcode of moved piece on the from and to squares    with the hashbd and hashkey values keeps things current. */{  if (f >= 0)    {      hashbd ^= hashcode[side][piece][f].bd;      hashkey ^= hashcode[side][piece][f].key;    }  if (t >= 0)    {      hashbd ^= hashcode[side][piece][t].bd;      hashkey ^= hashcode[side][piece][t].key;    }}UpdatePieceList(side,sq,iop)short side,sq,iop;/*   Update the PieceList and Pindex arrays when a piece is captured or    when a capture is unmade. */{register short i;  if (iop == 1)    {      PieceCnt[side]--;      for (i = Pindex[sq]; i <= PieceCnt[side]; i++)        {          PieceList[side][i] = PieceList[side][i+1];          Pindex[PieceList[side][i]] = i;        }    }  else    {      PieceCnt[side]++;      PieceList[side][PieceCnt[side]] = sq;      Pindex[sq] = PieceCnt[side];    }}InitializeStats()/*   Scan thru the board seeing what's on each square. If a piece is found,    update the variables PieceCnt, PawnCnt, Pindex and PieceList. Also    determine the material for each side and set the hashkey and hashbd    variables to represent the current board position. Array    PieceList[side][indx] contains the location of all the pieces of    either side. Array Pindex[sq] contains the indx into PieceList for a    given square. */{register short i,sq;  epsquare = -1;  for (i = 0; i < 8; i++)    PawnCnt[white][i] = PawnCnt[black][i] = 0;  mtl[white] = mtl[black] = pmtl[white] = pmtl[black] = 0;  PieceCnt[white] = PieceCnt[black] = 0;  hashbd = hashkey = 0;  for (sq = 0; sq < 64; sq++)    if (color[sq] != neutral)      {        mtl[color[sq]] += value[board[sq]];        if (board[sq] == pawn)          {            pmtl[color[sq]] += valueP;            ++PawnCnt[color[sq]][column[sq]];          }        if (board[sq] == king) Pindex[sq] = 0;          else Pindex[sq] = ++PieceCnt[color[sq]];        PieceList[color[sq]][Pindex[sq]] = sq;        hashbd ^= hashcode[color[sq]][board[sq]][sq].bd;        hashkey ^= hashcode[color[sq]][board[sq]][sq].key;      }}pick(p1,p2)short p1,p2;/*     Find the best move in the tree between indexes p1 and p2. Swap the    best move into the p1 element. */{register short p,s;short p0,s0;struct leaf temp;  s0 = Tree[p1].score; p0 = p1;  for (p = p1+1; p <= p2; p++)    if ((s = Tree[p].score) > s0)      {        s0 = s; p0 = p;      }  if (p0 != p1)    {      temp = Tree[p1]; Tree[p1] = Tree[p0]; Tree[p0] = temp;    }}repetition(cnt)short *cnt;/*    Check for draw by threefold repetition.*/{register short i,c;short f,t,b[64];unsigned short m;  *cnt = c = 0;  if (GameCnt > Game50+3)    {/*      memset((char *)b,0,64*sizeof(short));*/      for (i = 0; i < 64; b[i++] = 0);      for (i = GameCnt; i > Game50; i--)        {          m = GameList[i].gmove; f = m>>8; t = m & 0xFF;          if (++b[f] == 0) c--; else c++;          if (--b[t] == 0) c--; else c++;          if (c == 0) (*cnt)++;        }    }}#if (NEWMOVE < 3)int SqAtakd(sq,side)short sq,side;/*  See if any piece with color 'side' ataks sq.  First check for pawns  or king, then try other pieces. Array Dcode is used to check for  knight attacks or R,B,Q co-linearity.  */{register short m,d;short i,m0,m1,loc,piece,*PL;  m1 = map[sq];  if (side == white) m = m1-0x0F; else m = m1+0x0F;  if (!(m & 0x88))    if (board[unmap[m]] == pawn && color[unmap[m]] == side) return(true);  if (side == white) m = m1-0x11; else m = m1+0x11;  if (!(m & 0x88))    if (board[unmap[m]] == pawn && color[unmap[m]] == side) return(true);  if (distance(sq,PieceList[side][0]) == 1) return(true);    PL = PieceList[side];  for (i = 1; i <= PieceCnt[side]; i++)    {      loc = PL[i]; piece = board[loc];      if (piece == pawn) continue;      m0 = map[loc]; d = Dcode[abs(m1-m0)];      if (d == 0 || (Pdir[d] & pbit[piece]) == 0) continue;      if (piece == knight) return(true);      else        {          if (m1 < m0) d = -d;          for (m = m0+d; m != m1; m += d)            if (color[unmap[m]] != neutral) break;          if (m == m1) return(true);        }    }  return(false);}#endif#if (NEWMOVE < 2)ataks(side,a)short side,*a;/*    Fill array atak[][] with info about ataks to a square.  Bits 8-15    are set if the piece (king..pawn) ataks the square. Bits 0-7    contain a count of total ataks to the square.*/{register short u,m;short d,c,j,j1,j2,piece,i,m0,sq,*PL; /*  memset((char *)a,0,64*sizeof(short));*/  for (u = 0; u < 64; a[u++] = 0);  Dstart[pawn] = Dpwn[side]; Dstop[pawn] = Dstart[pawn] + 1;  PL = PieceList[side];  for (i = 0; i <= PieceCnt[side]; i++)    {      sq = PL[i];      m0 = map[sq];      piece = board[sq];      c = control[piece]; j1 = Dstart[piece]; j2 = Dstop[piece];      if (sweep[piece])        for (j = j1; j <= j2; j++)          {            d = Dir[j]; m = m0+d;            while (!(m & 0x88))              {                u = unmap[m];                a[u] = ++a[u] | c;                if (color[u] == neutral) m += d;                else break;              }          }      else        for (j = j1; j <= j2; j++)          if (!((m = m0+Dir[j]) & 0x88))            {              u = unmap[m];              a[u] = ++a[u] | c;            }    }}#endif/* ............    POSITIONAL EVALUATION ROUTINES    ............ */ScorePosition(side,score)short side,*score;/*   Perform normal static evaluation of board position. A score is    generated for each piece and these are summed to get a score for each    side. */{register short sq,s;short i,xside,pscore[3];  wking = PieceList[white][0]; bking = PieceList[black][0];  UpdateWeights();  xside = otherside[side];  pscore[white] = pscore[black] = 0;  for (c1 = white; c1 <= black; c1++)    {      c2 = otherside[c1];      if (c1 == white) EnemyKing = bking; else EnemyKing = wking;      atk1 = atak[c1]; atk2 = atak[c2];      PC1 = PawnCnt[c1]; PC2 = PawnCnt[c2];      for (i = 0; i <= PieceCnt[c1]; i++)        {          sq = PieceList[c1][i];          s = SqValue(sq,side);          pscore[c1] += s;          svalue[sq] = s;        }    }  if (hung[side] > 1) pscore[side] += HUNGX;  if (hung[xside] > 1) pscore[xside] += HUNGX;    *score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10;  if (dither) *score += rand() % dither;    if (*score > 0 && pmtl[side] == 0)    if (emtl[side] < valueR) *score = 0;    else if (*score < valueR) *score /= 2;  if (*score < 0 && pmtl[xside] == 0)    if (emtl[xside] < valueR) *score = 0;    else if (-*score < valueR) *score /= 2;      if (mtl[xside] == valueK && emtl[side] > valueB) *score += 200;  if (mtl[side] == valueK && emtl[xside] > valueB) *score -= 200;}ScoreLoneKing(side,score)short side,*score;/*    Static evaluation when loser has only a king and winner has no pawns   or no pieces.*/{short winner,loser,king1,king2,s,i;  UpdateWeights();  if (mtl[white] > mtl[black]) winner = white; else winner = black;  loser = otherside[winner];  king1 = PieceList[winner][0]; king2 = PieceList[loser][0];    s = 0;    if (pmtl[winner] > 0)    for (i = 1; i <= PieceCnt[winner]; i++)      s += ScoreKPK(side,winner,loser,king1,king2,PieceList[winner][i]);        else if (emtl[winner] == valueB+valueN)    s = ScoreKBNK(winner,king1,king2);      else if (emtl[winner] > valueB)    s = 500 + emtl[winner] - DyingKing[king2] - 2*distance(king1,king2);      if (side == winner) *score = s; else *score = -s;}int ScoreKPK(side,winner,loser,king1,king2,sq)short side,winner,loser,king1,king2,sq;/*   Score King and Pawns versus King endings.*/{short s,r;    if (PieceCnt[winner] == 1) s = 50; else s = 120;  if (winner == white)    {      if (side == loser) r = row[sq]-1; else r = row[sq];      if (row[king2] >= r && distance(sq,king2) < 8-r) s += 10*row[sq];      else s = 500+50*row[sq];      if (row[sq] < 6) sq += 16; else sq += 8;    }  else    {      if (side == loser) r = row[sq]+1; else r = row[sq];      if (row[king2] <= r && distance(sq,king2) < r+1) s += 10*(7-row[sq]);      else s = 500+50*(7-row[sq]);      if (row[sq] > 1) sq -= 16; else sq -= 8;    }  s += 8*(taxicab(king2,sq) - taxicab(king1,sq));  return(s);}int ScoreKBNK(winner,king1,king2)short winner,king1,king2;/*   Score King+Bishop+Knight versus King endings.   This doesn't work all that well but it's better than nothing.*/{short s;  s = emtl[winner] - 300;  if (KBNKsq == 0) s += KBNK[king2];  else s += KBNK[locn[row[king2]][7-column[king2]]];  s -= taxicab(king1,king2);  s -= distance(PieceList[winner][1],king2);  s -= distance(PieceList[winner][2],king2);  return(s);}SqValue(sq,side)short sq,side;/*   Calculate the positional value for the piece on 'sq'.*/{register short j,fyle,rank;short s,piece,a1,a2,in_square,r,mob,e,c;  piece = board[sq];  a1 = (atk1[sq] & 0x4FFF); a2 = (atk2[sq] & 0x4FFF);  rank = row[sq]; fyle = column[sq];  s = 0;  if (piece == pawn && c1 == white)    {      s = Mwpawn[sq];      if (sq == 11 || sq == 12)        if (color[sq+8] != neutral) s += PEDRNK2B;      if ((fyle == 0 || PC1[fyle-1] == 0) &&          (fyle == 7 || PC1[fyle+1] == 0))        s += ISOLANI[fyle];      else if (PC1[fyle] > 1) s += PDOUBLED;      if (a1 < ctlP && atk1[sq+8] < ctlP)        {          s += BACKWARD[a2 & 0xFF];          if (PC2[fyle] == 0) s += PWEAKH;          if (color[sq+8] != neutral) s += PBLOK;        }      if (PC2[fyle] == 0)        {          if (side == black) r = rank-1; else r = rank;          in_square = (row[bking] >= r && distance(sq,bking) < 8-r);          if (a2 == 0 || side == white) e = 0; else e = 1;          for (j = sq+8; j < 64; j += 8)            if (atk2[j] >= ctlP) { e = 2; break; }            else if (atk2[j] > 0 || color[j] != neutral) e = 1;          if (e == 2) s += (stage*PassedPawn3[rank]) / 10;          else if (in_square || e == 1) s += (stage*PassedPawn2[rank]) / 10;          else if (emtl[black] > 0) s += (stage*PassedPawn1[rank]) / 10;          else s += PassedPawn0[rank];        }    }  else if (piece == pawn && c1 == black)    {      s = Mbpawn[sq];      if (sq == 51 || sq == 52)        if (color[sq-8] != neutral) s += PEDRNK2B;      if ((fyle == 0 || PC1[fyle-1] == 0) &&          (fyle == 7 || PC1[fyle+1] == 0))        s += ISOLANI[fyle];      else if (PC1[fyle] > 1) s += PDOUBLED;      if (a1 < ctlP && atk1[sq-8] < ctlP)        {          s += BACKWARD[a2 & 0xFF];          if (PC2[fyle] == 0) s += PWEAKH;          if (color[sq-8] != neutral) s += PBLOK;        }      if (PC2[fyle] == 0)        {          if (side == white) r = rank+1; else r = rank;          in_square = (row[wking] <= r && distance(sq,wking) < r+1);          if (a2 == 0 || side == black) e = 0; else e = 1;          for (j = sq-8; j >= 0; j -= 8)            if (atk2[j] >= ctlP) { e = 2; break; }            else if (atk2[j] > 0 || color[j] != neutral) e = 1;          if (e == 2) s += (stage*PassedPawn3[7-rank]) / 10;          else if (in_square || e == 1) s += (stage*PassedPawn2[7-rank]) / 10;          else if (emtl[white] > 0) s += (stage*PassedPawn1[7-rank]) / 10;          else s += PassedPawn0[7-rank];        }    }  else if (piece == knight)    {      s = Mknight[c1][sq];    }  else if (piece == bishop)    {      s = Mbishop[c1][sq];      BRscan(sq,&s,&mob);      s += BMBLTY[mob];    }  else if (piece == rook)    {      s += RookBonus;      BRscan(sq,&s,&mob);      s += RMBLTY[mob];      if (PC1[fyle] == 0) s += RHOPN;      if (PC2[fyle] == 0) s += RHOPNX;      if (rank == rank7[c1] && pmtl[c2] > 100) s += 10;      if (stage > 2) s += 14 - taxicab(sq,EnemyKing);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -