c# – 国际象棋编程(无AI) – 移动验证
我正在尝试编写自己的国际象棋引擎(没有AI).
我知道有 Chess Game Starter Kit,我看了它的开始灵感. 但是我没有抓到的是我的非国王作品在哪里经过验证的动作(here is moves validation)阻止自己检查? 想象一下情况: 因为我要检查,所以我现在不能动我的主教. 或者您如何建议检查这种情况? 谢谢 解决方法
对于给定的棋盘位置,大多数国际象棋引擎仅通过生成伪合法移动开始.通过伪合法,我的意思是即使它会产生一个移动:
>让国王受到控制 原因是性能.由于beta修剪,实际上不会搜索到许多动作,因此您可以通过避免全面检查移动有效性来节省时间. 对于搜索的每个移动,您需要检查它是否真的有效.这通常是通过将King的颜色和方块(以及King旁边的方块用于铸造移动)传递到IsAttacked方法来完成的.如果该方法返回true,则表示此移动无效,因此您不应将其包含在搜索中. 这是我自己的C#国际象棋引擎的IsAttacked方法.请记住,我的引擎是基于magic bitboard的,因此代码不能直接应用于您链接的国际象棋入门套件.除非你熟悉魔术位板,否则翻译不会是微不足道的. // IsAttacked is primarily used as a move legality test to see if a set of // one or more squares is under attack from the side to move. // It returns true as soon as an attack is detected,otherwise returns false. // It can be used for check detection,castling legality,or simply to // detect whether a specific square is attacked. internal bool IsAttacked(Board board,UInt64 targetSquares,bool whiteAttacking) { UInt64 slidingAttackers; Int32 targetSquare; UInt64 remainingTargetSquares = targetSquares; // Test for attacks by WHITE on any of the target squares. if (whiteAttacking) { // For the remaining target squares... while (remainingTargetSquares != 0) { // Find the next square in the list. targetSquare = BitOperations.BitScanForward(remainingTargetSquares); // Is this square attacked by a pawn,knight,or king? if ((board.WhitePawns & Constants.BLACK_PAWN_ATTACKS[targetSquare]) != 0) return true; if ((board.WhiteKnights & Constants.KNIGHT_ATTACKS[targetSquare]) != 0) return true; if ((board.WhiteKing & Constants.KING_ATTACKS[targetSquare]) != 0) return true; // Is this square attacked by a queen or rook along a file or rank? slidingAttackers = board.WhiteQueens | board.WhiteRooks; if (slidingAttackers != 0) { if (this.RankMoves(board.OccupiedSquares,slidingAttackers,targetSquare) != 0) return true; if (this.FileMoves(board.OccupiedSquares,targetSquare) != 0) return true; } // Is this square attacked by a queen or bishop along a diagonal? slidingAttackers = board.WhiteQueens | board.WhiteBishops; if (slidingAttackers != 0) { if (this.DiagonalA8H1Moves(board.OccupiedSquares,targetSquare) != 0) return true; if (this.DiagonalA1H8Moves(board.OccupiedSquares,targetSquare) != 0) return true; } // This square isn't attacked - remove and move on to next target square. remainingTargetSquares ^= Constants.BITSET[targetSquare]; } } // Test for attacks by BLACK on any of the target squares. else { // For the remaining target squares... while (remainingTargetSquares != 0) { // Find the next square in the list. targetSquare = BitOperations.BitScanForward(remainingTargetSquares); // Is this square attacked by a pawn,or king? if ((board.BlackPawns & Constants.WHITE_PAWN_ATTACKS[targetSquare]) != 0) return true; if ((board.BlackKnights & Constants.KNIGHT_ATTACKS[targetSquare]) != 0) return true; if ((board.BlackKing & Constants.KING_ATTACKS[targetSquare]) != 0) return true; // Is this square attacked by a queen or rook along a file or rank? slidingAttackers = board.BlackQueens | board.BlackRooks; if (slidingAttackers != 0) { if (this.RankMoves(board.OccupiedSquares,targetSquare) != 0) return true; } // Is this square attacked by a queen or bishop along a diagonal? slidingAttackers = board.BlackQueens | board.BlackBishops; if (slidingAttackers != 0) { if (this.DiagonalA8H1Moves(board.OccupiedSquares,targetSquare) != 0) return true; } // This square isn't attacked - remove and move on to next target square. remainingTargetSquares ^= Constants.BITSET[targetSquare]; } } // None of the target squares are attacked. return false; } 这是为White生成伪合法铸造移动的代码片段: // If White can still castle kingside... if ((board.WhiteCastlingStatus & Board.EnumCastlingStatus.CanCastleOO) != 0) { // And the White kingside castling squares (F1/G1) aren't occupied... if ((Constants.MASK_FG[Constants.WHITE_MOVE] & board.OccupiedSquares) == 0) { board.MoveBuffer[moveIndex++] = Constants.WHITE_CASTLING_OO; } } // If White can still castle queenside... if ((board.WhiteCastlingStatus & Board.EnumCastlingStatus.CanCastleOOO) != 0) { // And the White queenside castling squares (D1/C1/B1) aren't occupied... if ((Constants.MASK_BD[Constants.WHITE_MOVE] & board.OccupiedSquares) == 0) { board.MoveBuffer[moveIndex++] = Constants.WHITE_CASTLING_OOO; } } 这里是检查伪合法铸造移动是否实际合法的代码: // Checks whether the King is moving from or into check. // Checks whether the King is moving across attacked squares. internal bool IsCastlingMoveLegal(Board board,Move move) { if (move.IsCastlingOO) { if (move.IsWhiteMove) { // Are any of the White kingside castling squares (E1/F1/G1) attacked? return !this.IsAttacked(board,Constants.MASK_EG[Constants.WHITE_MOVE],false); } else { // Are any of the Black kingside castling squares (E8/F8/G8) attacked? return !this.IsAttacked(board,Constants.MASK_EG[Constants.BLACK_MOVE],true); } } else if (move.IsCastlingOOO) { if (move.IsWhiteMove) { // Are any of the White queenside castling squares (E1/D1/C1) attacked? return !this.IsAttacked(board,Constants.MASK_CE[Constants.WHITE_MOVE],false); } else { // Are any of the Black queenside castling squares (E8/D8/C8) attacked? return !this.IsAttacked(board,Constants.MASK_CE[Constants.BLACK_MOVE],true); } } // Not a castling move! else { Debug.Assert(false,"Not a castling move!"); return true; } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |