compute move data

This commit is contained in:
Thibault Duplessis 2015-07-21 19:07:43 +02:00
parent a14c110904
commit 173f67ae48
6 changed files with 59 additions and 4 deletions

View file

@ -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]

View file

@ -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)

View 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)
}

View file

@ -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

View file

@ -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
}
}

View file

@ -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])