Thursday, 14 March 2013

FEN Strings

I've made some progress yesterday.  I have an elementary bitboard representation working and I can set and get the chess board using a FEN string.  A FEN String essentially represents the current board setup in a convenient notation.  Here is an example after white's initial e4:

rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1

Each string in between the slashes represents a rank in the chessboard, starting from the 8th rank. Lower case is black, upper case is white. Numbers represents empty squares between pieces.  For example '4P3' represents four empty squares, followed by a pawn, followed by three more empty squares, totaling eight.  The '/8/' therefore means (you've guessed it!) a complete empty rank.

The remaining string 'b KQkq e3 0 1' represents the side to move, the castling rights (e.g. 'K' means white can caste king-side, 'q' that black can caste queen-side, etc.), en-passant square and the move counters.  The en-passant square is the square directly behind the pawn that made the two-square move.  In this case, white move e4, which means that e3 is the en-passant square.  Black can capture the pawn if he had a pawn on either d4 or f4.  Regardless, the en-passant square is always indicated, whether it can be taken or not.  The move counts are the half-moves since a last capture or pawn move (for the 50-move draw rule), followed by the number of full moves.

I found myself constantly checking the validity of the FEN string during the parsing stage, which started to look really ugly.  So I turned to one of my best friends... regular expressions!

Regular expressions can get tricky...quickly, but is incredibly powerful to recognise patterns in strings.  Here is a short extract from Vicki that shows how a FEN string can be checked:

 
The 'verifyRank()' method simply verifies that the a rank adds up to eight. Doing that in a regular expression may get very hairy (actually I don't think it can be done). The code also verifies that there are 2 kings at least.  Of course, that can easily be done by the regular expression, but the string will get rather long. 

No comments: