Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions app/views/mod/games.scala
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,9 @@ def games(
case None => span(cls := "result")("½")
,
pov.player.ratingDiff match
case Some(d) if d > 0 => goodTag(s"+$d")
case Some(d) if d < 0 => badTag(d)
case _ => span("-")
case Some(d) if d.positive => goodTag(s"+$d")
case Some(d) if d.negative => badTag(d)
case _ => span("-")
),
assessment match
case Some(Left(full)) => td(dataSort := full.analysis.avg)(full.analysis.toString)
Expand Down
2 changes: 1 addition & 1 deletion modules/activity/src/main/BSONHandlers.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package lila.activity

import reactivemongo.api.bson.*

import scala.util.Success
import chess.IntRating

import lila.common.LichessDay
import lila.core.chess.Rank
Expand Down
3 changes: 2 additions & 1 deletion modules/activity/src/main/model.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ object RatingProg:
case _ => rp2O.orElse(rp1O)
def make(player: lila.core.game.LightPlayer) =
player.rating.map: rating =>
lila.core.rating.RatingProg(rating, rating.applyDiff(~player.ratingDiff))
val newRating = player.ratingDiff.fold(rating)(diff => rating.map(_ + diff.value))
lila.core.rating.RatingProg(rating, newRating)

object Score:
extension (s: Score)
Expand Down
5 changes: 3 additions & 2 deletions modules/clas/src/main/ClasProgress.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package lila.clas

import java.time.Duration
import reactivemongo.api.*
import reactivemongo.api.bson.*
import scalalib.model.Days

import java.time.Duration
import chess.IntRating
import chess.rating.IntRatingDiff

import lila.core.game.GameRepo
import lila.core.user.WithPerf
Expand Down
2 changes: 1 addition & 1 deletion modules/clas/src/main/ui/DashboardUi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ final class DashboardUi(helpers: Helpers, ui: ClasUi)(using NetDomain):
tr(
studentTd(c, s),
td(dataSort := perf.intRating, cls := "rating")(perf.glicko.display),
td(dataSort := prog.ratingProgress)(
td(dataSort := prog.ratingProgress.value)(
ratingProgress(prog.ratingProgress) | trans.clas.na.txt()
),
td(prog.nb),
Expand Down
1 change: 1 addition & 0 deletions modules/coach/src/main/Coach.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package lila.coach

import reactivemongo.api.bson.Macros.Annotations.Key
import chess.IntRating

import lila.core.id.ImageId
import lila.core.perf.UserWithPerfs
Expand Down
3 changes: 2 additions & 1 deletion modules/core/src/main/challenge.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ package challenge

import _root_.chess.variant.Variant
import _root_.chess.{ Color, Mode }
import _root_.chess.rating.RatingProvisional
import _root_.chess.IntRating
import scalalib.model.Days

import lila.core.id.ChallengeId
import lila.core.rating.data.*
import lila.core.userId.UserId

trait Challenge:
Expand Down
3 changes: 2 additions & 1 deletion modules/core/src/main/fide.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package lila.core
package fide

import _root_.chess.{ FideId, PlayerName, PlayerTitle, Elo, KFactor }
import _root_.chess.{ FideId, PlayerName, PlayerTitle }
import _root_.chess.rating.{ Elo, KFactor }

enum FideTC:
case standard, rapid, blitz
Expand Down
12 changes: 8 additions & 4 deletions modules/core/src/main/game/Game.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import _root_.chess.{
Mode,
Ply,
Speed,
Status
Status,
Outcome,
IntRating
}
import scalalib.model.Days

Expand Down Expand Up @@ -193,6 +195,7 @@ case class Game(
def loser: Option[Player] = winner.map(opponent)

def winnerColor: Option[Color] = winner.map(_.color)
def outcome: Option[Outcome] = finished.option(Outcome(winnerColor))

def winnerUserId: Option[UserId] = winner.flatMap(_.userId)

Expand Down Expand Up @@ -254,9 +257,10 @@ case class Game(
if w != b
yield w -> b

def averageUsersRating = players.flatMap(_.rating) match
case a :: b :: Nil => Some((a + b).value / 2)
case a :: Nil => Some((a + 1500).value / 2)
def averageUsersRating: Option[IntRating] = players.flatMap(_.rating) match
// case a :: b :: Nil => Some((a + b).map(_ / 2))
case a :: b :: Nil => Some((a + b))
case a :: Nil => Some((a + IntRating(1500)).map(_ / 2))
case _ => None

def isPgnImport = pgnImport.isDefined
Expand Down
14 changes: 10 additions & 4 deletions modules/core/src/main/game/Player.scala
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package lila.core
package game

import _root_.chess.{ Color, PlayerName, Ply }
import _root_.chess.{ Color, PlayerName, Ply, IntRating }
import _root_.chess.rating.{ IntRatingDiff, RatingProvisional }
import cats.kernel.Eq

import lila.core.id.GamePlayerId
import lila.core.perf.Perf
import lila.core.rating.data.{ IntRating, IntRatingDiff, RatingProvisional }
import lila.core.user.WithPerf
import lila.core.userId.{ UserId, UserIdOf }

Expand Down Expand Up @@ -43,11 +43,17 @@ case class Player(
case ((None, _), (Some(_), _)) => false
case ((_, a), (_, b)) => a.value < b.value

def ratingAfter = rating.map(_.applyDiff(~ratingDiff))
def ratingAfter = for
r <- rating
d <- ratingDiff
yield r.map(_ + d.value)

def stableRating = rating.ifFalse(provisional.value)

def stableRatingAfter = stableRating.map(_.applyDiff(~ratingDiff))
def stableRatingAfter = for
r <- stableRating
d <- ratingDiff
yield r.map(_ + d.value)

def light = LightPlayer(color, aiLevel, userId, rating, ratingDiff, provisional, berserk)

Expand Down
4 changes: 2 additions & 2 deletions modules/core/src/main/game/light.scala
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package lila.core
package game

import _root_.chess.{ Color, Status }
import _root_.chess.{ Color, Status, IntRating }
import _root_.chess.variant.Variant
import _root_.chess.rating.{ IntRatingDiff, RatingProvisional }

import lila.core.id.GameId
import lila.core.rating.data.{ IntRating, IntRatingDiff, RatingProvisional }
import lila.core.userId.UserId

case class LightGame(
Expand Down
2 changes: 1 addition & 1 deletion modules/core/src/main/history.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package lila.core
package history

import scalalib.model.Days
import _root_.chess.IntRating

import lila.core.perf.{ Perf, PerfKey }
import lila.core.rating.data.IntRating
import lila.core.user.{ User, WithPerf }
import lila.core.userId.UserId

Expand Down
1 change: 0 additions & 1 deletion modules/core/src/main/lilaism/Lilaism.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ object Lilaism extends LilaLibraryExtensions:
}
export lila.core.userId.{ UserId, UserName, UserStr, MyId, UserIdOf }
export lila.core.data.{ Markdown, Html, JsonStr }
export lila.core.rating.data.{ IntRating, IntRatingDiff, RatingProvisional }
export lila.core.perf.{ PerfKey, Perf }
export lila.core.email.EmailAddress
export lila.core.user.{ User, Me }
Expand Down
28 changes: 25 additions & 3 deletions modules/core/src/main/perf.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package lila.core

import _root_.chess.variant.Variant
import _root_.chess.{ Speed, variant as ChessVariant }
import _root_.chess.{ Speed, IntRating, variant as ChessVariant }
import _root_.chess.rating.{ IntRatingDiff }
import _root_.chess.rating.glicko.Glicko
import monocle.syntax.all.*
import monocle.syntax.AppliedPLens

import lila.core.rating.Glicko
import lila.core.rating.data.{ IntRating, IntRatingDiff }
import lila.core.userId.{ UserId, UserIdOf }

object perf:
Expand Down Expand Up @@ -171,6 +173,26 @@ object perf:

def keyed(key: PerfKey): KeyedPerf = KeyedPerf(key, apply(key))

def focusKey(key: PerfKey): AppliedPLens[UserPerfs, UserPerfs, Perf, Perf] = key match
case "bullet" => this.focus(_.bullet)
case "blitz" => this.focus(_.blitz)
case "rapid" => this.focus(_.rapid)
case "classical" => this.focus(_.classical)
case "correspondence" => this.focus(_.correspondence)
case "ultraBullet" => this.focus(_.ultraBullet)
case "standard" => this.focus(_.standard)
case "chess960" => this.focus(_.chess960)
case "kingOfTheHill" => this.focus(_.kingOfTheHill)
case "threeCheck" => this.focus(_.threeCheck)
case "antichess" => this.focus(_.antichess)
case "atomic" => this.focus(_.atomic)
case "horde" => this.focus(_.horde)
case "racingKings" => this.focus(_.racingKings)
case "crazyhouse" => this.focus(_.crazyhouse)
case "puzzle" => this.focus(_.puzzle)
// impossible because PerfKey can't be instantiated with arbitrary values
case key => sys.error(s"Unknown perf key: $key")

case class UserWithPerfs(user: lila.core.user.User, perfs: UserPerfs):
export user.*
object UserWithPerfs:
Expand Down
2 changes: 1 addition & 1 deletion modules/core/src/main/pool.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package lila.core
package pool

import _root_.chess.{ ByColor, Clock }
import _root_.chess.IntRating
import alleycats.Zero

import lila.core.id.GameFullId
import lila.core.perf.PerfKey
import lila.core.rating.RatingRange
import lila.core.rating.data.IntRating
import lila.core.socket.Sri
import lila.core.userId.*

Expand Down
42 changes: 4 additions & 38 deletions modules/core/src/main/rating.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,8 @@ package lila.core
package rating

import alleycats.Zero

object data:

opaque type IntRating = Int
object IntRating extends RelaxedOpaqueInt[IntRating]:
extension (r: IntRating) def applyDiff(diff: IntRatingDiff): IntRating = r + diff.value

opaque type IntRatingDiff = Int
object IntRatingDiff extends RelaxedOpaqueInt[IntRatingDiff]:
given Zero[IntRatingDiff] = Zero(0)

opaque type Rating = Double
object Rating extends OpaqueDouble[Rating]

opaque type RatingProvisional = Boolean
object RatingProvisional extends YesNo[RatingProvisional]

import data.*

case class Glicko(
rating: Double,
deviation: Double,
volatility: Double
):
override def toString = f"$intRating/$intDeviation/${volatility}%.3f"
def intRating: IntRating = IntRating(rating.toInt)
def intDeviation = deviation.toInt
def provisional = RatingProvisional(deviation >= Glicko.provisionalDeviation)
def established = provisional.no
def establishedIntRating = Option.when(established)(intRating)
def clueless = deviation >= Glicko.cluelessDeviation
def display = s"$intRating${if provisional.yes then "?" else ""}"

object Glicko:
val provisionalDeviation = 110
val cluelessDeviation = 230
import _root_.chess.IntRating
import _root_.chess.rating.IntRatingDiff

case class RatingProg(before: IntRating, after: IntRating):
def diff = IntRatingDiff(after.value - before.value)
Expand All @@ -53,8 +19,8 @@ case class RatingRange(min: IntRating, max: IntRating):

object RatingRange:

val min = IntRating(400)
val max = IntRating(2900)
val min: IntRating = IntRating(400)
val max: IntRating = IntRating(2900)

val broad = RatingRange(min, max)
val default = broad
Expand Down
6 changes: 3 additions & 3 deletions modules/core/src/main/user.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package lila.core

import _root_.chess.{ Color, ByColor, PlayerTitle }
import _root_.chess.{ Color, ByColor, PlayerTitle, IntRating }
import _root_.chess.rating.IntRatingDiff
import _root_.chess.rating.glicko.Glicko
import play.api.i18n.Lang
import play.api.libs.json.JsObject
import reactivemongo.api.bson.Macros.Annotations.Key
Expand All @@ -11,8 +13,6 @@ import scalalib.model.Days
import lila.core.email.*
import lila.core.id.Flair
import lila.core.perf.{ KeyedPerf, Perf, PerfKey, UserPerfs, UserWithPerfs }
import lila.core.rating.Glicko
import lila.core.rating.data.{ IntRating, IntRatingDiff }
import lila.core.userId.*

object user:
Expand Down
3 changes: 2 additions & 1 deletion modules/evaluation/src/main/PlayerAggregateAssessment.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package lila.evaluation

import scala.math.sqrt
import chess.IntRating

import lila.core.perf.UserWithPerfs
import lila.rating.UserPerfsExt.bestRating
Expand Down Expand Up @@ -98,7 +99,7 @@ case class PlayerAggregateAssessment(
val sfAvgHold = sfAvgGiven(_.basics.hold)
val sfAvgNoHold = sfAvgGiven(!_.basics.hold)

def isGreatUser = user.perfs.bestRating > 2500 && user.count.rated >= 100
def isGreatUser = user.perfs.bestRating > IntRating(2500) && user.count.rated >= 100

def isNewRatedUser = user.count.rated < 10

Expand Down
3 changes: 2 additions & 1 deletion modules/fide/src/main/FidePlayer.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package lila.fide

import chess.{ FideId, PlayerName, PlayerTitle, Elo, KFactor }
import chess.{ FideId, PlayerName, PlayerTitle }
import chess.rating.{ Elo, KFactor }
import reactivemongo.api.bson.Macros.Annotations.Key

import java.text.Normalizer
Expand Down
3 changes: 2 additions & 1 deletion modules/fide/src/main/FidePlayerSync.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ package lila.fide

import akka.stream.contrib.ZipInputStreamSource
import akka.stream.scaladsl.*
import chess.{ FideId, PlayerName, PlayerTitle, Elo, KFactor }
import chess.{ FideId, PlayerName, PlayerTitle }
import chess.rating.{ Elo, KFactor }
import play.api.libs.ws.StandaloneWSClient
import reactivemongo.api.bson.*
import java.util.zip.ZipInputStream
Expand Down
1 change: 1 addition & 0 deletions modules/game/src/main/Event.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import chess.bitboard.Bitboard
import chess.format.pgn.SanStr
import chess.format.{ BoardFen, Fen }
import chess.variant.Crazyhouse
import chess.rating.IntRatingDiff
import chess.{
Centis,
Check,
Expand Down
1 change: 1 addition & 0 deletions modules/game/src/main/GameRepo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package lila.game
import chess.format.Fen
import chess.format.pgn.SanStr
import chess.{ ByColor, Color, Status }
import chess.rating.IntRatingDiff
import reactivemongo.akkastream.{ AkkaStreamCursor, cursorProducer }
import reactivemongo.api.bson.*
import reactivemongo.api.commands.WriteResult
Expand Down
2 changes: 1 addition & 1 deletion modules/game/src/main/Importer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ val parseImport: (PgnStr, Option[UserId]) => Either[ErrorStr, ImportedGame] = (p
.newImportedGame(
chess = game,
players = ByColor: c =>
lila.game.Player.makeImported(c, parsed.tags.names(c), parsed.tags.elos(c)),
lila.game.Player.makeImported(c, parsed.tags.names(c), parsed.tags.ratings(c)),
mode = Mode.Casual,
source = lila.core.game.Source.Import,
pgnImport = PgnImport.make(user = user, date = parsed.tags.anyDate, pgn = pgn).some
Expand Down
3 changes: 2 additions & 1 deletion modules/game/src/main/LightGame.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package lila.game

import chess.Color
import chess.{ Color, IntRating }
import chess.rating.{ IntRatingDiff, RatingProvisional }

import lila.core.game.LightPlayer

Expand Down
Loading