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

📄 epd.c

📁 一款运行在linux上的象棋游戏。用GTK/GNOME环境下用GLADE开发。
💻 C
字号:
/* GNU Chess 5.0 - epd.c - EPD position definition 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*//* * */#include <stdio.h>#include <string.h>#include <ctype.h>#include "common.h"#define EPDCLOSE 1short ReadEPDFile (const char *file, short op)/**************************************************************************** * *  Reads in an EPD file.  The first call will read the first EPD line, *  the second call will read the 2nd line and so on.   To improve *  performance, the file is never closed.  Closing of the file happens *  only on 2 conditions:  (i) A ReadEPDFile failed because there is no  *  more lines to read.  (ii) A called to ReadEPDFile to explicitly  *  request that the file is closed (op = EPDCLOSE); *  If op == 2, then we work silently. * ****************************************************************************/{   static FILE *fp = NULL;   char line[MAXSTR];   /*  If first time through, must open file  */   if (fp == NULL)   {      fp = fopen (file, "r");      if (fp == NULL)      {         printf ("Error opening file %s\n", file);         return (false);      }   }   /*  Is this a close request? */   if (op == EPDCLOSE)      {       fclose (fp);      fp = NULL;      return (false);   }next_line:   /*  Okay, we read in an EPD entry  */   fgets (line, MAXSTR-1, fp);   if (!feof(fp))    {      int ret = ParseEPD (line);      /* For now just ignore malformed lines */      if (ret != EPD_SUCCESS) goto next_line;      if (op != 2)         printf ("\n%s : Best move = %s\n", id, solution);      return (true);   }   /* finished, must close file */   else   {       fclose (fp);      fp = NULL;      return (false);   }}/* * Returns EPD_SUCCESS on success, EPD_ERROR on error. We try to be * quite tough on the format. However, as of yet no legality checking * is done and the board is not reset on error, this should be done by * the caller. */int ParseEPD (char *p)/************************************************************************** *    *  Parses an EPD input line.  A few global variables are updated e.g. *  current board, side to move, en passant, castling status, etc. * **************************************************************************/{   int r, c, sq;   char *str_p;   r = 56;   c = 0;   memset (&board, 0, sizeof (board));   while (p && *p != ' ')   {     sq = r + c;     switch (*p)     {        case 'P' :  SETBIT (board.b[white][pawn], sq);		    SETBIT (board.blockerr90, r90[sq]);		    SETBIT (board.blockerr45, r45[sq]);		    SETBIT (board.blockerr315, r315[sq]);		    board.material[white] += ValueP;		    break;	        case 'N' :  SETBIT (board.b[white][knight], sq);		    SETBIT (board.blockerr90, r90[sq]);		    SETBIT (board.blockerr45, r45[sq]);		    SETBIT (board.blockerr315, r315[sq]);		    board.material[white] += ValueN;		    break;	        case 'B' :  SETBIT (board.b[white][bishop], sq);		    SETBIT (board.blockerr90, r90[sq]);		    SETBIT (board.blockerr45, r45[sq]);		    SETBIT (board.blockerr315, r315[sq]);		    board.material[white] += ValueB;		    break;	        case 'R' :  SETBIT (board.b[white][rook], sq);		    SETBIT (board.blockerr90, r90[sq]);		    SETBIT (board.blockerr45, r45[sq]);		    SETBIT (board.blockerr315, r315[sq]);		    board.material[white] += ValueR;		    break;	        case 'Q' :  SETBIT (board.b[white][queen], sq);		    SETBIT (board.blockerr90, r90[sq]);		    SETBIT (board.blockerr45, r45[sq]);		    SETBIT (board.blockerr315, r315[sq]);		    board.material[white] += ValueQ;		    break;	        case 'K' :  SETBIT (board.b[white][king], sq);		    SETBIT (board.blockerr90, r90[sq]);		    SETBIT (board.blockerr45, r45[sq]);		    SETBIT (board.blockerr315, r315[sq]);		    break;	        case 'p' :  SETBIT (board.b[black][pawn], sq);		    SETBIT (board.blockerr90, r90[sq]);		    SETBIT (board.blockerr45, r45[sq]);		    SETBIT (board.blockerr315, r315[sq]);		    board.material[black] += ValueP;		    break;	        case 'n' :  SETBIT (board.b[black][knight], sq);		    SETBIT (board.blockerr90, r90[sq]);		    SETBIT (board.blockerr45, r45[sq]);		    SETBIT (board.blockerr315, r315[sq]);		    board.material[black] += ValueN;		    break;	        case 'b' :  SETBIT (board.b[black][bishop], sq);		    SETBIT (board.blockerr90, r90[sq]);		    SETBIT (board.blockerr45, r45[sq]);		    SETBIT (board.blockerr315, r315[sq]);		    board.material[black] += ValueB;		    break;	        case 'r' :  SETBIT (board.b[black][rook], sq);		    SETBIT (board.blockerr90, r90[sq]);		    SETBIT (board.blockerr45, r45[sq]);		    SETBIT (board.blockerr315, r315[sq]);		    board.material[black] += ValueR;		    break;	        case 'q' :  SETBIT (board.b[black][queen], sq);		    SETBIT (board.blockerr90, r90[sq]);		    SETBIT (board.blockerr45, r45[sq]);		    SETBIT (board.blockerr315, r315[sq]);                    board.material[black] += ValueQ;		    break;	        case 'k' :  SETBIT (board.b[black][king], sq);		    SETBIT (board.blockerr90, r90[sq]);		    SETBIT (board.blockerr45, r45[sq]);		    SETBIT (board.blockerr315, r315[sq]);		    break;	        case '/' :  r -= 8;	 	    c = -1;		    break;        default  :  break;     }     if (isdigit (*p))        c += (*p - '0');     else        c++;     /*       * Special case, a trailing "/" is accepted on the      * end of the board settings.      */     if (r == -8 && p[1] == ' ')	     r = 0;     if (r < 0 || c > 8) return EPD_ERROR;     if (c == 8 && p[1] != '/' && p[1] != ' ') return EPD_ERROR;     p++;   }   board.pmaterial[white] = board.material[white] - 				nbits(board.b[white][pawn]) * ValueP;   board.pmaterial[black] = board.material[black] - 				nbits(board.b[black][pawn]) * ValueP;   board.king[white] = leadz (board.b[white][king]);   board.king[black] = leadz (board.b[black][king]);   UpdateFriends ();    UpdateCBoard ();   UpdateMvboard ();   /*  Get side to move  */   if (!++p) return EPD_ERROR;   if      (*p == 'w') board.side = white;    else if (*p == 'b') board.side = black;   else return EPD_ERROR;   /* Isn't this one cute? */   if (!++p || *p != ' ' || !++p) return EPD_ERROR;     /*  Castling status  */   while (p && *p != ' ') {      if      (*p == 'K') board.flag |= WKINGCASTLE;      else if (*p == 'Q') board.flag |= WQUEENCASTLE;      else if (*p == 'k') board.flag |= BKINGCASTLE;      else if (*p == 'q') board.flag |= BQUEENCASTLE;      else if (*p == '-') { p++; break; }      else return EPD_ERROR;      p++;   }   if (!p || *p != ' ' || !++p) return EPD_ERROR;   /*    * En passant square, can only be '-' or [a-h][36]    * In fact, one could add more sanity checks here.    */   if (*p != '-') {      if (!p[1] || *p < 'a' || *p > 'h' ||	  !(p[1] == '3' || p[1] == '6')) return EPD_ERROR;      board.ep = (*p - 'a') + (p[1] - '1')*8;      p++;   } else {      board.ep = -1;   }   solution[0] = '\0';   id[0] = '\0';   if (!++p) return EPD_SUCCESS;   /* The opcodes are optional, so we should not generate errors here */   /*  Read in best move; "bm" operator */   str_p = strstr(p, "bm");   if (str_p) sscanf (str_p, "bm %63[^;];", solution);    /*  Read in the description; "id" operator */   str_p = strstr(p, "id");   if (str_p) sscanf (p, "id %31[^;];", id);   CalcHashKey ();   phase = PHASE;   return EPD_SUCCESS;}void LoadEPD (char *p)/************************************************************************** *    *  This routine reads in the next or the Nth position in the file. * **************************************************************************/{   char file[MAXSTR];   int N = 1;   sscanf (p, "%31s %d ", file, &N);   if (strcmp (file, "next") == 0)   {      ReadEPDFile (file, 0);   }   else   {       ReadEPDFile (file, 1);      while (--N)      {         if (ReadEPDFile (file, 2) == false)         {	    printf ("File position exceeded\n");	    return;          }      }      ReadEPDFile (file, 0);   }   ShowBoard ();   NewPosition ();}void SaveEPD (char *p)/************************************************************************** *    *  This routine appends the current position in EPD format into a file. * **************************************************************************/{   char file[MAXSTR];   FILE *fp;   int r, c, sq, k;   char c1;   sscanf (p, "%s ", file);   fp = fopen (file, "a");   for (r = A8; r >= A1; r -= 8)   {      k = 0;      for (c = 0; c < 8; c++)      {         sq = r + c;	 if (cboard[sq] == empty)	    k++;	 else	 {	    if (k) 	       fprintf (fp, "%1d", k);	    k = 0;	    c1 = notation[cboard[sq]];	    if (BitPosArray[sq] & board.friends[black])	       c1 = tolower (c1);	    fprintf (fp, "%c", c1);	 }      }      if (k)	 fprintf (fp, "%1d", k);      if (r > A1)         fprintf (fp, "/");   }   /* Print other stuff */   fprintf (fp, (board.side == white ? " w " : " b "));   if (board.flag & WKINGCASTLE)      fprintf (fp, "K");   if (board.flag & WQUEENCASTLE)      fprintf (fp, "Q");   if (board.flag & BKINGCASTLE)      fprintf (fp, "k");   if (board.flag & BQUEENCASTLE)      fprintf (fp, "q");   if (!(board.flag & (WCASTLE | BCASTLE)))      fprintf (fp, "-");   fprintf (fp, " %s", (board.ep > -1 ? algbr[board.ep] : "-"));   fprintf (fp, " bm 1; id 1;");   fprintf (fp, "\n");   fclose (fp);}

⌨️ 快捷键说明

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