1

I don't have too much knowledge about bitboards and bit operations and I got some examples of bitboard chess engines from Github. And I like to know if anyone can help me with a problem.

How can I identify the exact piece that is attacking the king?

I got an example in the isKingInCheck function from position.js that just identifies when the king is attacked (even identifies if the piece is pawn, or bishop, etc.), but I need to know exactly the piece (position) that is attacking the king.

I believe that would be possible creating a generic attack mask function, like the function below. The problem is that I don't know how I get each piece (and its position during the game) individually from the pre-made bitboards, declared in the position.js file.

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);
};

Anyone know how can I achieve this?

JRamos29
  • 880
  • 7
  • 20

1 Answers1

0

I think the most efficient way to find the checking pieces would be to find them at the same time as you generate the legal moves. That would require some refactoring and could be a bit complicated.

One easier way would be to use a reworked copy of the isAttacked function by generating the attack masks for each piece starting from the king's position.

For example, if you send the king's bitboard to the makePawnAttackMask function with the king's color and you apply a logical and between the mask and the opposite player's pawns, you'll get a bitboard containing the checking pawn. You can then use the function extractLowestBitPosition or getLowestBitPosition to find the square of the attacking pawn if it exists. Make sure the bitboard is not empty before trying to extract the least significant bit's position :

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;
}

If you'll be finding checking pieces using only legal chess positions, positions that could happen in an actual game, then you could stop once you've found 2 checking pieces as it's impossible for 3 pieces to check the king at once.

I believe you could also quit looking for pieces of one type once you've found one in the mask, except for the queen. I think it is right that in a legal chess position a king can't be attacked by 2 of the same piece type at once except for 2 queens since a pawn capture/promotion to a queen can give check and at the same time discover a queen attack.

bouc1620
  • 41
  • 1
  • 5