📄 swap.c
字号:
/* GNU Chess 5.0 - swap.c - static exchange evaluator 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 "common.h"
static const int xray[7] = { 0, 1, 0, 1, 1, 1, 0 };
int SwapOff (int move)
/****************************************************************************
*
* A Static Exchange Evaluator (or SEE for short).
* First determine the target square. Create a bitboard of all squares
* attacking the target square for both sides. Using these 2 bitboards,
* we take turn making captures from smallest piece to largest piece.
* When a sliding piece makes a capture, we check behind it to see if
* another attacker piece has been exposed. If so, add this to the bitboard
* as well. When performing the "captures", we stop if one side is ahead
* and doesn't need to capture, a form of pseudo-minimaxing.
*
****************************************************************************/
{
int f, t, sq, piece, lastval;
int side, xside;
int swaplist[MAXPLYDEPTH], n;
BitBoard b, c, *d, *e, r;
f = FROMSQ (move);
t = TOSQ (move);
side = ((board.friends[white] & BitPosArray[f]) ? white : black);
xside = 1^side;
/* Squares attacking t for side and xside */
b = AttackTo (t, side);
c = AttackTo (t, xside);
CLEARBIT(b, f);
if (xray[cboard[f]])
AddXrayPiece (t, f, side, &b, &c);
d = board.b[side];
e = board.b[xside];
if (move & PROMOTION)
{
swaplist[0] = Value[PROMOTEPIECE (move)] - ValueP;
lastval = -Value[PROMOTEPIECE (move)];
}
else
{
swaplist[0] = (move & ENPASSANT ? ValueP : Value[cboard[t]]);
lastval = -Value[cboard[f]];
}
n = 1;
while (1)
{
if (c == NULLBITBOARD)
break;
for (piece = pawn; piece <= king; piece++)
{
r = c & e[piece];
if (r)
{
sq = leadz (r);
CLEARBIT (c, sq);
if (xray[piece])
AddXrayPiece (t, sq, xside, &c, &b);
swaplist[n] = swaplist[n-1] + lastval;
n++;
lastval = Value[piece];
break;
}
}
if (b == NULLBITBOARD)
break;
for (piece = pawn; piece <= king; piece++)
{
r = b & d[piece];
if (r)
{
sq = leadz (r);
CLEARBIT (b, sq);
if (xray[piece])
AddXrayPiece (t, sq, side, &b, &c);
swaplist[n] = swaplist[n-1] + lastval;
n++;
lastval = -Value[piece];
break;
}
}
}
/****************************************************************************
*
* At this stage, we have the swap scores in a list. We just need to
* mini-max the scores from the bottom up to the top of the list.
*
****************************************************************************/
--n;
while (n)
{
if (n & 1)
{
if (swaplist[n] <= swaplist[n-1])
swaplist[n-1] = swaplist[n];
}
else
{
if (swaplist[n] >= swaplist[n-1])
swaplist[n-1] = swaplist[n];
}
--n;
}
return (swaplist[0]);
}
void AddXrayPiece (int t, int sq, int side, BitBoard *b, BitBoard *c)
/***************************************************************************
*
* The purpose of this routine is to find a piece which attack through
* another piece (e.g. two rooks, Q+B, B+P, etc.) Side is the side attacking
* the square where the swapping is to be done.
*
***************************************************************************/
{
int dir, nsq, piece;
BitBoard a;
dir = directions[t][sq];
a = Ray[sq][dir] & board.blocker;
if (a == NULLBITBOARD)
return;
nsq = (t < sq ? leadz (a) : trailz (a));
piece = cboard[nsq];
if ((piece == queen) || (piece == rook && dir > 3) ||
(piece == bishop && dir < 4))
{
if (BitPosArray[nsq] & board.friends[side])
*b |= BitPosArray[nsq];
else
*c |= BitPosArray[nsq];
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -