1

我对位板和位操作了解不多,我从 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);
};

任何人都知道我怎样才能做到这一点?

4

1 回答 1

0

我认为找到检查棋子的最有效方法是在生成合法棋步的同时找到它们。这将需要一些重构并且可能有点复杂。

一种更简单的方法是使用isAttacked函数的重新设计副本,方法是从国王的位置开始为每个棋子生成攻击掩码。

例如,如果您将国王的位板与国王的颜色一起发送到makePawnAttackMask函数,并在掩码和对面玩家的棋子之间应用逻辑与,您将得到一个包含检查棋子的位板。然后,您可以使用函数extractLowestBitPositiongetLowestBitPosition来查找攻击棋子的方格(如果存在)。在尝试提取最低有效位的位置之前,请确保位板不为空:

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 个相同类型的棋子攻击是正确的,因为一个棋子捕获/提升到一个皇后可以检查并同时发现一个女王攻击。

于 2021-05-17T20:40:07.760 回答