Dec 18, 2006

[Programming] The makeMove()-method

The makeMove-method takes a Move-object and makes the move on the board. There are a few things that happens when making a move.
  • Updating the piece positions in the boardArray. This is basically updating the target square with the moving piece, and emptying the square it moved from

  • When castling we also need to move the rook.

  • When capturing en passant we need to remember to clear the square above/below the piece (depending on what side is capturing).

  • Make sure we update the castling rights.

  • If a pawn moved two squares, we need to put in a new en passant square.

  • If a pawn got promoted, we need to replace it with the chosen new piece.
There's alot of things to keep track of isn't it? :)

Castling rights: There are a number of ways to see if the castling rights changed after a move. I decided to do as follows.

After each move we check the corners and both sides' king square ('e1' and 'e8'), if any of these squares were to lack the right piece (e.g. a black rook on 'h8') we can update the castling rights.

A white king missing from 'e1' would result in all castling rights being removed for white, since the king has moved. A black rook missing from 'h8' would result in removing the short-castle rights for black, since he has moved the rook (or it has been captured).

We do not have to worry about previous castling rights. Take a look at the diagram to the left. At a first glance it might look like white has his castling rights intact, but the rook on 'h1' has been moved!

On the Rf1-h1 move, we would not catch any change in the castling rights, since all the castling pieces are placed at their correct square. But the castling rights were changed when the rook moved from 'h1' in the first place, resulting in an update of white's castling rights to only alow long castling.

Keep in mind we are not adding any rights just because the pieces are placed correctly, so earlier changes will always stay intact.

If the move is a castle, all we have to do is remove the rights for the side castling, since a castle can't interfere with the other side's castling rights. It can temporary stop a castle by having the rook positioned so the other side's king needs to pass a checked square, but it doesn't permanently change the rights. The temporary change will be handled by the move-generating algorithm.

Promotions: Since our Move-objects keep track of what piece has been chosen for the promotion, all we have to do is replace it's target square with the corresponding piece. I have done this using the following code:
switch(move.moveType)
{
case PROMOTION_QUEEN:
boardArray[move.toIndex] = W_QUEEN*(-toMove);
break;
case PROMOTION_ROOK:
boardArray[move.toIndex] = W_ROOK*(-toMove);
break;
case PROMOTION_BISHOP:
boardArray[move.toIndex] = W_BISHOP*(-toMove);
break;
case PROMOTION_KNIGHT:
boardArray[move.toIndex] = W_KNIGHT*(-toMove);
break;
}
boardArray[move.fromIndex] = EMPTY_SQUARE;
I am using the 'toMove' property to get the right colour of the new piece. The toMove variable is either 1 (white's move) or -1 (black's move), so by simply multiplying the piece by it we can change the colour. Now we already switched side to move in the beginning of the method so we have to use -toMove to get the right side.

So if it is black's move, the W_QUEEN (integer 2) will be transformed to B_QUEEN (integer -2) when multiplying with the side to move (-1).

Getting the moves: For now we do not have any easy way of creating a Move-object to make on the board. So we have to hard code it using something like:
Move move = new Move(B_KING, 116, 118, 0, SHORT_CASTLE);
This is obviously not that much fun when you want to try going through a whole game. But don't worry, the move generating algorithm will generate all moves available on the board, so soon we have easy access to every possible move in Move-object form.

Conclusion: We now have a way setting up a position, making a move, and extracting the position. Next step will be unmaking a move.

No comments: