4

OK I have read a lot of things on the web most of them using Java that doesn't have unsigned int. I am working on Objective-C that has unsigned int.

Lets consider the following scenario.

The board is like this:

enter image description here

A1 is on the lower left and is the least significant bit and H8 is on the top right and is the most significant bit.

I have constructed the bitmasks for the movements of all pieces for all positions on the board.

Suppose the following simple situation:

  1. the game will start. All pieces are on their initial positions.
  2. the user tries to move the knight on G1 to E2.

Obviously this movement is impossible because there is a pawn on E2.

How do I discover if a movement is valid?

Ok I have the bitmask of all pieces that is this:

1111111111111111000000000000000000000000000000001111111111111111

and I have the bitmask of the possible movements for the knight at G1 that is

00000000
00000000
00000000
00000000
00000000
00000X0X
0000X000
00000000

or in bits

0000000000001000000001010000000000000000000000000000000000000000

if I AND these two

1111111111111111000000000000000000000000000000001111111111111111 0000000000001000000001010000000000000000000000000000000000000000

I get

0000000000001000000000000000000000000000000000000000000000000000

all I know is that there is a piece at that point but I am not seeing how this tells me if that is a valid move or not.

Another question is this: suppose this move would let my king under attack. Obviously the move would be technically possible under the knight rules of movement but impossible because I cannot do a move that puts my king under attack.

How do I get these informations? Thanks

2

Let me answer your questions for @MikeJones:


  1. You will need to store the generated moves in a bitboard. The following code example should work:

    unsigned int moves = .... // This gives a bitboard of where your knight can move
    unsigned int whitePieces = .... // This gives a bitboard of where your white pieces are
    
    if (moves & whitePieces) {
        // If your code reaches here, one of your moves is invalid because we can't capture our own piece
    } else {
        // If your code reaches here, your moves are pseudo-legal
    }
    

    Note that I say pseudo-legal, because it's only legal if the move itself doesn't expose your own king. You'll need some logic to check it and this brings us to the second point.


  1. Mike's solution for checking king attacks will work but it's slow. You should do what Stockfish is doing (I don't see a better and faster way). In position.cpp, Stockfish does this:

    • If the moving piece is the king, then the move is only legal if the destination is not under attacked by the opponent.

      if (type_of(piece_on(from)) == KING)
          return type_of(m) == CASTLING || !(attackers_to(to_sq(m)) & pieces(~us));
      

      This can be easily implemented by AND, because you will always need to keep a bitboard for white pieces and black pieces.


    • If the moving piece is not the king, the move is only legal if it's not pinned or it's moving along the ray towards or away from the king:

      return !(pinned & from)
          ||  aligned(from, to_sq(m), square(us));
      

      You can construct a pinned bitboard by going through all the pieces, and ask which of them is blocking the enemy attack to the king. Something like this will work:

      unsigned int enemyAttacks = ... // Bitboard of where the enemy pieces can attack the king
      unsigned int myPieces = .... // Bitboard of where my pieces and pawns are
      
      if (enemyAttacks & myPieces) {
          // One of our pieces is blocking the attack
      }
      
  • I've screwed up the formatting and not sure how to fix it. Can someone edit my answer for me? – SmallChess Jul 30 '16 at 5:18
2

Make a bitboard of all the white pieces. If the AND of the possible knight move and the white pieces is TRUE, then the move is illegal--attempting to capture your own piece.

The simplest way is to make the move and check if the King is in check.

The method I use is a little more complicated. First I check is the King is in check now. If the King is in check, I can delete all non-king moves which do not finish on the line the check is coming from. If the King is not in check, I only have to check the line if the piece moves from the line. The code seems harder to write, but the validating routine runs less lines.

To explain the latter case better. If the King on f1 is not in check, and I move the Knight on f3, I only have to examine if a check was masked by this Knight. If a Bishop moved from d3, I only have to examine if the opponent's Bishop or Queen is checking from c4, b5 or a6.

  • Lets divide your answer in 4 paragraphs. I will refer them by number. 1 how can an AND of 64 bits be true? what do you mean by true? Non zero? Please explain that using the numbers I have posted. I need to see where the zeros and ones are... 😃... sorry about all other paragraphs you wrote. They are too verbose for my brain with no examples of zeros and ones... my brain is like a FIFO buffer with very limited storage space for words... in the middle of your paragraphs the first characters were not in the buffer anymore, so I could not compute 😃 please, give me some juicy zeros and ones! – SpaceDog Jul 30 '16 at 4:05
  • @SpaceDog Please review my answer – SmallChess Jul 30 '16 at 5:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.