forked from lichess-org/lila
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGenerated.scala
50 lines (42 loc) · 1.61 KB
/
Generated.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package lila.puzzle
import scala.util.{ Try, Success, Failure }
import chess.format.{ Forsyth, UciMove }
import chess.{ Game, Variant }
import org.joda.time.DateTime
import play.api.libs.json._
case class Generated(
tags: List[String],
position: String,
solution: JsObject,
id: String) {
def toPuzzle: Try[PuzzleId => Puzzle] = for {
lines ← Generated readLines solution
history = position split ' '
_ ← if (history.isEmpty) Failure(new Exception("Empty history")) else Success(true)
fen ← Generated fenOf history
} yield Puzzle.make(
gameId = id.some,
tags = tags,
history = position.trim.split(' ').toList,
fen = fen,
lines = lines)
}
object Generated {
def readLines(obj: JsObject): Try[Lines] = (obj.fields.toList map {
case (move, JsString("win")) => Success(Win(move))
case (move, JsString("retry")) => Success(Retry(move))
case (move, more: JsObject) => readLines(more) map { Node(move, _) }
case (move, value) => Failure(new Exception(s"Invalid line $move $value"))
}).sequence
private[puzzle] def fenOf(moves: Seq[String]): Try[String] =
(moves.init.foldLeft(Try(Game(Variant.Standard))) {
case (game, moveStr) => game flatMap { g =>
(UciMove(moveStr) toValid s"Invalid UCI move $moveStr" flatMap {
case UciMove(orig, dest, prom) => g(orig, dest, prom) map (_._1)
}).fold(errs => Failure(new Exception(errs.shows)), Success.apply)
}
}) map { game =>
Forsyth >> Forsyth.SituationPlus(game.situation, moves.size / 2)
}
implicit val generatedJSONRead = Json.reads[Generated]
}