lila/modules/coach_old/src/main/Results.scala

88 lines
2.6 KiB
Scala

package lila.coach
import org.joda.time.DateTime
import lila.game.Pov
case class Results(
nbGames: Int,
nbAnalysis: Int,
nbWin: Int,
nbLoss: Int,
nbDraw: Int,
ratingDiff: Int,
gameSections: GameSections,
bestWin: Option[Results.BestWin],
opponentRatingSum: Int,
lastPlayed: Option[DateTime]) {
def opponentRatingAvg = (nbGames > 0) option (opponentRatingSum / nbGames)
def ratingDiffAvg = (nbGames > 0) option (ratingDiff / nbGames)
def aggregate(p: RichPov) = copy(
nbGames = nbGames + 1,
nbAnalysis = nbAnalysis + p.analysis.isDefined.fold(1, 0),
nbWin = nbWin + (~p.pov.win).fold(1, 0),
nbLoss = nbLoss + (~p.pov.loss).fold(1, 0),
nbDraw = nbDraw + p.pov.game.drawn.fold(1, 0),
ratingDiff = ratingDiff + ~p.pov.player.ratingDiff,
gameSections = gameSections aggregate p,
bestWin = if (~p.pov.win) {
Results.makeBestWin(p.pov).fold(bestWin) { newBest =>
bestWin.fold(newBest) { prev =>
if (newBest.rating > prev.rating) newBest else prev
}.some
}
}
else bestWin,
opponentRatingSum = opponentRatingSum + ~p.pov.opponent.rating,
lastPlayed = p.pov.game.createdAt.some)
def merge(r: Results) = Results(
nbGames = nbGames + r.nbGames,
nbAnalysis = nbAnalysis + r.nbAnalysis,
nbWin = nbWin + r.nbWin,
nbLoss = nbLoss + r.nbLoss,
nbDraw = nbDraw + r.nbDraw,
ratingDiff = ratingDiff + r.ratingDiff,
gameSections = gameSections merge r.gameSections,
bestWin = (bestWin, r.bestWin) match {
case (Some(a), Some(b)) => Some(a merge b)
case (Some(a), _) => a.some
case (_, Some(b)) => b.some
case _ => none
},
opponentRatingSum = opponentRatingSum + r.opponentRatingSum,
lastPlayed = (lastPlayed, r.lastPlayed) match {
case (Some(a), Some(b)) => Some(if (a isAfter b) a else b)
case (Some(a), _) => a.some
case (_, Some(b)) => b.some
case _ => none
})
}
object Results {
val empty = Results(0, 0, 0, 0, 0, 0, GameSections.empty, none, 0, none)
case class BestWin(id: String, userId: String, rating: Int) {
def merge(b: BestWin) = if (rating > b.rating) this else b
}
def makeBestWin(pov: Pov): Option[BestWin] = (pov.game.playedTurns > 4) ?? {
pov.opponent.userId |@| pov.opponent.rating apply {
case (opId, opRating) => BestWin(pov.gameId, opId, opRating)
}
}
case class Computation(results: Results) {
def aggregate(p: RichPov) = copy(results = results.aggregate(p))
def nbGames = results.nbGames
def run = results
}
val emptyComputation = Computation(empty)
}