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

📄 eval.c

📁 一款运行在linux上的象棋游戏。用GTK/GNOME环境下用GLADE开发。
💻 C
📖 第 1 页 / 共 3 页
字号:
/* GNU Chess 5.0 - eval.c - evaluation 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 <string.h>#include <stdlib.h>#include "common.h"#include "eval.h"int LoneKing (int, int);int ScoreKBNK (int, int);int KPK (int);int BishopTrapped (short);int DoubleQR7 (short);BitBoard passed[2];BitBoard weaked[2];static int PawnSq[2][64] = {{  0,  0,  0,  0,  0,  0,  0,  0,   5,  5,  5,-10,-10,  5,  5,  5,  -2, -2, -2,  6,  6, -2, -2, -2,   0,  0,  0, 25, 25,  0,  0,  0,   2,  2, 12, 16, 16, 12,  2,  2,   4,  8, 12, 16, 16, 12,  4,  4,   4,  8, 12, 16, 16, 12,  4,  4,   0,  0,  0,  0,  0,  0,  0,  0},{  0,  0,  0,  0,  0,  0,  0,  0,   4,  8, 12, 16, 16, 12,  4,  4,   4,  8, 12, 16, 16, 12,  4,  4,   2,  2, 12, 16, 16, 12,  2,  2,   0,  0,  0, 25, 25,  0,  0,  0,  -2, -2, -2,  6,  6, -2, -2, -2,   5,  5,  5,-10,-10,  5,  5,  5,   0,  0,  0,  0,  0,  0,  0,  0}};static const int Passed[2][8] ={ { 0, 48, 48, 120, 144, 192, 240, 0}, {0, 240, 192, 144, 120, 48, 48, 0} };/* Penalties for one or more isolated pawns on a given file */static const int isolani_normal[8] = {  -8, -10, -12, -14, -14, -12, -10, -8};/* Penalties if the file is half-open (i.e. no enemy pawns on it) */static const int isolani_weaker[8] = {  -22, -24, -26, -28, -28, -26, -24, -22};static const BitBoard d2e2[2] =		 { ULL(0x0018000000000000), ULL(0x0000000000001800) };static const BitBoard brank7[2]  = { ULL(0x000000000000FF00),				     ULL(0x00FF000000000000) };static const BitBoard brank8[2]  = { ULL(0x00000000000000FF),				     ULL(0xFF00000000000000) };static const BitBoard brank67[2] = { ULL(0x0000000000FFFF00),				     ULL(0x00FFFF0000000000) };static const BitBoard brank58[2] = { ULL(0x00000000FFFFFFFF),				     ULL(0xFFFFFFFF00000000) };int ScoreP (short side)/*************************************************************************** * *  Pawn evaluation is based on the following factors (which is being *  constantly updated!). * *  1.  Pawn square tables. *  2.  Passed pawns. *  3.  Backward pawns. *  4.  Pawn base under attack. *  5.  Doubled pawns  *  6.  Isolated pawns  *  7.  Connected passed pawns on 6/7th rank. *  8.  Unmoved & blocked d, e pawn *  9.  Passed pawn which cannot be caught. *  10. Pawn storms. * ***************************************************************************/{   int xside;   int s, sq, i, i1;   int n1, n2, backward;   int nfile[8];   int EnemyKing;   BitBoard c, t, p, blocker, *e;   PawnSlot *ptable;   if (board.b[side][pawn] == NULLBITBOARD)      return (0);   xside = 1^side;   EnemyKing = board.king[xside];   p = board.b[xside][pawn];   c = t = board.b[side][pawn];   ptable = PawnTab[side] + (PawnHashKey & PHashMask);   TotalPawnHashCnt++;   if (ptable->phase == phase && ptable->pkey == KEY(PawnHashKey))   {      GoodPawnHashCnt++;      s = ptable->score;      passed[side] = ptable->passed;      weaked[side] = ptable->weaked;      goto phase2;    }   s = 0;   passed[side] = NULLBITBOARD;   weaked[side] = NULLBITBOARD;   memset (nfile, 0, sizeof (nfile));   while (t)   {      sq = leadz (t);      CLEARBIT (t, sq);      s += PawnSq[side][sq];       /*  Passed pawns  */      if ((p & PassedPawnMask[side][sq]) == NULLBITBOARD)      {	 if ((side == white && (FromToRay[sq][sq|56] & c) == 0) ||	     (side == black && (FromToRay[sq][sq&7] & c) == 0))          {            passed[side] |= BitPosArray[sq];            s += (Passed[side][RANK(sq)] * phase) / 12;         }      }      /*  Backward pawns */      backward = false;    /*   i = sq + (side == white ? 8 : -8); */      if ( side == white ) { 	 i = sq + 8;  }      else {         i= sq - 8; }      if (!(PassedPawnMask[xside][i] & ~FileBit[ROW(sq)] & c) &&	  cboard[i] != pawn)      {         n1 = nbits (c & MoveArray[ptype[xside]][i]);         n2 = nbits (p & MoveArray[ptype[side]][i]);         if (n1 < n2)            backward = true;      }      if (!backward && (BitPosArray[sq] & brank7[xside]))      {         i1 = 1;         i = i + (side == white ? 8 : -8);         if (!(PassedPawnMask[xside][i] & ~FileBit[ROW(i1)] & c))         {            n1 = nbits (c & MoveArray[ptype[xside]][i]);            n2 = nbits (p & MoveArray[ptype[side]][i]);            if (n1 < n2)               backward = true;         }      }      if (backward)      {         weaked[side] |= BitPosArray[sq];         s += BACKWARDPAWN;      }      /* Pawn base under attack */      if ((MoveArray[ptype[side]][sq] & p) && (MoveArray[ptype[side]][sq] & c))         s += PAWNBASEATAK;       /*  Increment file count for isolani & doubled pawn evaluation */      nfile[ROW(sq)]++;   }   for (i = 0; i <= 7; i++)   {      /* Doubled pawns */      if (nfile[i] > 1)         s += DOUBLEDPAWN;      /* Isolated pawns */      if (nfile[i] && (!(c & IsolaniMask[i])))      {	 /* Isolated on a half-open file */         if (!(FileBit[i] & board.b[xside][pawn]))	   s += isolani_weaker[i] * nfile[i];	 else /* Normal isolated pawn */           s += isolani_normal[i] * nfile[i];	 weaked[side] |= (c & FileBit[i]);      }   }  if (computerplays == side) {    /* Penalize having eight pawns */    if (nbits(board.b[computerplays][pawn]) == 8)        s += EIGHT_PAWNS;    /* Detect stonewall formation in enemy */    if (nbits(stonewall[xside] & board.b[xside][pawn]) == 3)      s += STONEWALL;    /* Locked pawns */    n = 0;    if (side == white)      n = nbits((c >> 8) & board.b[xside][pawn] &               boxes[1]);    else      n = nbits((c << 8) & board.b[xside][pawn] &               boxes[1]);    if (n > 1)      s += n * LOCKEDPAWNS;  }   /* Save the score into the pawn hash table */    ptable->pkey = KEY(PawnHashKey);   ptable->passed = passed[side];   ptable->weaked = weaked[side];   ptable->score = s;   ptable->phase = phase;/*************************************************************************** *   *  This section of the pawn code cannot be saved into the pawn hash as *  they depend on the position of other pieces.  So they have to be  *  calculated again. * ***************************************************************************/phase2:   /* Pawn on f6/c6 with Queen against castled king is very strong */   c = board.b[side][pawn];   sq = board.king[xside];   if (side == white && board.b[side][queen] && 	(BitPosArray[C6] | BitPosArray[F6]) & c)   {      if (c & BitPosArray[F6] && sq > H6 && distance[sq][G7]==1)         s += PAWNNEARKING;      if (c & BitPosArray[C6] && sq > H6 && distance[sq][B7]==1)         s += PAWNNEARKING;   }   else if (side == black && board.b[side][queen] &&	(BitPosArray[C3] | BitPosArray[F3]) & c)   {      if (c & BitPosArray[F3] && sq < A3 && distance[sq][G2]==1)         s += PAWNNEARKING;      if (c & BitPosArray[C3] && sq < A3 && distance[sq][B2]==1)         s += PAWNNEARKING;   }   /* Connected passed pawns on 6th or 7th rank */   t = passed[side] & brank67[side];   if (t && (board.pmaterial[xside] == ValueR || 	(board.pmaterial[xside] == ValueN &&	pieces[xside] == board.b[xside][knight])))   {      n1 = ROW(board.king[xside]);      n2 = RANK(board.king[xside]);      for (i = 0; i <= 6; i++)      {	 if (t & FileBit[i] && t & FileBit[i+1] && (n1 < i-1 || n1 > i+1 ||		(side == white && n2 < 4) || (side == black && n2 > 3)))            s += CONNECTEDPP;      }   }   /* Pawn on d2,e2/d7,e7 is blocked  */   blocker = board.friends[side] | board.friends[xside];   if (side == white && (((c & d2e2[white]) >> 8) & blocker))      s += BLOCKDEPAWN;   if (side == black && (((c & d2e2[black]) << 8) & blocker))      s += BLOCKDEPAWN;   /* Enemy has no pieces & King is outside of passed pawn square */   if (passed[side] && board.pmaterial[xside]==0)   {      e = board.b[xside];      i1 = board.king[xside];      p = passed[side];      while (p)      {         sq = leadz (p);	 CLEARBIT (p, sq);	 if (board.side == side)         {	    if (!(SquarePawnMask[side][sq] & board.b[xside][king]))	       s += ValueQ * Passed[side][RANK(sq)] / PFACTOR;         }         else if (!(MoveArray[king][i1] & SquarePawnMask[side][sq]))	    s += ValueQ * Passed[side][RANK(sq)] / PFACTOR;      }   }  /* If both sides are castled on different sides, bonus for pawn storms */  c = board.b[side][pawn];  if (abs (ROW (board.king[side]) - ROW (board.king[xside])) >= 4 &&	PHASE < 6)  {     n1 = ROW (board.king[xside]);     p = (IsolaniMask[n1] | FileBit[n1]) & c;     while (p)     {        sq = leadz (p);        CLEARBIT (p, sq);        s += 10 * (5 - distance[sq][board.king[xside]]);     }  }   return (s);}static const int Outpost[2][64] ={  { 0, 0, 0, 0, 0, 0, 0, 0,    0, 0, 0, 0, 0, 0, 0, 0,    0, 0, 0, 0, 0, 0, 0, 0,    0, 0, 1, 1, 1, 1, 0, 0,    0, 1, 1, 1, 1, 1, 1, 0,    0, 0, 1, 1, 1, 1, 0, 0,    0, 0, 0, 1, 1, 0, 0, 0,    0, 0, 0, 0, 0, 0, 0, 0 },  { 0, 0, 0, 0, 0, 0, 0, 0,    0, 0, 0, 1, 1, 0, 0, 0,    0, 0, 1, 1, 1, 1, 0, 0,    0, 1, 1, 1, 1, 1, 1, 0,    0, 0, 1, 1, 1, 1, 0, 0,    0, 0, 0, 0, 0, 0, 0, 0,    0, 0, 0, 0, 0, 0, 0, 0,    0, 0, 0, 0, 0, 0, 0, 0 }};static inline int CTL(short sq, short piece __attribute__ ((unused)), short side)/*************************************************************************** * *  Return a score corresponding to the number of squares in the bitboard *  target multiplied by a specified bonus for controlling each square. * *  Can be used for control of the center and attacks around the king. * ***************************************************************************/{  int s, n, EnemyKing, FriendlyKing;  BitBoard controlled;  s = 0;  EnemyKing = board.king[1^side];  FriendlyKing = board.king[side];  controlled = AttackXFrom (sq, side);  /* Center control */  n = nbits (controlled & boxes[0]);  s += 4*n;  /* Attacks against enemy king */  n = nbits (controlled & DistMap[EnemyKing][2]);  s += n;  /* Defenses for friendly king */  n = nbits (controlled & DistMap[FriendlyKing][2]);  s += n;  /* Mobility */  n = nbits(controlled);  s += 4*n;  return (s);}int ScoreN (short side)/*************************************************************************** * *  1.  central knight - distance from enemy king. *  2.  mobility/control/attack *  3.  outpost knight protected by pawn. *  4.  knight attacking weak pawns. * ***************************************************************************/{   int xside;   int s, s1, sq;   int EnemyKing;   BitBoard c, t;   if (board.b[side][knight] == NULLBITBOARD)      return (0);   xside = side^1;   s = s1 = 0;   c = board.b[side][knight];   t = board.b[xside][pawn];    EnemyKing = board.king[xside];   if ( c & pinned )   {	s += PINNEDKNIGHT * nbits(c & pinned);   }   while (c)   {      sq = leadz (c);      CLEARBIT (c, sq);      /* Control */      s1 = CTL(sq,knight,side);        if ( (BitPosArray[sq] & rings[3]) != NULLBITBOARD)	s1 += KNIGHTONRIM;      if (Outpost[side][sq] && 	  !(t & IsolaniMask[ROW(sq)] & PassedPawnMask[side][sq]) )      {         s1 += OUTPOSTKNIGHT;    	 /* Knight defended by own pawn */         if (MoveArray[ptype[xside]][sq] & board.b[side][pawn])            s1 += OUTPOSTKNIGHT;      }          /* Attack on weak opponent pawns */      if (MoveArray[knight][sq] & weaked[xside])         s1 += ATAKWEAKPAWN;      s += s1;   }   return (s);}int ScoreB (short side)/**************************************************************************** * *  1.  double bishops. *  2.  mobility/control/attack *  3.  outpost bishop *  4.  fianchetto bishop *  5.  Bishop pair * ****************************************************************************/{   int xside;   int s, s1, n, sq, EnemyKing;   BitBoard c, t;   if (board.b[side][bishop] == NULLBITBOARD)      return (0);   s = s1 = 0;   c = board.b[side][bishop];   xside = side ^ 1;   EnemyKing = board.king[xside];   n = 0;   t = board.b[xside][pawn];   if ( c & pinned )   {	s += PINNEDBISHOP * nbits(c & pinned);   }   while (c)   {      sq = leadz (c);      CLEARBIT (c, sq);      n++;      /* Control */      s1 = CTL(sq,bishop,side);      /*  Outpost bishop */      if (Outpost[side][sq] && 	  !(t & IsolaniMask[ROW(sq)] & PassedPawnMask[side][sq]))      {         s1 += OUTPOSTBISHOP;

⌨️ 快捷键说明

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