refactor: NCS-22 NCS-23 reworked modules and tests #17
@@ -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