lila/modules/insight/src/main/Metric.scala

246 lines
5.3 KiB
Scala

package lila.insight
import scalatags.Text.all._
import reactivemongo.api.bson._
sealed abstract class Metric(
val key: String,
val name: String,
val dbKey: String,
val position: Position,
val per: Position,
val dataType: Metric.DataType,
val description: String
)
object Metric {
sealed trait DataType {
def name = toString.toLowerCase
}
object DataType {
case object Seconds extends DataType
case object Count extends DataType
case object Average extends DataType
case object Percent extends DataType
}
import DataType._
import Position._
import InsightEntry.{ BSONFields => F }
case object MeanCpl
extends Metric(
"acpl",
"Average centipawn loss",
F moves "c",
Move,
Move,
Average,
"""Precision of your moves. Lower is better."""
)
case object CplBucket
extends Metric(
"cplBucket",
"Centipawn loss bucket",
F moves "c",
Move,
Move,
Percent,
Dimension.CplRange.description
)
case object Movetime
extends Metric(
"movetime",
"Move time",
F moves "t",
Move,
Move,
Seconds,
Dimension.MovetimeRange.description
)
case object Result
extends Metric("result", "Game result", F.result, Game, Game, Percent, Dimension.Result.description)
case object Termination
extends Metric(
"termination",
"Game termination",
F.termination,
Game,
Game,
Percent,
Dimension.Termination.description
)
case object RatingDiff
extends Metric(
"ratingDiff",
"Rating gain",
F.ratingDiff,
Game,
Game,
Average,
"The amount of rating points you win or lose when the game ends."
)
case object OpponentRating
extends Metric(
"opponentRating",
"Opponent rating",
F.opponentRating,
Game,
Game,
Average,
"The average rating of your opponent for the relevant variant."
)
case object NbMoves
extends Metric(
"nbMoves",
"Moves per game",
F moves "r",
Move,
Game,
Average,
"Number of moves you play in the game. Doesn't count the opponent moves."
)
case object PieceRole
extends Metric(
"piece",
"Piece moved",
F moves "r",
Move,
Move,
Percent,
Dimension.PieceRole.description
)
case object Opportunism
extends Metric(
"opportunism",
"Opportunism",
F moves "o",
Move,
Move,
Percent,
"How often you take advantage of your opponent blunders. 100% means you punish them all, 0% means you counter-blunder them all."
)
case object Luck
extends Metric(
"luck",
"Luck",
F moves "l",
Move,
Move,
Percent,
"How often your opponent fails to punish your blunders. 100% means they miss all your blunders, 0% means they spot them all."
)
case object Material
extends Metric(
"material",
"Material imbalance",
F moves "i",
Move,
Move,
Average,
Dimension.MaterialRange.description
)
case object Blurs
extends Metric(
"blurs",
"Blurs",
F moves "b",
Move,
Move,
Percent,
"How often moves are preceded by a window blur."
)
case object TimeVariance
extends Metric(
"timeVariance",
"Time variance",
F moves "v",
Move,
Move,
Average,
"Low variance means consistent move times"
)
val all = List(
MeanCpl,
CplBucket,
Movetime,
Result,
Termination,
RatingDiff,
OpponentRating,
NbMoves,
PieceRole,
Opportunism,
Luck,
Material,
Blurs,
TimeVariance
)
val byKey = all map { p =>
(p.key, p)
} toMap
def requiresAnalysis(m: Metric) =
m match {
case MeanCpl => true
case CplBucket => true
case _ => false
}
def requiresStableRating(m: Metric) =
m match {
case RatingDiff => true
case OpponentRating => true
case _ => false
}
def isStacked(m: Metric) =
m match {
case Result => true
case Termination => true
case PieceRole => true
case CplBucket => true
case _ => false
}
def valuesOf(metric: Metric): List[MetricValue] =
metric match {
case Result =>
lila.insight.Result.all.map { r =>
MetricValue(BSONInteger(r.id), MetricValueName(r.name))
}
case Termination =>
lila.insight.Termination.all.map { r =>
MetricValue(BSONInteger(r.id), MetricValueName(r.name))
}
case PieceRole =>
chess.Role.all.reverse.map { r =>
MetricValue(BSONString(r.forsyth.toString), MetricValueName(r.toString))
}
case CplBucket =>
lila.insight.CplRange.all.map { cpl =>
MetricValue(BSONInteger(cpl.cpl), MetricValueName(cpl.name))
}
case _ => Nil
}
case class MetricValueName(name: String)
case class MetricValue(key: BSONValue, name: MetricValueName)
}