📄 genmove.c
字号:
/* GNU Chess 5.0 - genmove.c - move generator 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 "common.h"const short raybeg[7] = { 0, 0, 0, 0, 4, 0, 0 };const short rayend[7] = { 0, 0, 0, 4, 8, 8, 0 };static leaf *node;#define ADDMOVE(a,b,c) \ do { \ node->move = MOVE(a,b) | (c); \ node++; \ } while (0)#define ADDPROMOTE(a,b) \ do { \ ADDMOVE (a, b, QUEENPRM); \ ADDMOVE (a, b, KNIGHTPRM); \ ADDMOVE (a, b, ROOKPRM); \ ADDMOVE (a, b, BISHOPPRM); \ } while (0)static inline void BitToMove (short f, BitBoard b)/*************************************************************************** * * Convert a bitboard into a list of moves. These are stored * into the tree. f is the origin square. * ***************************************************************************/{ int t; while (b) { t = leadz (b); CLEARBIT (b, t); ADDMOVE (f, t, 0); }}void GenMoves (short ply)/**************************************************************************** * * My bitboard move generator. Let's see how fast we can go! * This routine generates pseudo-legal moves. * ****************************************************************************/{ int side; int piece, sq, t, ep; BitBoard b, c, d, e, friends, notfriends, blocker, notblocker; BitBoard *a; side = board.side; a = board.b[side]; friends = board.friends[side]; notfriends = ~friends; blocker = board.blocker; notblocker = ~blocker; node = TreePtr[ply + 1]; ep = board.ep; /* Knight & King */ for (piece = knight; piece <= king; piece += 4) { b = a[piece]; while (b) { sq = leadz (b); CLEARBIT (b, sq); BitToMove (sq, MoveArray[piece][sq] & notfriends); } } /* Bishops */ b = a[bishop]; while (b) { sq = leadz (b); CLEARBIT (b, sq); d = BishopAttack(sq); BitToMove (sq, d & notfriends); } /* Rooks */ b = a[rook]; while (b) { sq = leadz (b); CLEARBIT (b, sq); d = RookAttack(sq); BitToMove (sq, d & notfriends); } /* Queen */ b = a[queen]; while (b) { sq = leadz (b); CLEARBIT (b, sq); d = QueenAttack(sq); BitToMove (sq, d & notfriends); } /* White pawn moves */ e = (board.friends[1^side] | (ep > -1 ? BitPosArray[ep] : NULLBITBOARD)); if (side == white) { c = (a[pawn] >> 8) & notblocker; /* 1 square forward */ while (c) { t = leadz (c); CLEARBIT (c, t); if (t >= 56) /* promotion */ { ADDPROMOTE (t-8, t); } else ADDMOVE (t-8, t, 0); } b = a[pawn] & RankBit[1]; /* all pawns on 2nd rank */ c = (b >> 8) & notblocker; c = (c >> 8) & notblocker; /* 2 squares forward */ while (c) { t = leadz (c); CLEARBIT (c, t); ADDMOVE (t-16, t, 0); } b = a[pawn] & ~FileBit[0]; /* captures to the left */ c = (b >> 7) & e; while (c) { t = leadz (c); CLEARBIT (c, t); if (t >= 56) /* promotion */ { ADDPROMOTE (t-7, t); } else if (ep == t) { ADDMOVE (t-7, t, ENPASSANT); } else { ADDMOVE (t-7, t, 0); } } b = a[pawn] & ~FileBit[7]; /* captures to the right */ c = (b >> 9) & e; while (c) { t = leadz (c); CLEARBIT (c, t); if (t >= 56) /* promotion */ { ADDPROMOTE (t-9, t); } else if (ep == t) { ADDMOVE (t-9, t, ENPASSANT); } else { ADDMOVE (t-9, t, 0); } } } /* Black pawn forward moves */ if (side == black) { c = (a[pawn] << 8) & notblocker; while (c) { t = leadz (c); CLEARBIT (c, t); if (t <= 7) /* promotion */ { ADDPROMOTE (t+8, t); } else ADDMOVE (t+8, t, 0); } b = a[pawn] & RankBit[6]; /* all pawns on 7th rank */ c = (b << 8) & notblocker; c = (c << 8) & notblocker; while (c) { t = leadz (c); CLEARBIT (c, t); ADDMOVE (t+16, t, 0); } b = a[pawn] & ~FileBit[7]; /* captures to the left */ c = (b << 7) & e; while (c) { t = leadz (c); CLEARBIT (c, t); if (t <= 7) /* promotion */ { ADDPROMOTE (t+7, t); } else if (ep == t) { ADDMOVE (t+7, t, ENPASSANT); } else { ADDMOVE (t+7, t, 0); } } b = a[pawn] & ~FileBit[0]; /* captures to the right */ c = (b << 9) & e; while (c) { t = leadz (c); CLEARBIT (c, t); if (t <= 7) /* promotion */ { ADDPROMOTE (t+9, t); } else if (ep == t) { ADDMOVE (t+9, t, ENPASSANT); } else { ADDMOVE (t+9, t, 0); } } } /* Castling code */ b = board.b[side][rook]; if (side == white && (board.flag & WKINGCASTLE) && (b & BitPosArray[H1]) && !(FromToRay[E1][G1] & blocker) && !SqAtakd (E1, black) && !SqAtakd (F1, black) && !SqAtakd (G1, black)) { ADDMOVE (E1, G1, CASTLING); } if (side == white && (board.flag & WQUEENCASTLE) && (b & BitPosArray[A1]) && !(FromToRay[E1][B1] & blocker) && !SqAtakd (E1, black) && !SqAtakd (D1, black) && !SqAtakd (C1, black)) { ADDMOVE (E1, C1, CASTLING); } if (side == black && (board.flag & BKINGCASTLE) && (b & BitPosArray[H8]) && !(FromToRay[E8][G8] & blocker) && !SqAtakd (E8, white) && !SqAtakd (F8, white) && !SqAtakd (G8, white)) { ADDMOVE (E8, G8, CASTLING); } if (side == black && (board.flag & BQUEENCASTLE) && (b & BitPosArray[A8]) && !(FromToRay[E8][B8] & blocker) && !SqAtakd (E8, white) && !SqAtakd (D8, white) && !SqAtakd (C8, white)) { ADDMOVE (E8, C8, CASTLING); } /* Update tree pointers and count */ TreePtr[ply + 1] = node; GenCnt += TreePtr[ply + 1] - TreePtr[ply];}void GenNonCaptures (short ply)/**************************************************************************** * * Here I generate only non-captures. Promotions are considered * as captures and are not generated. * ****************************************************************************/{ int side; int piece, sq, t, ep; BitBoard b, c, d, friends, notfriends, blocker, notblocker; BitBoard *a; side = board.side; a = board.b[side]; friends = board.friends[side]; notfriends = ~friends; blocker = board.blocker; notblocker = ~blocker; node = TreePtr[ply + 1]; ep = board.ep; /* Knight & King */ for (piece = knight; piece <= king; piece += 4) { b = a[piece]; while (b) { sq = leadz (b); CLEARBIT (b, sq); BitToMove (sq, MoveArray[piece][sq] & notblocker); } } /* Bishops */ b = a[bishop]; while (b) { sq = leadz (b); CLEARBIT (b, sq); d = BishopAttack(sq); BitToMove (sq, d & notblocker); } /* Rooks */ b = a[rook]; while (b) { sq = leadz (b); CLEARBIT (b, sq); d = RookAttack(sq); BitToMove (sq, d & notblocker); } /* Queen */ b = a[queen]; while (b) { sq = leadz (b); CLEARBIT (b, sq); d = QueenAttack(sq); BitToMove (sq, d & notblocker); } /* White pawn moves */ if (side == white) { c = (a[pawn] >> 8) & notblocker; /* 1 square forward */ while (c) { t = leadz (c); CLEARBIT (c, t); if (t < 56) ADDMOVE (t-8, t, 0); } b = a[pawn] & RankBit[1]; /* all pawns on 2nd rank */ c = (b >> 8) & notblocker; c = (c >> 8) & notblocker; /* 2 squares forward */ while (c) { t = leadz (c); CLEARBIT (c, t); ADDMOVE (t-16, t, 0); } } /* Black pawn forward moves */ if (side == black) { c = (a[pawn] << 8) & notblocker;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -