refactor(core): simplify castling logic and improve move translation methods
Build & Test (NowChessSystems) TeamCity build failed

This commit is contained in:
2026-04-05 17:48:06 +02:00
parent 1fc5e43e77
commit 0778882db6
3 changed files with 66 additions and 71 deletions
@@ -7,7 +7,6 @@ import de.nowchess.chess.controller.Parser
import de.nowchess.chess.observer.*
import de.nowchess.chess.command.{CommandInvoker, MoveCommand, MoveResult}
import de.nowchess.io.{GameContextImport, GameContextExport}
import de.nowchess.io.pgn.PgnParser
import de.nowchess.rules.RuleSet
import de.nowchess.rules.sets.DefaultRules
@@ -142,34 +141,43 @@ class GameEngine(
importer.importGameContext(input) match
case Left(err) => Left(err)
case Right(ctx) =>
val savedContext = currentContext
currentContext = GameContext.initial
pendingPromotion = None
invoker.clear()
if ctx.moves.isEmpty then
currentContext = ctx
replayGame(ctx).map { _ =>
notifyObservers(PgnLoadedEvent(currentContext))
Right(())
else
var error: Option[String] = None
ctx.moves.foreach: move =>
handleParsedMove(move.from, move.to)
move.moveType match
case MoveType.Promotion(pp) =>
if pendingPromotion.isDefined then completePromotion(pp)
else error = Some(s"Promotion required for move ${move.from}${move.to}")
case _ => ()
error match
case Some(err) =>
currentContext = savedContext
Left(err)
case None =>
notifyObservers(PgnLoadedEvent(currentContext))
Right(())
}
}
private def replayGame(ctx: GameContext): Either[String, Unit] =
val savedContext = currentContext
currentContext = GameContext.initial
pendingPromotion = None
invoker.clear()
if ctx.moves.isEmpty then
currentContext = ctx
Right(())
else
replayMoves(ctx.moves, savedContext)
private def replayMoves(moves: List[Move], savedContext: GameContext): Either[String, Unit] =
var error: Option[String] = None
moves.foreach: move =>
if error.isEmpty then
handleParsedMove(move.from, move.to)
move.moveType match
case MoveType.Promotion(pp) =>
if pendingPromotion.isDefined then
completePromotion(pp)
else
error = Some(s"Promotion required for move ${move.from}${move.to}")
case _ => ()
error match
case Some(err) =>
currentContext = savedContext
Left(err)
case None =>
Right(())
/** Export the current game context using the provided exporter. */
def exportGame(exporter: GameContextExport): String = synchronized {
exporter.exportGameContext(currentContext)
@@ -202,7 +210,7 @@ class GameEngine(
to = move.to,
moveResult = Some(MoveResult.Successful(nextContext, captured)),
previousContext = Some(contextBefore),
notation = moveToPgn(move, contextBefore.board)
notation = translateMoveToNotation(move, contextBefore.board)
)
invoker.execute(cmd)
currentContext = nextContext
@@ -229,7 +237,7 @@ class GameEngine(
if currentContext.halfMoveClock >= 100 then
notifyObservers(FiftyMoveRuleAvailableEvent(currentContext))
private def moveToPgn(move: Move, boardBefore: Board): String =
private def translateMoveToNotation(move: Move, boardBefore: Board): String =
move.moveType match
case MoveType.CastleKingside => "O-O"
case MoveType.CastleQueenside => "O-O-O"