update variant elos on end game

This commit is contained in:
Thibault Duplessis 2013-07-21 18:48:29 +02:00
parent 40113d6103
commit 23dc89d302
3 changed files with 46 additions and 18 deletions

View file

@ -2,7 +2,7 @@ package lila.round
import chess.Color._
import chess.Status._
import chess.{ EloCalculator, Status, Color, Speed }
import chess.{ EloCalculator, Status, Color, Speed, Variant }
import lila.db.api._
import lila.game.tube.gameTube
import lila.game.{ GameRepo, Game, Pov, Event }
@ -62,12 +62,30 @@ private[round] final class Finisher(
val cheaterWin = (whiteDiff > 0 && whiteUser.engine) || (blackDiff > 0 && blackUser.engine)
(!cheaterWin) ?? {
val speed = Speed(game.clock) |> { s (s == Speed.Unlimited).fold(Speed.Slow, s) }
val (whiteSe, blackSe) = (whiteUser.speedElos(speed), blackUser.speedElos(speed))
val (whiteSeElo, blackSeElo) = eloCalculator.calculate(whiteSe, blackSe, game.winnerColor)
val (newWhiteSe, newBlackSe) = (whiteSe.addGame(whiteSeElo), blackSe.addGame(blackSeElo))
val (newWhiteSe, newBlackSe) = {
val (whiteSe, blackSe) = (whiteUser.speedElos(speed), blackUser.speedElos(speed))
val (whiteSeElo, blackSeElo) = eloCalculator.calculate(whiteSe, blackSe, game.winnerColor)
(whiteSe.addGame(whiteSeElo), blackSe.addGame(blackSeElo))
}
val variant = game.variant |> { v (v == Variant.Chess960).fold(Variant.Chess960, Variant.Standard) }
val (newWhiteVe, newBlackVe) = {
val (whiteVe, blackVe) = (whiteUser.variantElos(variant), blackUser.variantElos(variant))
val (whiteVeElo, blackVeElo) = eloCalculator.calculate(whiteVe, blackVe, game.winnerColor)
(whiteVe.addGame(whiteVeElo), blackVe.addGame(blackVeElo))
}
GameRepo.setEloDiffs(game.id, whiteDiff, blackDiff) >>
eloUpdater.game(whiteUser, whiteElo, blackUser.elo, speed.shortName, newWhiteSe) >>
eloUpdater.game(blackUser, blackElo, whiteUser.elo, speed.shortName, newBlackSe)
eloUpdater.game(
whiteUser,
whiteElo,
blackUser.elo,
speed.shortName -> newWhiteSe,
variant.name -> newWhiteVe) >>
eloUpdater.game(
blackUser,
blackElo,
whiteUser.elo,
speed.shortName -> newBlackSe,
variant.name -> newBlackVe)
} inject true.some
}
} yield ()).value.void

View file

@ -2,16 +2,22 @@ package lila.user
final class EloUpdater(floor: Int) {
def game(user: User, elo: Int, opponentElo: Int, speed: String, se: SubElo): Funit = math.max(elo, floor) |> { newElo
UserRepo.setElo(user.id, newElo, speed, se) >>
HistoryRepo.addEntry(user.id, newElo, opponentElo.some)
}
def game(
user: User,
elo: Int,
opponentElo: Int,
speedElo: (String, SubElo),
variantElo: (String, SubElo)): Funit =
math.max(elo, floor) |> { newElo
UserRepo.setElo(user.id, newElo, speedElo, variantElo) >>
HistoryRepo.addEntry(user.id, newElo, opponentElo.some)
}
private def adjustTo = User.STARTING_ELO
def adjust(u: User) = (u.elo > adjustTo) ?? {
UserRepo.setEloOnly(u.id, adjustTo) >>
HistoryRepo.addEntry(u.id, adjustTo, none)
UserRepo.setEloOnly(u.id, adjustTo) >>
HistoryRepo.addEntry(u.id, adjustTo, none)
}
}

View file

@ -41,11 +41,15 @@ object UserRepo {
def rank(user: User) = $count(enabledQuery ++ Json.obj("elo" -> $gt(user.elo))) map (1+)
def setElo(id: ID, elo: Int, speed: String, se: SubElo): Funit = $update($select(id), $set(
"elo" -> elo,
"speedElos.%s.nb".format(speed) -> se.nb,
"speedElos.%s.elo".format(speed) -> se.elo
))
def setElo(id: ID, elo: Int, speedElo: (String, SubElo), variantElo: (String, SubElo)): Funit = (speedElo, variantElo) match {
case ((speed, sElo), (variant, vElo)) $update($select(id), $set(
"elo" -> elo,
"speedElos.%s.nb".format(speed) -> sElo.nb,
"speedElos.%s.elo".format(speed) -> sElo.elo,
"variantElos.%s.nb".format(variant) -> vElo.nb,
"variantElos.%s.elo".format(variant) -> vElo.elo
))
}
def setEloOnly(id: ID, elo: Int): Funit = $update($select(id), $set("elo" -> elo))
@ -203,7 +207,7 @@ object UserRepo {
private def newUser(username: String, password: String) = {
val salt = Random nextString 32
val salt = Random nextString 32
implicit def speedElosTube = SpeedElos.tube
implicit def countTube = Count.tube