halve human rating diff in a match against a bot

pull/4302/head
Thibault Duplessis 2018-04-20 00:00:45 +02:00
parent c95a010cad
commit 0a351973bb
3 changed files with 44 additions and 26 deletions

View File

@ -38,6 +38,12 @@ case class Glicko(
volatility = volatility atMost Glicko.maxVolatility
)
def average(other: Glicko) = Glicko(
rating = (rating + other.rating) / 2,
deviation = (deviation + other.deviation) / 2,
volatility = (volatility + other.volatility) / 2
)
override def toString = s"$intRating $intDeviation"
}

View File

@ -38,6 +38,10 @@ case class Perf(
add(Glicko.default, date)
}
def averageGlicko(other: Perf) = copy(
glicko = glicko average other.glicko
)
def refund(points: Int): Perf = {
val newGlicko = glicko refund points
copy(

View File

@ -57,8 +57,8 @@ final class PerfsUpdater(
}
case _ =>
}
val perfsW = mkPerfs(ratingsW, white.perfs, game)
val perfsB = mkPerfs(ratingsB, black.perfs, game)
val perfsW = mkPerfs(ratingsW, white -> black, game)
val perfsB = mkPerfs(ratingsB, black -> white, game)
def intRatingLens(perfs: Perfs) = mainPerf(perfs).glicko.intRating
val ratingDiffs = Color.Map(
intRatingLens(perfsW) - intRatingLens(white.perfs),
@ -124,33 +124,41 @@ final class PerfsUpdater(
}
try {
system.updateRatings(results)
} catch {
}
catch {
case e: Exception => logger.error("update ratings", e)
}
}
private def mkPerfs(ratings: Ratings, perfs: Perfs, game: Game): Perfs = {
val speed = game.speed
val isStd = game.ratingVariant.standard
def addRatingIf(cond: Boolean, perf: Perf, rating: Rating) =
if (cond) perf.addOrReset(_.round.error.glicko, s"game ${game.id}")(rating, game.movedAt)
else perf
val perfs1 = perfs.copy(
chess960 = addRatingIf(game.ratingVariant.chess960, perfs.chess960, ratings.chess960),
kingOfTheHill = addRatingIf(game.ratingVariant.kingOfTheHill, perfs.kingOfTheHill, ratings.kingOfTheHill),
threeCheck = addRatingIf(game.ratingVariant.threeCheck, perfs.threeCheck, ratings.threeCheck),
antichess = addRatingIf(game.ratingVariant.antichess, perfs.antichess, ratings.antichess),
atomic = addRatingIf(game.ratingVariant.atomic, perfs.atomic, ratings.atomic),
horde = addRatingIf(game.ratingVariant.horde, perfs.horde, ratings.horde),
racingKings = addRatingIf(game.ratingVariant.racingKings, perfs.racingKings, ratings.racingKings),
crazyhouse = addRatingIf(game.ratingVariant.crazyhouse, perfs.crazyhouse, ratings.crazyhouse),
ultraBullet = addRatingIf(isStd && speed == Speed.UltraBullet, perfs.ultraBullet, ratings.ultraBullet),
bullet = addRatingIf(isStd && speed == Speed.Bullet, perfs.bullet, ratings.bullet),
blitz = addRatingIf(isStd && speed == Speed.Blitz, perfs.blitz, ratings.blitz),
rapid = addRatingIf(isStd && speed == Speed.Rapid, perfs.rapid, ratings.rapid),
classical = addRatingIf(isStd && speed == Speed.Classical, perfs.classical, ratings.classical),
correspondence = addRatingIf(isStd && speed == Speed.Correspondence, perfs.correspondence, ratings.correspondence)
)
if (isStd) perfs1.updateStandard else perfs1
private def mkPerfs(ratings: Ratings, users: (User, User), game: Game): Perfs = users match {
case (player, opponent) =>
val perfs = player.perfs
val speed = game.speed
val isStd = game.ratingVariant.standard
val isHumanVsMachine = player.noBot && opponent.isBot
def addRatingIf(cond: Boolean, perf: Perf, rating: Rating) =
if (cond) {
val p = perf.addOrReset(_.round.error.glicko, s"game ${game.id}")(rating, game.movedAt)
if (isHumanVsMachine) perf averageGlicko p // halve rating diffs for human
else p
}
else perf
val perfs1 = perfs.copy(
chess960 = addRatingIf(game.ratingVariant.chess960, perfs.chess960, ratings.chess960),
kingOfTheHill = addRatingIf(game.ratingVariant.kingOfTheHill, perfs.kingOfTheHill, ratings.kingOfTheHill),
threeCheck = addRatingIf(game.ratingVariant.threeCheck, perfs.threeCheck, ratings.threeCheck),
antichess = addRatingIf(game.ratingVariant.antichess, perfs.antichess, ratings.antichess),
atomic = addRatingIf(game.ratingVariant.atomic, perfs.atomic, ratings.atomic),
horde = addRatingIf(game.ratingVariant.horde, perfs.horde, ratings.horde),
racingKings = addRatingIf(game.ratingVariant.racingKings, perfs.racingKings, ratings.racingKings),
crazyhouse = addRatingIf(game.ratingVariant.crazyhouse, perfs.crazyhouse, ratings.crazyhouse),
ultraBullet = addRatingIf(isStd && speed == Speed.UltraBullet, perfs.ultraBullet, ratings.ultraBullet),
bullet = addRatingIf(isStd && speed == Speed.Bullet, perfs.bullet, ratings.bullet),
blitz = addRatingIf(isStd && speed == Speed.Blitz, perfs.blitz, ratings.blitz),
rapid = addRatingIf(isStd && speed == Speed.Rapid, perfs.rapid, ratings.rapid),
classical = addRatingIf(isStd && speed == Speed.Classical, perfs.classical, ratings.classical),
correspondence = addRatingIf(isStd && speed == Speed.Correspondence, perfs.correspondence, ratings.correspondence)
)
if (isStd) perfs1.updateStandard else perfs1
}
}