feat(io): implement PgnParser.importGameContext with move replay
Implement the importGameContext method to validate PGN input via validatePgn() and replay each move using DefaultRules.applyMove to populate GameContext.moves. Returns final GameContext with all moves applied or error message on failure. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,35 @@ object PgnParser:
|
||||
val moveText = rest.mkString(" ")
|
||||
validateMovesText(moveText).map(moves => PgnGame(headers, moves))
|
||||
|
||||
/** Import a PGN text into a GameContext by validating and replaying all moves.
|
||||
* Returns Right(GameContext) with all moves applied and .moves populated.
|
||||
* Returns Left(error message) if validation fails or move replay encounters an issue. */
|
||||
def importGameContext(input: String): Either[String, GameContext] =
|
||||
validatePgn(input).flatMap { game =>
|
||||
// Replay moves to populate GameContext.moves via DefaultRules.applyMove
|
||||
val (finalCtx, errors) = game.moves.foldLeft((GameContext.initial, Option.empty[String])) {
|
||||
case ((ctx, Some(err)), _) => (ctx, Some(err)) // Already failed, stop
|
||||
case ((ctx, None), histMove) =>
|
||||
val moveOpt = parseAlgebraicMove(
|
||||
s"${histMove.from}${histMove.to}",
|
||||
ctx,
|
||||
ctx.turn
|
||||
)
|
||||
moveOpt match
|
||||
case None => (ctx, Some(s"Failed to parse move ${histMove.from}${histMove.to}"))
|
||||
case Some(move) =>
|
||||
val nextCtx = DefaultRules.applyMove(ctx, move)
|
||||
(nextCtx, None)
|
||||
}
|
||||
errors match
|
||||
case Some(err) => Left(err)
|
||||
case None =>
|
||||
if finalCtx.moves.isEmpty && game.moves.nonEmpty then
|
||||
Left("No moves were parsed from the PGN")
|
||||
else
|
||||
Right(finalCtx)
|
||||
}
|
||||
|
||||
/** Parse a complete PGN text into a PgnGame with headers and moves.
|
||||
* Always succeeds (returns Some); malformed tokens are silently skipped. */
|
||||
def parsePgn(pgn: String): Option[PgnGame] =
|
||||
|
||||
Reference in New Issue
Block a user