feat: add FEN exporter and round-trip tests

Implements FenExporter.boardToFen() converting Board to FEN piece-placement string,
and adds three round-trip tests (initial position, empty board, partial position).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-28 18:33:03 +01:00
parent 2925c385bc
commit 2974029473
2 changed files with 27 additions and 0 deletions
@@ -1,8 +1,11 @@
package de.nowchess.chess.notation
import de.nowchess.api.board.*
<<<<<<< HEAD
import de.nowchess.api.game.{CastlingRights, GameState}
import de.nowchess.api.board.Color
=======
>>>>>>> cc62cd2 (feat: add FEN exporter and round-trip tests)
object FenExporter:
@@ -31,6 +34,7 @@ object FenExporter:
if emptyCount > 0 then rankChars += emptyCount.toString.charAt(0)
rankChars.mkString
<<<<<<< HEAD
/** Convert a GameState to a complete FEN string. */
def gameStateToFen(state: GameState): String =
val piecePlacement = state.piecePlacement
@@ -48,6 +52,8 @@ object FenExporter:
val result = s"$wk$wq$bk$bq"
if result.isEmpty then "-" else result
=======
>>>>>>> cc62cd2 (feat: add FEN exporter and round-trip tests)
/** Convert a Piece to its FEN character (uppercase = White, lowercase = Black). */
private def pieceToPgnChar(piece: Piece): Char =
val base = piece.pieceType match
@@ -40,3 +40,24 @@ class FenParserTest extends AnyFunSuite with Matchers:
board.map(_.pieceAt(Square(File.E, Rank.R6))) shouldBe Some(Some(Piece.BlackKing))
board.map(_.pieceAt(Square(File.E, Rank.R4))) shouldBe Some(Some(Piece.WhiteKing))
test("testRoundTripInitialPosition"):
val originalFen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR"
val board = FenParser.parseBoard(originalFen)
val exportedFen = board.map(FenExporter.boardToFen)
exportedFen shouldBe Some(originalFen)
test("testRoundTripEmptyBoard"):
val originalFen = "8/8/8/8/8/8/8/8"
val board = FenParser.parseBoard(originalFen)
val exportedFen = board.map(FenExporter.boardToFen)
exportedFen shouldBe Some(originalFen)
test("testRoundTripPartialPosition"):
val originalFen = "8/8/4k3/8/4K3/8/8/8"
val board = FenParser.parseBoard(originalFen)
val exportedFen = board.map(FenExporter.boardToFen)
exportedFen shouldBe Some(originalFen)