diff --git a/ChessKit/Sources/ChessProtocol/UCI.swift b/ChessKit/Sources/ChessProtocol/UCI.swift index 007f0ac..8e3abab 100644 --- a/ChessKit/Sources/ChessProtocol/UCI.swift +++ b/ChessKit/Sources/ChessProtocol/UCI.swift @@ -69,7 +69,7 @@ public final class UCIEngine { // MARK: - Command handlers - /// Parses `position [startpos | fen <6 fields>] [moves ...]`. + /// Parses `position [startpos | fen ] [moves ...]`. private func applyPosition(_ args: [String]) { var index = 0 var newBoard: Board? @@ -78,8 +78,11 @@ public final class UCIEngine { newBoard = Board() index = 1 } else if args.first == "fen" { - // A FEN is up to six space-separated fields following "fen". - let fenFields = Array(args.dropFirst().prefix(6)) + // The FEN runs until the "moves" keyword, capped at six fields. + // Stopping at "moves" is what lets a short FEN (Board accepts 4–5 + // fields, defaulting the clocks) keep its trailing moves instead of + // swallowing the "moves" token and the moves into the FEN string. + let fenFields = Array(args.dropFirst().prefix { $0 != "moves" }.prefix(6)) newBoard = Board(fen: fenFields.joined(separator: " ")) index = 1 + fenFields.count } diff --git a/ChessKit/Tests/ChessProtocolTests/UCITests.swift b/ChessKit/Tests/ChessProtocolTests/UCITests.swift index 9e601bc..e374ae6 100644 --- a/ChessKit/Tests/ChessProtocolTests/UCITests.swift +++ b/ChessKit/Tests/ChessProtocolTests/UCITests.swift @@ -42,6 +42,16 @@ final class UCITests: XCTestCase { XCTAssertNil(uci.currentBoard[Sq.parse("e2")!]) } + func testPositionShortFENWithMoves() { + // A 4-field FEN (no halfmove/fullmove counters) followed by moves. + // The "moves" keyword must not be absorbed into the FEN, or the move + // is silently dropped and e2e4 is never applied. + let uci = makeAdapter() + uci.process("position fen 4k3/8/8/8/8/8/4P3/4K3 w - - moves e2e4") + XCTAssertEqual(uci.currentBoard[Sq.parse("e4")!], Piece(color: .white, kind: .pawn)) + XCTAssertNil(uci.currentBoard[Sq.parse("e2")!]) + } + func testUCINewGameResets() { let uci = makeAdapter() uci.process("position startpos moves e2e4")