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

📄 move.c

📁 一款运行在linux上的象棋游戏。用GTK/GNOME环境下用GLADE开发。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* GNU Chess 5.0 - move.c - make and unmake moves code   Copyright (c) 1999-2002 Free Software Foundation, Inc.   GNU Chess is based on the two research programs    Cobalt by Chua Kong-Sian and Gazebo by Stuart Cracraft.   GNU Chess is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2, or (at your option)   any later version.   GNU Chess is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with GNU Chess; see the file COPYING.  If not, write to   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,   Boston, MA 02111-1307, USA.   Contact Info:      bug-gnu-chess@gnu.org     cracraft@ai.mit.edu, cracraft@stanfordalumni.org, cracraft@earthlink.net*//* * */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include "common.h"void MakeMove (int side, int *move)/************************************************************************** * *  To make a move on the board and update the various game information. * **************************************************************************/{   BitBoard *a;   int f, t, fpiece, tpiece;    int rookf, rookt, epsq, sq;   int xside;   GameRec *g;   xside = 1^side;   f = FROMSQ(*move);   t = TOSQ(*move);   fpiece = cboard[f];   tpiece = cboard[t];   a = &board.b[side][fpiece];   CLEARBIT (*a, f);   SETBIT (*a, t);   CLEARBIT (board.blockerr90, r90[f]);   SETBIT (board.blockerr90, r90[t]);   CLEARBIT (board.blockerr45, r45[f]);   SETBIT (board.blockerr45, r45[t]);   CLEARBIT (board.blockerr315, r315[f]);   SETBIT (board.blockerr315, r315[t]);   cboard[f] = empty;   cboard[t] = fpiece;   GameCnt++;   g = &Game[GameCnt];   g->epsq = board.ep;    g->bflag = board.flag;   g->Game50 = Game50;   g->hashkey = HashKey;   g->phashkey = PawnHashKey;   g->mvboard = Mvboard[t];   g->comments = NULL;   Mvboard[t] = Mvboard[f]+1;    Mvboard[f] = 0;   if (board.ep > -1)      HashKey ^= ephash[board.ep];   HashKey ^= hashcode[side][fpiece][f];   HashKey ^= hashcode[side][fpiece][t];   if (fpiece == king)      board.king[side] = t;   if (fpiece == pawn)   {      PawnHashKey ^= hashcode[side][pawn][f];      PawnHashKey ^= hashcode[side][pawn][t];   }   if (tpiece != 0)		/* Capture */   {      ExchCnt[side]++;      CLEARBIT (board.b[xside][tpiece], t);      *move |= (tpiece << 15);      HashKey ^= hashcode[xside][tpiece][t];      if (tpiece == pawn)         PawnHashKey ^= hashcode[xside][pawn][t];      board.material[xside] -= Value[tpiece];      if (tpiece != pawn)         board.pmaterial[xside] -= Value[tpiece];   }   if (*move & PROMOTION) 	/* Promotion */    {      SETBIT (board.b[side][PROMOTEPIECE (*move)], t);      CLEARBIT (*a, t);      cboard[t] = PROMOTEPIECE (*move);      HashKey ^= hashcode[side][pawn][t];      HashKey ^= hashcode[side][cboard[t]][t];      PawnHashKey ^= hashcode[side][pawn][t];      board.material[side] += (Value[cboard[t]] - ValueP);      board.pmaterial[side] += Value[cboard[t]];   }   if (*move & ENPASSANT)	/* En passant */   {      ExchCnt[side]++;      epsq = board.ep + (side == white ? - 8 : 8);      CLEARBIT (board.b[xside][pawn], epsq);      CLEARBIT (board.blockerr90, r90[epsq]);      CLEARBIT (board.blockerr45, r45[epsq]);      CLEARBIT (board.blockerr315, r315[epsq]);      cboard[epsq] = empty;      HashKey ^= hashcode[xside][pawn][epsq];      PawnHashKey ^= hashcode[xside][pawn][epsq];      board.material[xside] -= ValueP;   }   if (*move & (CAPTURE | CASTLING) || fpiece == pawn)      Game50 = GameCnt;   if (*move & CASTLING) 	/* Castling */   {      if (t & 0x04)		/* King side */      {         rookf = t + 1;         rookt = t - 1;      }      else			/* Queen side */      {         rookf = t - 2;         rookt = t + 1;      }      a = &board.b[side][rook];      CLEARBIT (*a, rookf);      SETBIT (*a, rookt);      CLEARBIT (board.blockerr90, r90[rookf]);      SETBIT (board.blockerr90, r90[rookt]);      CLEARBIT (board.blockerr45, r45[rookf]);      SETBIT (board.blockerr45, r45[rookt]);      CLEARBIT (board.blockerr315, r315[rookf]);      SETBIT (board.blockerr315, r315[rookt]);      cboard[rookf] = empty;      cboard[rookt] = rook;      Mvboard[rookf] = 0;      Mvboard[rookt] = 1;      HashKey ^= hashcode[side][rook][rookf];      HashKey ^= hashcode[side][rook][rookt];      board.castled[side] = true;   }   /* If king or rook move, clear castle flag. */   if (side == white)   {      if (fpiece == king && board.flag & WCASTLE)      {	 if (board.flag & WKINGCASTLE)            HashKey ^= WKCastlehash;	 if (board.flag & WQUEENCASTLE)            HashKey ^= WQCastlehash;         board.flag &= ~WCASTLE;      }      else if (fpiece == rook)      {         if (f == H1)	 {	    if (board.flag & WKINGCASTLE)               HashKey ^= WKCastlehash;	    board.flag &= ~WKINGCASTLE;	 }         else if (f == A1) 	 {	    if (board.flag & WQUEENCASTLE)               HashKey ^= WQCastlehash;	    board.flag &= ~WQUEENCASTLE;	 }      }      if (tpiece == rook)      {         if (t == H8) 	 {	    if (board.flag & BKINGCASTLE)	       HashKey ^= BKCastlehash;	    board.flag &= ~BKINGCASTLE;         }         else if (t == A8) 	 {	    if (board.flag & BQUEENCASTLE)	       HashKey ^= BQCastlehash;	    board.flag &= ~BQUEENCASTLE;	 }      }   }   else   {      if (fpiece == king && board.flag & BCASTLE)      {	 if (board.flag & BKINGCASTLE)	    HashKey ^= BKCastlehash;	 if (board.flag & BQUEENCASTLE)	    HashKey ^= BQCastlehash;         board.flag &= ~BCASTLE;      }      else if (fpiece == rook)      {         if (f == H8) 	 {	    if (board.flag & BKINGCASTLE)	       HashKey ^= BKCastlehash;	    board.flag &= ~BKINGCASTLE;         }         else if (f == A8) 	 {	    if (board.flag & BQUEENCASTLE)	       HashKey ^= BQCastlehash;	    board.flag &= ~BQUEENCASTLE;	 }      }      if (tpiece == rook)      {         if (t == H1) 	 {	    if (board.flag & WKINGCASTLE)               HashKey ^= WKCastlehash;	    board.flag &= ~WKINGCASTLE;	 }         else if (t == A1) 	 {	    if (board.flag & WQUEENCASTLE)               HashKey ^= WQCastlehash;	    board.flag &= ~WQUEENCASTLE;	 }      }    }   /* If pawn move 2 squares, set ep passant square. */   if (fpiece == pawn && abs(f-t) == 16)   {      sq = (f + t) / 2;      board.ep = sq;      HashKey ^= ephash[sq];   }   else      board.ep = -1;   board.side = xside;   HashKey ^= Sidehash;   UpdateFriends ();   /* Update game record */   g->move = *move;   return;}void UnmakeMove (int side, int *move)/**************************************************************************** * *  To unmake a move on the board and update the various game information. *  Note that if side is black, then black is about to move, but we will be *  undoing a move by white, not black. * ****************************************************************************/{   BitBoard *a;   int f, t, fpiece, cpiece;      int rookf, rookt, epsq;   int xside;   GameRec *g;   side = 1^side;   xside = 1^side;   f = FROMSQ(*move);   t = TOSQ(*move);   fpiece = cboard[t];   cpiece = CAPTUREPIECE (*move);   a = &board.b[side][fpiece];   CLEARBIT (*a, t);   SETBIT (*a, f);      CLEARBIT (board.blockerr90, r90[t]);    SETBIT (board.blockerr90, r90[f]);    CLEARBIT (board.blockerr45, r45[t]);    SETBIT (board.blockerr45, r45[f]);    CLEARBIT (board.blockerr315, r315[t]);    SETBIT (board.blockerr315, r315[f]);    cboard[f] = cboard[t];   cboard[t] = empty;   g = &Game[GameCnt];   Mvboard[f] = Mvboard[t]-1;   Mvboard[t] = g->mvboard;   if (fpiece == king)      board.king[side] = f;      /* if capture, put back the captured piece */   if (*move & CAPTURE)   {      ExchCnt[side]--;      SETBIT (board.b[xside][cpiece], t);        SETBIT (board.blockerr90, r90[t]);        SETBIT (board.blockerr45, r45[t]);        SETBIT (board.blockerr315, r315[t]);        cboard[t] = cpiece;       board.material[xside] += Value[cpiece];        if (cpiece != pawn)         board.pmaterial[xside] += Value[cpiece];     }   /* Undo promotion */   if (*move & PROMOTION)   {      CLEARBIT (*a, f);      SETBIT (board.b[side][pawn], f);        cboard[f] = pawn;      board.material[side] += (ValueP - Value[PROMOTEPIECE (*move)]);       board.pmaterial[side] -= Value[PROMOTEPIECE (*move)];   }   /* Undo enpassant */   if (*move & ENPASSANT)   {      ExchCnt[side]--;      epsq = (side == white ? g->epsq - 8 : g->epsq + 8);      SETBIT (board.b[xside][pawn], epsq);       SETBIT (board.blockerr90, r90[epsq]);       SETBIT (board.blockerr45, r45[epsq]);       SETBIT (board.blockerr315, r315[epsq]);       cboard[epsq] = pawn;      board.material[xside] += ValueP;     }      /* if castling, undo rook move */   if (*move & CASTLING)   {      if (t & 0x04)		/* King side */      {         rookf = t + 1;         rookt = t - 1;      }      else			/* Queen side */      {         rookf = t - 2;         rookt = t + 1;      }      a = &board.b[side][rook];      CLEARBIT (*a, rookt);      SETBIT (*a, rookf);       CLEARBIT (board.blockerr90, r90[rookt]);      SETBIT (board.blockerr90, r90[rookf]);      CLEARBIT (board.blockerr45, r45[rookt]);      SETBIT (board.blockerr45, r45[rookf]);      CLEARBIT (board.blockerr315, r315[rookt]);      SETBIT (board.blockerr315, r315[rookf]);      cboard[rookf] = rook;      cboard[rookt] = empty;      Mvboard[rookf] = 0;      Mvboard[rookt] = 0;      board.castled[side] = false;   }   UpdateFriends ();   board.side = side;   board.ep = g->epsq;   board.flag = g->bflag;     HashKey = g->hashkey;   PawnHashKey = g->phashkey;   Game50 = g->Game50;   GameCnt--;   return;}void SANMove (int move, int ply)/**************************************************************************** * *  Convert the move to a SAN format.  GenMoves (ply) needs to be called *  by the calling routine for this to work. * ****************************************************************************/{   int side;   int piece, ambiguous;   int f, t;   BitBoard b;   leaf *node1;   char *s;   side = board.side;   s = SANmv;   f = FROMSQ(move);   t = TOSQ(move);   /* Check some special moves like castling */   if (move & CASTLING)   {      if (t == 6 || t == 62)         strcpy (s, "O-O");      else	 strcpy (s, "O-O-O");      return;   } /**************************************************************************** * *  Here split the code into 2 parts for clarity sake.  First part deals  *  with pawn moves only, 2nd part only piece moves.  However before doing  *  that, see if the move is ambiguous. * ****************************************************************************/   /*  AMBIGUITY CHECK  */   piece = cboard[f];   side = board.side;   b = board.b[side][piece];   ambiguous = false;   node1 = TreePtr[ply];   if (nbits (b) > 1)   {      /*        *  Scan the movelist to see if another same-type piece is       *  also moving to that particular to-square.       */      for (node1 = TreePtr[ply]; node1 < TreePtr[ply + 1]; node1++)      {         if (FROMSQ(node1->move) == f)            continue;                   /* original piece, skip */         if (TOSQ(node1->move) != t)            continue;                   /* diff to-square, skip */         if (cboard[FROMSQ(node1->move)] != piece)            continue;                   /* diff piece   */         ambiguous = true;	 break;      }   }   if (piece == pawn)   {      /* Capture or enpassant */      if (cboard[t] != 0 || board.ep == t)      {         *s++ = algbrfile [ROW (f)];	 *s++ = 'x';      }      strcpy (s, algbr[t]);      s += 2;      /* Promotion */      if (move & PROMOTION)      {         *s++ = '=';         *s++ = notation[PROMOTEPIECE (move)];      }   }   else	/* its not pawn */   {      *s++ = notation[piece];      if (ambiguous)      {         if (ROW (f) == ROW (FROMSQ(node1->move)))            *s++ = algbrrank[RANK (f)];	 else	    *s++ = algbrfile[ROW (f)];      }

⌨️ 快捷键说明

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