📄 movgen.cpp
字号:
if (Board[move->new1].piece == empty)
if (Board[castsq].piece == empty)
if ((move->new1 > move->old) || (Board[move->new1-1].piece
== empty))
/* Are the squares unattacked */
if (!Attacks(Opponent, move->old))
if (!Attacks(Opponent, move->new1))
if (!Attacks(Opponent, castsq))
killmov = 1;
}
}
else
{
if (move->spe && (move->movpiece == pawn))
{
/* E.p. capture */
/* Was the Opponent's move a 2 square move? */
if (MovTab[Depth-1].movpiece == pawn)
if (abs(MovTab[Depth-1].new1 - MovTab[Depth-1].old) >= 0x20)
if ((Board[move->old].piece == pawn) && (Board[move->old].color
== Player))
killmov = (move->new1 == ((MovTab[Depth-1].new1
+ MovTab[Depth-1].old) / 2));
}
else
{
if (move->spe) /* Normal test */
{
promote = move->movpiece; /* Pawnpromotion */
move->movpiece = pawn;
}
/* Is the content of Old and New1 squares correct? */
if (Board[move->old].piece == move->movpiece)
if (Board[move->old].color == Player)
if (Board[move->new1].piece == move->content)
if (move->content == empty || Board[move->new1].color == Opponent)
{
if (move->movpiece == pawn) /* Is the move possible? */
{
if (abs(move->new1 - move->old) < 0x20)
killmov = 1;
else
killmov = Board[(move->new1+move->old) / 2].piece == empty;
}
else
killmov = PieceAttacks(move->movpiece, Player,
move->old, move->new1);
}
if (move->spe)
move->movpiece = promote;
}
}
return killmov;
}
/*
* Store a move in buffer
*/
static void Generate(void)
{
BufCount++;
Buffer[BufCount] = Next;
}
/*
* Generates pawnpromotion
*/
static void PawnPromotionGen(void)
{
PIECETYPE promote;
Next.spe = 1;
for (promote = queen; promote <= knight; ((int)promote)++)
{
Next.movpiece = promote;
Generate();
}
Next.spe = 0;
}
/*
* Generates captures of the piece on new1 using PieceTab
*/
static void CapMovGen(void)
{
EDGESQUARETYPE nextsq, sq;
INDEXTYPE i;
Next.spe = 0;
Next.content = Board[Next.new1].piece;
Next.movpiece = pawn;
nextsq = Next.new1 - PawnDir[Player];
for (sq = nextsq-1; sq <= nextsq+1; sq++)
if (sq != nextsq)
if ((sq & 0x88) == 0)
if (Board[sq].piece == pawn && Board[sq].color == Player)
{
Next.old = sq;
if (Next.new1 < 8 || Next.new1 >= 0x70)
PawnPromotionGen();
else
Generate();
}
/* Other captures, starting with the smallest pieces */
for (i = OfficerNo[Player]; i >= 0; i--)
if (PieceTab[Player][i].ipiece != empty && PieceTab[Player][i].ipiece
!= pawn)
if (PieceAttacks(PieceTab[Player][i].ipiece, Player,
PieceTab[Player][i].isquare, Next.new1))
{
Next.old = PieceTab[Player][i].isquare;
Next.movpiece = PieceTab[Player][i].ipiece;
Generate();
}
}
/*
* generates non captures for the piece on old
*/
static void NonCapMovGen(void)
{
DIRTYPE first, last, dir;
int direction;
EDGESQUARETYPE newsq;
Next.spe = 0;
Next.movpiece = Board[Next.old].piece;
Next.content = empty;
switch (Next.movpiece)
{
case king :
for (dir = 7; dir >= 0; dir--)
{
newsq = Next.old + DirTab[dir];
if (!(newsq & 0x88))
if (Board[newsq].piece == empty)
{
Next.new1 = newsq;
Generate();
}
}
break;
case knight :
for (dir = 7; dir >= 0; dir--)
{
newsq = Next.old + KnightDir[dir];
if (!(newsq & 0x88))
if (Board[newsq].piece == empty)
{
Next.new1 = newsq;
Generate();
}
}
break;
case queen :
case rook :
case bishop:
first = 7;
last = 0;
if (Next.movpiece == rook) first = 3;
if (Next.movpiece == bishop) last = 4;
for (dir = first; dir >= last; dir--)
{
direction = DirTab[dir];
newsq = Next.old + direction;
/* Generate all non captures in the direction */
while (!(newsq & 0x88))
{
if (Board[newsq].piece != empty) goto TEN;
Next.new1 = newsq;
Generate();
newsq = Next.new1 + direction;
}
TEN: continue;
}
break;
case pawn :
Next.new1 = Next.old + PawnDir[Player]; /* one square forward */
if (Board[Next.new1].piece == empty)
{
if (Next.new1 < 8 || Next.new1 >= 0x70)
PawnPromotionGen();
else
{
Generate();
if (Next.old < 0x18 || Next.old >= 0x60)
{
Next.new1 += (Next.new1 - Next.old); /* 2 squares forward */
if (Board[Next.new1].piece == empty) Generate();
}
}
}
} /* switch */
}
/*
* The move generator.
* InitMovGen generates all possible moves and places them in a buffer.
* Movgen will the generate the moves one by one and place them in next.
*
* On entry:
* Player contains the color to move.
* MovTab[Depth-1] the las performed move.
*
* On exit:
* Buffer contains the generated moves.
*
* The moves are generated in the order :
* Captures
* Castlings
* Non captures
* E.p. captures
*/
void InitMovGen(void)
{
CASTDIRTYPE castdir;
EDGESQUARETYPE sq;
INDEXTYPE index;
BufCount = BufPnt = 0;
/* generate all captures starting with captures of
largest pieces */
for (index = 1; index <= PawnNo[Opponent]; index++)
if (PieceTab[Opponent][index].ipiece != empty)
{
Next.new1 = PieceTab[Opponent][index].isquare;
CapMovGen();
}
Next.spe = 1;
Next.movpiece = king;
Next.content = empty;
for (castdir = CASTDIRTYPE(lng-1); castdir <= shrt-1; ((int)castdir)++)
{
Next.new1 = CastMove[Player][castdir].castnew;
Next.old = CastMove[Player][castdir].castold;
if (KillMovGen(&Next)) Generate();
}
/* generate non captures, starting with pawns */
for (index = PawnNo[Player]; index >= 0; index--)
if (PieceTab[Player][index].ipiece != empty)
{
Next.old = PieceTab[Player][index].isquare;
NonCapMovGen();
}
if (MovTab[Depth-1].movpiece == pawn) /* E.p. captures */
if (abs(MovTab[Depth-1].new1 - MovTab[Depth-1].old) >= 0x20)
{
Next.spe = 1;
Next.movpiece = pawn;
Next.content = empty;
Next.new1 = (MovTab[Depth-1].new1 + MovTab[Depth-1].old) / 2;
for (sq = MovTab[Depth-1].new1-1; sq <= MovTab[Depth-1].new1+1;
sq++)
if (sq != MovTab[Depth-1].new1)
if (!(sq & 0x88))
{
Next.old = sq;
if (KillMovGen(&Next)) Generate();
}
}
}
/*
* place next move from the buffer in next. Generate zeromove when there
* are no more moves.
*/
void MovGen(void)
{
if (BufPnt >= BufCount)
Next = ZeroMove;
else
{
BufPnt++;
Next = Buffer[BufPnt];
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -