From 1e9d9d6a34efe82e63fb848be216772056d21ccb Mon Sep 17 00:00:00 2001 From: Thanh Le Date: Sat, 7 Oct 2023 16:30:31 +0200 Subject: [PATCH 1/3] Traverse sans only once in gameMoveWhileValid - Fix reversed order when error happen - Add gameMoveWhileValidReverse because in some case we need games in reversed order, for example: https://github.com/lichess-org/lila/blob/27f1db88d269c17a04ccdbdfa67ed9cda6bd4514/modules/study/src/main/ServerEval.scala#L147 --- src/main/scala/Replay.scala | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/main/scala/Replay.scala b/src/main/scala/Replay.scala index fa1363394..29386a139 100644 --- a/src/main/scala/Replay.scala +++ b/src/main/scala/Replay.scala @@ -53,17 +53,18 @@ object Replay: ): (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 = games.headOption.fold(init)(_._1) + san(game.situation) + .map(m => (m.applyGame(game), Uci.WithSan(m.toUci, str)) :: games) + .leftMap(err => (init, games.reverse, err.some)) + .map(gs => (init, gs.reverse, none)) + .merge private def computeSituations[M]( sit: Situation, From 37c7630a6cfd289290829b0b4ac84953bec3b382 Mon Sep 17 00:00:00 2001 From: Thanh Le Date: Tue, 10 Oct 2023 20:03:25 +0200 Subject: [PATCH 2/3] Remove head.option --- src/main/scala/Replay.scala | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/scala/Replay.scala b/src/main/scala/Replay.scala index 29386a139..14387e3ca 100644 --- a/src/main/scala/Replay.scala +++ b/src/main/scala/Replay.scala @@ -54,16 +54,17 @@ object Replay: val init = makeGame(variant, initialFen.some) val emptyGames = List.empty[(Game, Uci.WithSan)] sans - .foldM(emptyGames): - case (games, str) => + .foldM((init, emptyGames)): + case ((head, games), str) => Parser .sanOnly(str) .flatMap: san => - val game = games.headOption.fold(init)(_._1) - san(game.situation) - .map(m => (m.applyGame(game), Uci.WithSan(m.toUci, str)) :: games) + san(head.situation) + .map: move => + val newGame = move.applyGame(head) + (newGame, (newGame, Uci.WithSan(move.toUci, str)) :: games) .leftMap(err => (init, games.reverse, err.some)) - .map(gs => (init, gs.reverse, none)) + .map(gs => (init, gs._2.reverse, none)) .merge private def computeSituations[M]( From 687091bf0fa8b7969f23ad44d528506ea0782f0f Mon Sep 17 00:00:00 2001 From: Thanh Le Date: Fri, 13 Oct 2023 15:27:43 +0200 Subject: [PATCH 3/3] Add gameMoveWhileValidReverse function --- src/main/scala/Replay.scala | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/scala/Replay.scala b/src/main/scala/Replay.scala index 14387e3ca..0430366f4 100644 --- a/src/main/scala/Replay.scala +++ b/src/main/scala/Replay.scala @@ -46,7 +46,7 @@ object Replay: ) ) - def gameMoveWhileValid( + def gameMoveWhileValidReverse( sans: Seq[SanStr], initialFen: Fen.Epd, variant: Variant @@ -63,10 +63,18 @@ object Replay: .map: move => val newGame = move.applyGame(head) (newGame, (newGame, Uci.WithSan(move.toUci, str)) :: games) - .leftMap(err => (init, games.reverse, err.some)) - .map(gs => (init, gs._2.reverse, none)) + .leftMap(err => (init, games, err.some)) + .map(gs => (init, gs._2, 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 (game, gs, err) => (game, gs.reverse, err) + private def computeSituations[M]( sit: Situation, moves: List[M],