Skip to content
neverlonePublic

About

Strict FEN chess-position parser, validator, and board renderer, in C.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

fenlab

A FEN (Forsyth-Edwards Notation) parser, validator, and board renderer for the command line, written in C with no dependencies beyond the standard library.

Why it's interesting

FEN is the standard way chess positions get passed between engines, GUIs, and databases (rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1 is "the position after 1.e4"). Most tools parse FEN loosely and trust the input. fenlab instead treats it as a real grammar to validate: rank lengths, legal piece counts, exactly one king per side, no pawns on the back rank, castling rights that are actually backed by a king and rook on their home squares, and an en passant square that's on the right rank. Then it proves the parse was lossless by serializing the position straight back into byte-identical FEN.

Install / run

Requires a C11 compiler (cc/gcc) and make. No other dependencies.

make          # builds ./fenlab
make test     # builds and runs tests/test_fen (24 checks)

Usage

./fenlab --startpos
VALID FEN

8 | ♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜
7 | ♟ ♟ ♟ ♟ ♟ ♟ ♟ ♟
6 | · · · · · · · ·
5 | · · · · · · · ·
4 | · · · · · · · ·
3 | · · · · · · · ·
2 | ♙ ♙ ♙ ♙ ♙ ♙ ♙ ♙
1 | ♖ ♘ ♗ ♕ ♔ ♗ ♘ ♖
   a b c d e f g h 

side to move   : white
castling rights: KQkq
en passant     : -
halfmove clock : 0
fullmove number: 1
material       : white 39, black 39 (excludes kings)

round-trip FEN : rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1

Feed it any FEN (as one quoted string or as bare words — the shell splits it either way, fenlab rejoins them):

./fenlab rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1
VALID FEN

8 | ♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜
7 | ♟ ♟ ♟ ♟ ♟ ♟ ♟ ♟
6 | · · · · · · · ·
5 | · · · · · · · ·
4 | · · · · ♙ · · ·
3 | · · · · · · · ·
2 | ♙ ♙ ♙ ♙ · ♙ ♙ ♙
1 | ♖ ♘ ♗ ♕ ♔ ♗ ♘ ♖
   a b c d e f g h 

side to move   : black
castling rights: KQkq
en passant     : e3
halfmove clock : 0
fullmove number: 1
material       : white 39, black 39 (excludes kings)

round-trip FEN : rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1

Use --ascii for plain-letter rendering instead of Unicode glyphs (useful in terminals/fonts without chess symbols). Invalid input is rejected with a specific reason and a non-zero exit code:

$ ./fenlab "8/8/8/8/8/8/8/8 w - - 0 1"
INVALID: position must have exactly one white king (found 0)

How it works

  • src/fen.c splits the FEN into its (up to six) whitespace-separated fields. Piece placement is parsed rank by rank, validating that digits represent a 1-8 empty-square run and every rank sums to exactly 8 squares. Missing trailing fields fall back to standard defaults (w, -, -, 0, 1), so a bare piece-placement string is also accepted.
  • After parsing, validate_rules() checks chess-specific invariants: exactly one king per side, no more than 16 pieces or 8 pawns per side, no pawns on rank 1 or 8, and — for each claimed castling right — that the relevant king and rook are actually still on their home squares.
  • fen_serialize() walks the same board back into a FEN string (run-length encoding empty squares), which the CLI prints as a round-trip check.
  • src/render.c maps piece letters to Unicode chess glyphs (or plain ASCII) for the terminal board.
  • tests/test_fen.c is a small assert-based suite: round-trip fidelity for real positions, and rejection of malformed rank lengths, missing kings, unbacked castling rights, and bad en passant squares.

License

MIT, see LICENSE.

About

Strict FEN chess-position parser, validator, and board renderer, in C.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages