BOOL _PositionStruct::LegalMove(int mv) const { int sqSrc, sqDst, sqPin; int pcSelfSide, pcSrc, pcDst, nDelta; sqSrc = SRC(mv); pcSrc = ucpcSquares[sqSrc]; pcSelfSide = SIDE_TAG(sdPlayer); if ((pcSrc & pcSelfSide) == 0) { return FALSE; } sqDst = DST(mv); pcDst = ucpcSquares[sqDst]; if ((pcDst & pcSelfSide) != 0) { return FALSE; } switch (pcSrc - pcSelfSide) { case PIECE_KING: return IN_FORT(sqDst) && KING_SPAN(sqSrc, sqDst); case PIECE_ADVISOR: return IN_FORT(sqDst) && ADVISOR_SPAN(sqSrc, sqDst); case PIECE_BISHOP: return SAME_HALF(sqSrc, sqDst) && BISHOP_SPAN(sqSrc, sqDst) && ucpcSquares[BISHOP_PIN(sqSrc, sqDst)] == 0; case PIECE_KNIGHT: sqPin = KNIGHT_PIN(sqSrc, sqDst); return sqPin != sqSrc && ucpcSquares[sqPin] == 0; case PIECE_ROOK: case PIECE_CANNON: if (SAME_RANK(sqSrc, sqDst)) { nDelta = (sqDst < sqSrc ? -1 : 1); } else if (SAME_FILE(sqSrc, sqDst)) { nDelta = (sqDst < sqSrc ? -16 : 16); } else { return FALSE; } sqPin = sqSrc + nDelta; while (sqPin != sqDst && ucpcSquares[sqPin] == 0) { sqPin += nDelta; } if (sqPin == sqDst) { return pcDst == 0 || pcSrc - pcSelfSide == PIECE_ROOK; } else if (pcDst != 0 && pcSrc - pcSelfSide == PIECE_CANNON) { sqPin += nDelta; while (sqPin != sqDst && ucpcSquares[sqPin] == 0) { sqPin += nDelta; } return sqPin == sqDst; } else { return FALSE; } case PIECE_PAWN: if (AWAY_HALF(sqDst, sdPlayer) && (sqDst == sqSrc - 1 || sqDst == sqSrc + 1)) { return TRUE; } return sqDst == SQUARE_FORWARD(sqSrc, sdPlayer); default: return FALSE; } }
// 棋子保护判断 bool PositionStruct::Protected(int sd, int sqSrc, int sqExcept) const { // 参数"sqExcept"表示排除保护的棋子(指格子编号),考虑被牵制子的保护时,需要排除牵制目标子的保护 int i, sqDst, sqPin, pc, x, y, nSideTag; SlideMaskStruct *lpsmsRank, *lpsmsFile; // 棋子保护判断包括以下几个步骤: __ASSERT_SQUARE(sqSrc); nSideTag = SIDE_TAG(sd); if (HOME_HALF(sqSrc, sd)) { if (IN_FORT(sqSrc)) { // 1. 判断受到帅(将)的保护 sqDst = ucsqPieces[nSideTag + KING_FROM]; if (sqDst != 0 && sqDst != sqExcept) { __ASSERT_SQUARE(sqDst); if (KING_SPAN(sqSrc, sqDst)) { return true; } } // 2. 判断受到仕(士)的保护 for (i = ADVISOR_FROM; i <= ADVISOR_TO; i ++) { sqDst = ucsqPieces[nSideTag + i]; if (sqDst != 0 && sqDst != sqExcept) { __ASSERT_SQUARE(sqDst); if (ADVISOR_SPAN(sqSrc, sqDst)) { return true; } } } } // 3. 判断受到相(象)的保护 for (i = BISHOP_FROM; i <= BISHOP_TO; i ++) { sqDst = ucsqPieces[nSideTag + i]; if (sqDst != 0 && sqDst != sqExcept) { __ASSERT_SQUARE(sqDst); if (BISHOP_SPAN(sqSrc, sqDst) && ucpcSquares[BISHOP_PIN(sqSrc, sqDst)] == 0) { return true; } } } } else { // 4. 判断受到过河兵(卒)横向的保护 for (sqDst = sqSrc - 1; sqDst <= sqSrc + 1; sqDst += 2) { // 如果棋子在边线,那么断言不成立 // __ASSERT_SQUARE(sqDst); if (sqDst != sqExcept) { pc = ucpcSquares[sqDst]; if ((pc & nSideTag) != 0 && PIECE_INDEX(pc) >= PAWN_FROM) { return true; } } } } // 5. 判断受到兵(卒)纵向的保护 sqDst = SQUARE_BACKWARD(sqSrc, sd); // 如果棋子在底线,那么断言不成立 // __ASSERT_SQUARE(sqDst); if (sqDst != sqExcept) { pc = ucpcSquares[sqDst]; if ((pc & nSideTag) != 0 && PIECE_INDEX(pc) >= PAWN_FROM) { return true; } } // 6. 判断受到马的保护 for (i = KNIGHT_FROM; i <= KNIGHT_TO; i ++) { sqDst = ucsqPieces[nSideTag + i]; if (sqDst != 0 && sqDst != sqExcept) { __ASSERT_SQUARE(sqDst); sqPin = KNIGHT_PIN(sqDst, sqSrc); // 注意,sqSrc和sqDst是反的! if (sqPin != sqDst && ucpcSquares[sqPin] == 0) { return true; } } } x = FILE_X(sqSrc); y = RANK_Y(sqSrc); lpsmsRank = RankMaskPtr(x, y); lpsmsFile = FileMaskPtr(x, y); // 7. 判断受到车的保护,参阅"position.cpp"里的"CheckedBy()"函数 for (i = ROOK_FROM; i <= ROOK_TO; i ++) { sqDst = ucsqPieces[nSideTag + i]; if (sqDst != 0 && sqDst != sqSrc && sqDst != sqExcept) { if (x == FILE_X(sqDst)) { if ((lpsmsFile->wRookCap & PreGen.wBitFileMask[sqDst]) != 0) { return true; } } else if (y == RANK_Y(sqDst)) { if ((lpsmsRank->wRookCap & PreGen.wBitRankMask[sqDst]) != 0) { return true; } } } } // 8. 判断受到炮的保护,参阅"position.cpp"里的"CheckedBy()"函数 for (i = CANNON_FROM; i <= CANNON_TO; i ++) { sqDst = ucsqPieces[nSideTag + i]; if (sqDst && sqDst != sqSrc && sqDst != sqExcept) { if (x == FILE_X(sqDst)) { if ((lpsmsFile->wCannonCap & PreGen.wBitFileMask[sqDst]) != 0) { return true; } } else if (y == RANK_Y(sqDst)) { if ((lpsmsRank->wCannonCap & PreGen.wBitRankMask[sqDst]) != 0) { return true; } } } } return false; }