From 28f015e7436fcf4d35356f2617cd0cc5d913f9cf Mon Sep 17 00:00:00 2001 From: Thanh Le Date: Sat, 7 Oct 2023 16:30:31 +0200 Subject: [PATCH] Traverse sans only once in gameMoveWhileValid Also add gameMoveWhileValidReverse because in some case we need games in reverse order, for example: https://github.com/lichess-org/lila/blob/27f1db88d269c17a04ccdbdfa67ed9cda6bd4514/modules/study/src/main/ServerEval.scala#L147 --- src/main/scala/Replay.scala | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/main/scala/Replay.scala b/src/main/scala/Replay.scala index fa1363394..4afa7d963 100644 --- a/src/main/scala/Replay.scala +++ b/src/main/scala/Replay.scala @@ -46,24 +46,33 @@ object Replay: ) ) - def gameMoveWhileValid( + def gameMoveWhileValidReverse( sans: Seq[SanStr], initialFen: Fen.Epd, variant: Variant ): (Game, List[(Game, Uci.WithSan)], Option[ErrorStr]) = val init = makeGame(variant, initialFen.some) val emptyGames = List.empty[(Game, Uci.WithSan)] - (for - moves <- Parser.moves(sans).leftMap(err => (init, emptyGames, err.some)) - games <- moves.value - .zip(sans) - .foldM(emptyGames): - case (games, (san, sanStr)) => - val game = games.headOption.fold(init)(_._1) - san(game.situation) - .leftMap(err => (init, games, err.some)) - .map(m => (m.applyGame(game), Uci.WithSan(m.toUci, sanStr)) :: games) - yield (init, games.reverse, none)).merge + sans + .foldM(emptyGames): + case (games, str) => + Parser + .sanOnly(str) + .flatMap: san => + val game: Game = games.headOption.fold(init)(_._1) + san(game.situation) + .map(m => (m.applyGame(game), Uci.WithSan(m.toUci, str)) :: games) + .leftMap(err => (init, games, err.some)) + .map(gs => (init, gs, none)) + .merge + + def gameMoveWhileValid( + sans: Seq[SanStr], + initialFen: Fen.Epd, + variant: Variant + ): (Game, List[(Game, Uci.WithSan)], Option[ErrorStr]) = + gameMoveWhileValidReverse(sans, initialFen, variant) match + case (g, gs, err) => (g, gs.reverse, err) private def computeSituations[M]( sit: Situation,