📄 genmove.c
字号:
while (c) { t = leadz (c); CLEARBIT (c, t); if ( t > 7) 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); } } /* Castling code */ b = board.b[side][rook]; if (side == white && (board.flag & WKINGCASTLE) && (b & BitPosArray[7]) && !(FromToRay[4][6] & blocker) && !SqAtakd (4, black) && !SqAtakd (5, black) && !SqAtakd (6, black)) { ADDMOVE (4, 6, CASTLING); } if (side == white && (board.flag & WQUEENCASTLE) && (b & BitPosArray[0]) && !(FromToRay[4][1] & blocker) && !SqAtakd (4, black) && !SqAtakd (3, black) && !SqAtakd (2, black)) { ADDMOVE (4, 2, CASTLING); } if (side == black && (board.flag & BKINGCASTLE) && (b & BitPosArray[63]) && !(FromToRay[60][62] & blocker) && !SqAtakd (60, white) && !SqAtakd (61, white) && !SqAtakd (62, white)) { ADDMOVE (60, 62, CASTLING); } if (side == black && (board.flag & BQUEENCASTLE) && (b & BitPosArray[56]) && !(FromToRay[60][57] & blocker) && !SqAtakd (60, white) && !SqAtakd (59, white) && !SqAtakd (58, white)) { ADDMOVE (60, 58, CASTLING); } /* Update tree pointers and count */ TreePtr[ply + 1] = node; GenCnt += TreePtr[ply + 1] - TreePtr[ply];}void GenCaptures (short ply)/**************************************************************************** * * This routine generates captures. En passant and pawn promotions * are included. * ****************************************************************************/{ int side; int piece, sq, t, ep; BitBoard b, c, friends, notfriends, enemy, blocker; BitBoard *a; side = board.side; a = board.b[side]; friends = board.friends[side]; notfriends = ~friends; enemy = board.friends[1^side]; blocker = board.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] & enemy); } } /* Bishop */ b = a[bishop]; while (b) { sq = leadz (b); CLEARBIT (b, sq); c = BishopAttack(sq); BitToMove (sq, c & enemy); } /* Rook */ b = a[rook]; while (b) { sq = leadz (b); CLEARBIT (b, sq); c = RookAttack(sq); BitToMove (sq, c & enemy); } /* Queen */ b = a[queen]; while (b) { sq = leadz (b); CLEARBIT (b, sq); c = QueenAttack(sq); BitToMove (sq, c & enemy); } /* White pawn moves */ if (side == white) { b = a[pawn] & RankBit[6]; /* all pawns on 7 rank */ c = (b >> 8) & ~blocker; /* 1 square forward */ while (c) { t = leadz (c); CLEARBIT (c, t); ADDPROMOTE (t-8, t); } b = a[pawn] & ~FileBit[0]; /* captures to the left */ c = (b >> 7) & (board.friends[1^side] | (ep > -1 ? BitPosArray[ep] : ULL(0))); 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) & (board.friends[1^side] | (ep > -1 ? BitPosArray[ep] : ULL(0))); 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) { b = a[pawn] & RankBit[1]; /* all pawns on 2nd rank */ c = (b << 8) & ~blocker; while (c) { t = leadz (c); CLEARBIT (c, t); ADDPROMOTE (t+8, t); } b = a[pawn] & ~FileBit[7]; /* captures to the left */ c = (b << 7) & (board.friends[1^side] | (ep > -1 ? BitPosArray[ep] : ULL(0))); 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) & (board.friends[1^side] | (ep > -1 ? BitPosArray[ep] : ULL(0))); 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); } } } /* Update tree pointers and count */ TreePtr[ply + 1] = node; GenCnt += TreePtr[ply + 1] - TreePtr[ply];}void GenCheckEscapes (short ply)/************************************************************************** * * The king is in check, so generate only moves which get the king out * of check. * Caveat: The special case of an enpassant capture must be taken into * account too as the captured pawn could be the checking piece. * **************************************************************************/{ int side, xside; int kingsq, chksq, sq, sq1, epsq, dir; BitBoard checkers, b, c, p, escapes; escapes = NULLBITBOARD; side = board.side; xside = 1 ^ side;/* TreePtr[ply + 1] = TreePtr[ply]; */ node = TreePtr[ply + 1]; kingsq = board.king[side]; checkers = AttackTo (kingsq, xside); p = board.b[side][pawn]; if (nbits (checkers) == 1) { /* Captures of checking pieces (except by king) */ chksq = leadz (checkers); b = AttackTo (chksq, side); b &= ~board.b[side][king]; while (b) { sq = leadz (b); CLEARBIT (b, sq); if (!PinnedOnKing (sq, side)) { if (cboard[sq] == pawn && (chksq <= H1 || chksq >= A8)) { ADDPROMOTE (sq, chksq); } else ADDMOVE (sq, chksq, 0); } } /* Maybe enpassant can help */ if (board.ep > -1) { epsq = board.ep; if (epsq + (side == white ? -8 : 8) == chksq) { b = MoveArray[ptype[1^side]][epsq] & p; while (b) { sq = leadz (b); CLEARBIT (b, sq); if (!PinnedOnKing (sq, side)) ADDMOVE (sq, epsq, ENPASSANT); } } } /* Lets block/capture the checking piece */ if (slider[cboard[chksq]]) { c = FromToRay[kingsq][chksq] & NotBitPosArray[chksq]; while (c) { sq = leadz (c); CLEARBIT (c, sq); b = AttackTo (sq, side); b &= ~(board.b[side][king] | p); /* Add in pawn advances */ if (side == white && sq > H2) { if (BitPosArray[sq-8] & p) b |= BitPosArray[sq-8]; if (RANK(sq) == 3 && cboard[sq-8] == empty && (BitPosArray[sq-16] & p)) b |= BitPosArray[sq-16]; } if (side == black && sq < H7) { if (BitPosArray[sq+8] & p) b |= BitPosArray[sq+8]; if (RANK(sq) == 4 && cboard[sq+8] == empty && (BitPosArray[sq+16] & p)) b |= BitPosArray[sq+16]; } while (b) { sq1 = leadz (b); CLEARBIT (b, sq1); if (!PinnedOnKing (sq1, side)) { if (cboard[sq1] == pawn && (sq > H7 || sq < A2)) { ADDPROMOTE (sq1, sq); } else ADDMOVE (sq1, sq, 0); } } } } } /* If more than one checkers, move king to get out of check */ if (checkers) escapes = MoveArray[king][kingsq] & ~board.friends[side]; while (checkers) { chksq = leadz (checkers); CLEARBIT (checkers, chksq); dir = directions[chksq][kingsq]; if (slider[cboard[chksq]]) escapes &= ~Ray[chksq][dir]; } while (escapes) { sq = leadz (escapes); CLEARBIT (escapes, sq); if (!SqAtakd (sq, xside)) ADDMOVE (kingsq, sq, 0); } /* Update tree pointers and count */ TreePtr[ply + 1] = node; GenCnt += TreePtr[ply + 1] - TreePtr[ply]; return;}void FilterIllegalMoves (short ply)/************************************************************************** * * All the illegal moves in the current ply is removed. * **************************************************************************/{ leaf *p; int side, xside; int check, sq; side = board.side; xside = 1^side; sq = board.king[side]; for (p = TreePtr[ply]; p < TreePtr[ply+1]; p++) { MakeMove (side, &p->move); if (cboard[TOSQ(p->move)] != king) check = SqAtakd (sq, xside); else check = SqAtakd (TOSQ(p->move), xside); UnmakeMove (xside, &p->move); if (check) /* its an illegal move */ { --TreePtr[ply+1]; *p = *TreePtr[ply+1]; --p; GenCnt--; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -