compute move data
This commit is contained in:
parent
a14c110904
commit
173f67ae48
|
@ -24,6 +24,9 @@ private[coach] object BSONHandlers {
|
|||
}
|
||||
def write(x: StatusScores) = intMapHandler write x.m.mapKeys(_.id.toString)
|
||||
}
|
||||
implicit val MoveBSONHandler = Macros.handler[Move]
|
||||
implicit val MovesBSONHandler = Macros.handler[Moves]
|
||||
|
||||
implicit val PerfResultsStreakBSONHandler = Macros.handler[Streak]
|
||||
implicit val PerfResultsOutcomeStatusesBSONHandler = Macros.handler[OutcomeStatuses]
|
||||
implicit val ResultsBestWinBSONHandler = Macros.handler[BestWin]
|
||||
|
|
|
@ -31,7 +31,9 @@ private[coach] final class JSONWriters(
|
|||
"title" -> u.title)
|
||||
})
|
||||
}
|
||||
implicit val ResultsWinWriter = OWrites[Results] { o =>
|
||||
implicit val MoveWriter = Json.writes[Move]
|
||||
implicit val MovesWriter = Json.writes[Moves]
|
||||
implicit val ResultsWriter = OWrites[Results] { o =>
|
||||
Json.obj(
|
||||
"nbGames" -> o.nbGames,
|
||||
"nbAnalysis" -> o.nbAnalysis,
|
||||
|
@ -40,6 +42,7 @@ private[coach] final class JSONWriters(
|
|||
"nbDraw" -> o.nbDraw,
|
||||
"ratingDiff" -> o.ratingDiff,
|
||||
"gameSections" -> o.gameSections,
|
||||
"moves" -> o.moves,
|
||||
"bestWin" -> o.bestWin,
|
||||
"opponentRatingAvg" -> o.opponentRatingAvg,
|
||||
"lastPlayed" -> o.lastPlayed)
|
||||
|
|
44
modules/coach/src/main/Moves.scala
Normal file
44
modules/coach/src/main/Moves.scala
Normal file
|
@ -0,0 +1,44 @@
|
|||
package lila.coach
|
||||
|
||||
case class Move(nbGames: Int, acplSum: Int) {
|
||||
|
||||
def acplAvg = (nbGames > 0) option (acplSum / nbGames)
|
||||
|
||||
def merge(m: Move) = Move(
|
||||
nbGames = nbGames + m.nbGames,
|
||||
acplSum = acplSum + m.acplSum)
|
||||
|
||||
def add(acpl: Int) = copy(nbGames + 1, acplSum + acpl)
|
||||
}
|
||||
|
||||
case class Moves(white: Vector[Move], black: Vector[Move]) {
|
||||
|
||||
private def aggregateSide(side: Vector[Move], p: RichPov): Vector[Move] =
|
||||
p.moveAccuracy.fold(side) {
|
||||
_.take(Moves.SIZE).zipWithIndex.foldLeft(side) {
|
||||
case (side, (cp, index)) => side.updated(index, side(index) add cp)
|
||||
}
|
||||
}
|
||||
|
||||
def aggregate(p: RichPov) = copy(
|
||||
white = if (p.pov.color.white) aggregateSide(white, p) else white,
|
||||
black = if (p.pov.color.black) aggregateSide(black, p) else black)
|
||||
|
||||
private def mergeMoves(l1: Vector[Move], l2: Vector[Move]) = l1.zip(l2).map {
|
||||
case (m1, m2) => m1 merge m2
|
||||
}
|
||||
|
||||
def merge(o: Moves) = Moves(
|
||||
white = mergeMoves(white, o.white),
|
||||
black = mergeMoves(black, o.black))
|
||||
}
|
||||
|
||||
object Moves {
|
||||
|
||||
val SIZE = 80
|
||||
|
||||
private val emptyMove = Move(0, 0)
|
||||
private val emptySideData: Vector[Move] = Vector.fill(SIZE)(emptyMove)
|
||||
|
||||
val empty = Moves(emptySideData, emptySideData)
|
||||
}
|
|
@ -12,6 +12,7 @@ case class Results(
|
|||
nbDraw: Int,
|
||||
ratingDiff: Int,
|
||||
gameSections: GameSections,
|
||||
moves: Moves,
|
||||
bestWin: Option[Results.BestWin],
|
||||
opponentRatingSum: Int,
|
||||
lastPlayed: Option[DateTime]) {
|
||||
|
@ -28,6 +29,7 @@ case class Results(
|
|||
nbDraw = nbDraw + p.pov.game.drawn.fold(1, 0),
|
||||
ratingDiff = ratingDiff + ~p.pov.player.ratingDiff,
|
||||
gameSections = gameSections aggregate p,
|
||||
moves = moves aggregate p,
|
||||
bestWin = if (~p.pov.win) {
|
||||
Results.makeBestWin(p.pov).fold(bestWin) { newBest =>
|
||||
bestWin.fold(newBest) { prev =>
|
||||
|
@ -47,6 +49,7 @@ case class Results(
|
|||
nbDraw = nbDraw + r.nbDraw,
|
||||
ratingDiff = ratingDiff + r.ratingDiff,
|
||||
gameSections = gameSections merge r.gameSections,
|
||||
moves = moves merge r.moves,
|
||||
bestWin = (bestWin, r.bestWin) match {
|
||||
case (Some(a), Some(b)) => Some(a merge b)
|
||||
case (Some(a), _) => a.some
|
||||
|
@ -64,7 +67,7 @@ case class Results(
|
|||
|
||||
object Results {
|
||||
|
||||
val empty = Results(0, 0, 0, 0, 0, 0, GameSections.empty, none, 0, none)
|
||||
val empty = Results(0, 0, 0, 0, 0, 0, GameSections.empty, Moves.empty, none, 0, none)
|
||||
|
||||
case class BestWin(id: String, userId: String, rating: Int) {
|
||||
def merge(b: BestWin) = if (rating > b.rating) this else b
|
||||
|
|
|
@ -74,7 +74,8 @@ private object StatApi {
|
|||
initialFen = fen,
|
||||
analysis = an,
|
||||
division = division,
|
||||
accuracy = an.flatMap { lila.analyse.Accuracy(pov, _, division) }
|
||||
accuracy = an.flatMap { lila.analyse.Accuracy(pov, _, division) },
|
||||
moveAccuracy = an.map { lila.analyse.Accuracy.diffsList(pov, _) }
|
||||
).some
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ case class RichPov(
|
|||
initialFen: Option[String],
|
||||
analysis: Option[lila.analyse.Analysis],
|
||||
division: chess.Division,
|
||||
accuracy: Option[lila.analyse.Accuracy.DividedAccuracy])
|
||||
accuracy: Option[lila.analyse.Accuracy.DividedAccuracy],
|
||||
moveAccuracy: Option[List[Int]])
|
||||
|
||||
case class OpeningFamily(firstMove: String, results: Results, families: List[String])
|
||||
|
|
Loading…
Reference in a new issue