I've been rather angry at the fen format for a while. As the broadest used format for storing chess positions, it is used in the UCI chess engine protocol, and in the PGN format as a header tag.
To store a chess position, it takes more than just storing the location of the pieces. You also have to store the castling state, the cord which can be attacked by enpassant, the number of moves since last capture or pawn move (to judge draw on the fifty moves rule) and last, but very importantly, you have to somehow store the position repetition state.
In chess a game can be declared a draw if the same position has been repeated three times in a row. This rule can sometimes be used to force your opponent, which is in head of the game, to a draw.
A typical fen string could look like:
nbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 2
which is the board position, the castling state, the enpassant square, the fifty moves counter and the full move number.
The fen format nicely takes care of the first 4 parts, but it has no way of storing the repetition count. This might not sound as a big deal to most people, but imagine that a certain move will draw a game, and the engine is being told of the position using fen, then, if the move was good, the engine will play it, totally unaware of the draw danger.
Now, you can perhaps imagine how interested I was when I saw that the epd format, which is very much like the fen format, contains a so called opcode for storing the repetition count.
An epd string may look something like:
r1b1kb1r/pppp1ppp/8/1nN5/1n1p2Pq/5P2/PPPPP2P/R1BQKB1R w KQkq - hmvc 1; fmvn 7; rc 1; The two last fen fields have been moved to opcodes, and we have added a field called rc.
The repetition field is good, but it only solves half the problem. Consider this case:
Initial position # Repetition count is now 1 1. Nf3 # Repetition count is now 1 ... Nf6 # Repetition count is now 1 2. Ng1 # Repetition count is now 1 ... Ng8 # Repetition count is now 2 3. Nf3 # Repetition count is now 2 ... Nf6 # Repetition count is now 2 4. Ng1 # Repetition count is now 2 ... Ng8 # Repetition count is now 3
You see, we've got four positions with repetition count 1 and four positions with repetition count 2. How the heck is a software program going to decide whether a move is going to put it in repetition count 3 and there by a draw?