refactor: NCS-22 NCS-23 reworked modules and tests #17

Merged
Janis merged 42 commits from refactor/NCS-22 into main 2026-04-06 09:07:40 +02:00
Showing only changes of commit 7c42260d14 - Show all commits
@@ -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] =