问题描述
我对位板和位操作的了解不多,但我从 Github 获得了一些位板国际象棋引擎的示例。 我想知道是否有人可以帮助我解决问题。
我如何确定攻击国王的确切棋子?
我在 position.js 的 isKingInCheck 函数中得到了一个例子,它只识别国王何时受到攻击(甚至识别棋子是棋子还是象等),但我需要准确知道攻击国王的棋子(位置)。
我相信可以创建一个通用攻击掩码函数,如下面的函数。问题是我不知道如何从 position.js 文件中声明的预制位板中单独获取每个部分(及其在游戏中的位置)。
Chess.Position.makePawnAttackMask = function(color,pawns) {
var white = (color === Chess.PieceColor.WHITE);
var attacks1 = pawns.dup().and_not(Chess.bitboard.FILES[0]).shiftLeft(white ? 7 : -9);
var attacks2 = pawns.dup().and_not(Chess.bitboard.FILES[Chess.LAST_FILE]).shiftLeft(white ? 9 : -7);
return attacks1.or(attacks2);
};
有人知道我怎样才能做到这一点吗?
解决方法
我认为找到检查棋子的最有效方法是在生成合法移动的同时找到它们。这需要进行一些重构,而且可能有点复杂。
一种更简单的方法是使用 isAttacked 函数的重写副本,为从国王位置开始的每个棋子生成攻击掩码。
例如,如果您将国王的 bitboard 发送到具有国王颜色的 makePawnAttackMask 函数,并在掩码和对面玩家的 pawn 之间应用逻辑和,您将得到一个包含检查 pawn 的 bitboard。然后,您可以使用函数 extractLowestBitPosition 或 getLowestBitPosition 找到攻击棋子的正方形(如果存在)。在尝试提取最低有效位的位置之前,请确保位板为 not empty :
Chess.Position.prototype.getCheckingPieces = function(color) {
var checkingPieces = [];
var opponent = Chess.getOtherPieceColor(color);
var king = this.getPieceColorBitboard(Chess.Piece.KING,color);
var pawnAttack = Chess.Position.makePawnAttackMask(color,king);
pawnAttack = pawnAttack.and(This.getPieceColorBitboard(Chess.Piece.PAWN,opponent));
if (!pawnAttack.isEmpty()) {
checkingPieces.push(pawnAttack.extractLowestBitPosition());
if (checkingPieces.length > 1) {
return checkingPieces;
}
}
// ... evaluate attacks from the 4 other piece types
return checkingPieces;
}
如果您仅使用合法的国际象棋位置(在实际游戏中可能发生的位置)来查找检查子,那么您可以在找到 2 个检查子后停止,因为 3 个棋子不可能一次检查国王.
我相信一旦你在面具中找到了一种类型的碎片,除了女王之外,你也可以停止寻找一种类型的碎片。我认为在合法的国际象棋位置上,除了 2 个皇后之外,国王不能同时被 2 个相同类型的棋子攻击是正确的,因为棋子捕获/晋升到皇后可以进行检查,同时发现一个女王攻击。