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

📄 move.c

📁 一款运行在linux上的象棋游戏。用GTK/GNOME环境下用GLADE开发。
💻 C
📖 第 1 页 / 共 2 页
字号:
      if (cboard[t] != 0)		/* capture */         *s++ = 'x';       strcpy (s, algbr[t]);      s += 2;   }   /* See if it is a checking or mating move */   MakeMove (side, &move);   if (SqAtakd (board.king[1^side], side))   {      TreePtr[ply+2] = TreePtr[ply+1];      GenCheckEscapes (ply+1);      if (TreePtr[ply+1] == TreePtr[ply+2])         *s++ = '#';      else         *s++ = '+';      GenCnt -= TreePtr[ply+2] - TreePtr[ply+1];   }   UnmakeMove (1^side, &move);    *s = '\0';   return;}#define ASCIITOFILE(a) ((a) - 'a')#define ASCIITORANK(a) ((a) - '1')#define ASCIITOSQ(a,b) (ASCIITOFILE(a)) + (ASCIITORANK(b)) * 8#define ATOH(a) ((a) >= 'a' && (a) <= 'h')#define ITO8(a) ((a) >= '1' && (a) <= '8')inline int piece_id(const char c){/* Given c, what is the piece id.  This only takes one char, which * isn't enough to handle two-character names (common in Russian text * and old English notation that used Kt), but we're not supposed to * see such text here anyway.  This will * accept "P" for pawn, and many lowercase chars (but not "b" for Bishop). */   switch (c)   {      case 'n':      case 'N':         return knight;      case 'B':         return bishop;      case 'r':      case 'R':         return rook;      case 'q':      case 'Q':         return queen;      case 'k':      case 'K':         return king;      case 'p':      case 'P':         return pawn;   }   return empty;}leaf * ValidateMove (char *s)/************************************************************************* * *  This routine takes a string and check to see if it is a legal move. *  Note.  At the moment, we accept 2 types of moves notation. *  1.  e2e4 format.   2. SAN format. (e4) * **************************************************************************/{   short f, t, side, rank, file, fileto;   short piece, piece2, kount;   char promote;   char mvstr[MAXSTR], *p;   BitBoard b, b2;   leaf *n1, *n2;   TreePtr[2] = TreePtr[1];   GenMoves (1);      FilterIllegalMoves (1);	   side = board.side;   /************************************************************************    * The thing to do now is to clean up the move string.  This    * gets rid of things like 'x', '+', '=' and so forth.    ************************************************************************/   p = mvstr;   do   {      if (*s != 'x' && *s != '+' && *s != '=' && !isspace(*s))         *p++ = *s;    } while (*s++ != '\0' );   /* Flush castles that check */   if (mvstr[strlen(mvstr)-1] == '+' || mvstr[strlen(mvstr)-1] == '#' ||       mvstr[strlen(mvstr)-1] == '=') mvstr[strlen(mvstr)-1] = '\000';    /* Check for castling */   if (strcmp (mvstr, "O-O") == 0 || strcmp (mvstr, "o-o") == 0 ||        strcmp (mvstr, "0-0") == 0)   {      if (side == white)      {         f = 4; t = 6;      }      else       {	 f = 60; t = 62;      }      return (IsInMoveList (1, f, t, ' '));   }   if (strcmp (mvstr, "O-O-O") == 0 || strcmp (mvstr, "o-o-o") == 0 ||       strcmp (mvstr, "0-0-0") == 0)   {      if (side == white)      {         f = 4; t = 2;      }      else      {         f = 60; t = 58;      }      return (IsInMoveList (1, f, t, ' '));   }   /*  Test to see if it is e2e4 type notation */   if (ATOH (mvstr[0]) && ITO8 (mvstr[1]) && ATOH (mvstr[2]) &&	ITO8 (mvstr[3]))   {      f = ASCIITOSQ (mvstr[0], mvstr[1]);      t = ASCIITOSQ (mvstr[2], mvstr[3]);      piece = (strlen (mvstr) == 5 ? mvstr[4] : ' ');      return (IsInMoveList (1, f, t, piece));   }   /***********************************************************************    *  Its a SAN notation move.  More headache!      *  We generate all the legal moves and start comparing them with    *  the input move.    ***********************************************************************/   if (ATOH (mvstr[0]))	/* pawn move */   {      if (ITO8 (mvstr[1]))					/* e4 type */      {	 t = ASCIITOSQ (mvstr[0], mvstr[1]);         f = t + (side == white ? -8 : 8);         /* Add Sanity Check */         if ( f > 0 && f < 64 ) {	   if (BitPosArray[f] & board.b[side][pawn])           {              if (mvstr[2] != '\0')                  return (IsInMoveList (1, f, t, mvstr[2]));              else                 return (IsInMoveList (1, f, t, ' '));           }           f = t + (side == white ? -16 : 16);           if ( f > 0 && f < 64 ) {	     if (BitPosArray[f] & board.b[side][pawn])                return (IsInMoveList (1, f, t, ' '));	   } /* End bound check +/- 16 */	 } /* End bound check +/- 8 */        }      else if (ATOH (mvstr[1]) && ITO8 (mvstr[2]))		/* ed4 type */      {	 t = ASCIITOSQ (mvstr[1], mvstr[2]);	 rank = ASCIITORANK (mvstr[2]) + (side == white ? -1 : 1);         f = rank * 8 + ASCIITOFILE (mvstr[0]);         piece = (strlen (mvstr) == 4 ? mvstr[3] : ' ');         return (IsInMoveList (1, f, t, piece));      }      else if (ATOH (mvstr[1]))					/* ed type */      {         file = ASCIITOFILE (mvstr[0]);         fileto = ASCIITOFILE (mvstr[1]);	 b = board.b[side][pawn] & FileBit[file];	 if (side == white)	    b = b >> (fileto < file ? 7 : 9);         else	    b = b << (fileto < file ? 9 : 7);         if (board.ep > -1)	    b = b & (board.friends[1^side] | BitPosArray[board.ep]);         else	    b = b & (board.friends[1^side]);         switch (nbits (b))	 {	    case 0  : return ((leaf *) NULL);	    case 1  : t = leadz (b);	    	      f = t - (side == white ? 8 : -8) + (file - fileto);         	      piece = (strlen (mvstr) == 3 ? mvstr[2] : ' ');	    	      return (IsInMoveList (1, f, t, piece));	    default : 		      printf ("Ambiguous move: %s %s\n",s,mvstr);		      ShowBoard();/*		      getchar();*/	    	      return ((leaf *) NULL);	 }      }    }    else	if ((piece = piece_id(mvstr[0])) != empty &&            (piece_id(mvstr[1]) == empty))	/* Is a piece move */   {      /* Since piece_id accepts P as pawns, this will correctly       * handle malformed commands like Pe4 */      b = board.b[side][piece];      t = -1;      if (ITO8 (mvstr[1]))				/* N1d2 type move */      {         rank = ASCIITORANK (mvstr[1]);	 b &= RankBit[rank];	 t = ASCIITOSQ (mvstr[2], mvstr[3]);      }      else if (ATOH (mvstr[1]) && ATOH (mvstr[2]))	/* Nbd2 type move */      {         file = ASCIITOFILE (mvstr[1]);	 b &= FileBit[file];	 t = ASCIITOSQ (mvstr[2], mvstr[3]);      }      else if (ATOH (mvstr[1]) && ITO8 (mvstr[2]))	/* Nd2 type move */      {	 t = ASCIITOSQ (mvstr[1], mvstr[2]);      }      kount = 0;      n1 = n2 = (leaf *) NULL;      while (b)      {         f = leadz (b); 	 CLEARBIT (b, f);	 if ((n1 = IsInMoveList (1, f, t, ' ')) != (leaf *) NULL )	 {	    n2 = n1;	    kount++;	 }      }      if (kount > 1)      {	 printf ("Ambiguous move: %s %s\n",s,mvstr);	 ShowBoard();/*	 getchar();*/   	 return ((leaf *) NULL);      }       else if (kount == 0)   	 return ((leaf *) NULL);      else         return (n2);   }   else	if (((piece = piece_id(mvstr[0])) != empty) &&            ((piece2 = piece_id(mvstr[1])) != empty) &&	    ( (mvstr[2] == '\0') ||	      ((piece_id(mvstr[2]) != empty) && mvstr[3] == '\0')))   { /* KxP format */      promote = ' ';      if (piece_id(mvstr[2] != empty)) {          promote = mvstr[2];      }      kount = 0;      n1 = n2 = (leaf *) NULL;      b = board.b[side][piece];      while (b)      {         f = leadz (b); 	 CLEARBIT (b, f);         b2 = board.b[1^side][piece2];	 while (b2)	 {           t = leadz (b2); 	   CLEARBIT (b2, t);	   printf("Trying %s: ", AlgbrMove(MOVE(f,t)));	   if ((n1 = IsInMoveList (1, f, t, promote)) != (leaf *) NULL)	   {	     n2 = n1;	     kount++;	     printf("Y  ");	   }	   else printf("N  ");	 }      }      if (kount > 1)      {	 printf ("Ambiguous move: %s %s\n",s,mvstr);	 ShowBoard();/*	 getchar();*/   	 return ((leaf *) NULL);      }       else if (kount == 0)   	 return ((leaf *) NULL);      else         return (n2);         }   /* Fall through.  Nothing worked, return that no move was performed. */   return ((leaf *) NULL);}leaf * IsInMoveList (int ply, int f, int t, char piece)/************************************************************************** * *  Checks to see if from and to square can be found in the movelist *  and is legal. * **************************************************************************/{   leaf *node;   for (node = TreePtr[ply]; node < TreePtr[ply + 1]; node++)   {      if ((int) (node->move & 0x0FFF) == MOVE(f,t)  && 	toupper(piece) == notation[PROMOTEPIECE (node->move)])         return (node);   }   return ((leaf *) NULL);}int IsLegalMove (int move)/***************************************************************************** * *  Check that a move is legal on the current board.   *  Perform some preliminary sanity checks. *  1.  If from square is emtpy, illegal. *  2.  Piece not of right color. *  3.  To square is friendly, illegal. *  4.  Promotion move or enpassant, so piece must be pawn. *  5.  Castling move, piece must be king. *  Note that IsLegalMove() no longer care about if a move will place the *  king in check.  This will be caught by the Search(). * *****************************************************************************/{   int side;   int f, t, piece;   BitBoard blocker, enemy;   f = FROMSQ(move);    t = TOSQ(move);   /*  Empty from square  */   if (cboard[f] == empty)      return (false);   /*  Piece is not right color  */   side = board.side;   if (!(BitPosArray[f] & board.friends[side]))      return (false);   /*  TO square is a friendly piece, so illegal move  */   if (BitPosArray[t] & board.friends[side])      return (false);   piece = cboard[f];   /*  If promotion move, piece must be pawn */   if ((move & (PROMOTION | ENPASSANT)) && piece != pawn)      return (false);   /*  If enpassant, then the enpassant square must be correct */   if ((move & ENPASSANT) && t != board.ep)      return (false);   /*  If castling, then make sure its the king */   if ((move & CASTLING) && piece != king)      return (false);    blocker = board.blocker;   /*  Pawn moves need to be handle specially  */   if (piece == pawn)   {      if ((move & ENPASSANT) && board.ep > -1)         enemy = board.friends[1^side] | BitPosArray[board.ep];      else         enemy = board.friends[1^side];      if (side == white)      {         if (!(MoveArray[pawn][f] & BitPosArray[t] & enemy) &&             !(t - f == 8 && cboard[t] == empty) &&             !(t - f == 16 && RANK(f) == 1 && !(FromToRay[f][t] & blocker)))	    return (false);      }      else if (side == black)      {         if (!(MoveArray[bpawn][f] & BitPosArray[t] & enemy) &&             !(t - f == -8 && cboard[t] == empty) &&             !(t - f == -16 && RANK(f) == 6 && !(FromToRay[f][t] & blocker)))	    return (false);      }   }   /*  King moves are also special, especially castling  */   else if (piece == king)   {      if (side == white)      {         if (!(MoveArray[piece][f] & BitPosArray[t]) &&	     !(f == E1 && t == G1 && board.flag & WKINGCASTLE &&	       !(FromToRay[E1][G1] & blocker) && !SqAtakd(E1,black) &&		!SqAtakd(F1,black)) &&	     !(f == E1 && t == C1 && board.flag & WQUEENCASTLE &&	       !(FromToRay[E1][B1] & blocker) && !SqAtakd(E1,black) &&		!SqAtakd(D1,black)))            return (false);      }      if (side == black)      {         if (!(MoveArray[piece][f] & BitPosArray[t]) &&	     !(f == E8 && t == G8 && board.flag & BKINGCASTLE &&	       !(FromToRay[E8][G8] & blocker) && !SqAtakd(E8,white) &&		!SqAtakd(F8,white)) &&	     !(f == E8 && t == C8 && board.flag & BQUEENCASTLE &&	       !(FromToRay[E8][B8] & blocker) && !SqAtakd(E8,white) &&		!SqAtakd(D8,white)))            return (false);      }   }   else    {      if (!(MoveArray[piece][f] & BitPosArray[t]))         return (false);   }   /*  If there is a blocker on the path from f to t, illegal move  */   if (slider[piece])   {      if (FromToRay[f][t] & NotBitPosArray[t] & blocker)         return (false);   }   return (true);}char *AlgbrMove (int move)/***************************************************************************** * *  Convert an int move format to algebraic format of g1f3. * *****************************************************************************/{   int f, t;   static char s[6];   f = FROMSQ(move);   t = TOSQ(move);   strcpy (s, algbr[f]);   strcpy (s+2, algbr[t]);   if (move & PROMOTION)   {      if (flags & XBOARD)        s[4] = lnotation[PROMOTEPIECE (move)];      else        s[4] = notation[PROMOTEPIECE (move)];      s[5] = '\0';   }   else      s[4] = '\0';   return (s);}

⌨️ 快捷键说明

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