From 5114303f7866c47b932c63a3e6f647b743ccd05c Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Tue, 31 Dec 2024 11:26:28 +0100 Subject: [PATCH] dgt json has conflicting clock times, in move list and clock object use the clock object when that happens. It might be wrong in fewer occasions, but who knows. --- modules/relay/src/main/DgtJson.scala | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/modules/relay/src/main/DgtJson.scala b/modules/relay/src/main/DgtJson.scala index bd9a13df4cbc..1fac6d12da93 100644 --- a/modules/relay/src/main/DgtJson.scala +++ b/modules/relay/src/main/DgtJson.scala @@ -2,7 +2,7 @@ package lila.relay import play.api.libs.json.* import scalalib.model.Seconds -import chess.{ Centis, Outcome } +import chess.{ Centis, Outcome, ByColor } import chess.format.pgn.{ PgnStr, SanStr, Move, Tag, Tags } private object DgtJson: @@ -46,7 +46,11 @@ private object DgtJson: case class ClockJson(white: Option[Seconds], black: Option[Seconds], time: Long): def referenceTime: Instant = millisToInstant(time) + def byColor = ByColor(white, black) + /** This is DGT so it's all sorts of wrong. When the clock time is set in both the move `Rxd1 3010` and in + * `clock.white`, then the latter should be used. Most of the time. + */ case class GameJson( moves: List[String], result: Option[String], @@ -71,8 +75,10 @@ private object DgtJson: ).flatten ) def toPgn(roundTags: Tags): PgnStr = - val mergedTags = clockTags ++ mergeRoundTags(roundTags) - val strMoves = moves.map(parseMove).map(_.render).mkString(" ") + val mergedTags = clockTags ++ mergeRoundTags(roundTags) + val parsedMoves = moves.map(parseMove) + val fixedMoves = clock.foldLeft(parsedMoves)(replaceLastMoveTimesWithClock) + val strMoves = fixedMoves.map(_.render).mkString(" ") PgnStr(s"$mergedTags\n\n$strMoves") /* - dxe4 63 @@ -89,7 +95,15 @@ private object DgtJson: case Array("", emt) => (none, emt.toIntOption) case Array(clk, emt) => (clk.toIntOption, emt.toIntOption) case _ => (none, none) - Move(san = SanStr(~parts.headOption), secondsLeft = clk, moveTime = emt) + Move(san = SanStr(~parts.headOption), timeLeft = Seconds.from(clk), moveTime = Seconds.from(emt)) + + private def replaceLastMoveTimesWithClock(moves: List[Move], clock: ClockJson): List[Move] = + val lastMoveIndex = moves.size - 1 + def change(move: Move, sec: Option[Seconds]) = sec.fold(move)(s => move.copy(timeLeft = s.some)) + moves.mapWithIndex: (move, i) => + if i >= lastMoveIndex - 1 + then change(move, clock.byColor(Color.fromWhite(i % 2 == 0))) + else move given Reads[PairingPlayer] = Json.reads given Reads[RoundJsonPairing] = Json.reads