Search code examples
regexexpressionnotation

Regex challenge, Custom Chess Notation


Place a piece on the board (ex: Qld1 – place the white queen on D1, Kde8 – place the black king on E8).  Piece abbreviations are:
K = king
Q = queen
B = bishop
N = knight
R = rook
P = pawn
and l = light, d = dark.

Move a single piece on the board (ex: d8 h4 – moves the piece at D8 to the square at H4, c4 d6* - moves the piece at C4 to D6 and captures the piece at D6).
Move two pieces in a single turn (ex: e1 g1 h1 f1 – moves the king from E1 to G1 and moves the rook from H1 to F1.  This is called a “king-side castle”).

I need help writing a single regex to take all options listed. I got this far:

([KQNBR]?([a-h]?[1-8]?x)?[a-h]([2-7]|[18](=[KQNBR])?)|0-0(-0)?)(\(ep\)|\+{1,2})?

or

([BKNPQR]?)([a-h]?)([0-9]?)([x=]?)([BKNPQR\*]|[a-h][1-8])([+#]?)

before it was decided that the chess board will take on a very different custom notation for handling moves.

The question is I need help to creating a regex expression that will validate these chess moves.

An example is that, this program will not be live manipulation of a chess board. But instead a file will be read from a stream line by line, the console application of your chess game should read each line and produce the following results for each of the moves.

The first few lines of the file should read placements of each piece Qld1 which places a white queen on D1, kde8 places the black king on E8.

Afterwards the file will read each movement, d8 h4 will move the piece in position of d8 to h4.

The single regular expression will validate the text file to read if it is a valid move based on its expression. If it is invalid, skip the move and continue.


Solution

  • As a general strategy for creating complex regular expressions, you can create different regular expressions for each of the individual components.

    E.g. first create a regular expression matching placement ([KQNBR][ld][a-h][1-8]). This is easy to read and easy to create.

    Then create a regular expression for the normal moves ([a-h][1-8]\s[a-h][1-8]) and then one for the castling moves (left as an exercise for the reader). These you can combine using ([KQNBR][ld][a-h][1-8])|([a-h][1-8]\s[a-h][1-8]\*?)|etc.

    You can even reuse parts of the regular expressions, e.g. call [a-h][1-8] field in your language of choice and reuse that. A move would then be something like field + '\s' + field + '\*?'.

    Although this may not be the shortest regular expression (or the most efficient one) it will be much easier to create it and much more readable.