Adjust rating refund logic
Cap refunds to 50 above best rating, and adjust logic when current rating is higher than rating during unfair game. This closes #4073.pull/4076/head
parent
5631c71d26
commit
d2cb085bf6
|
@ -171,7 +171,7 @@ lazy val event = module("event", Seq(common, db, memo, i18n)).settings(
|
|||
)
|
||||
|
||||
lazy val mod = module("mod", Seq(common, db, user, hub, security, tournament, simul, game, analyse, evaluation,
|
||||
report, notifyModule, history)).settings(
|
||||
report, notifyModule, history, perfStat)).settings(
|
||||
libraryDependencies ++= provided(play.api, play.test, reactivemongo.driver)
|
||||
)
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@ final class PimpedLong(private val self: Long) extends AnyVal {
|
|||
|
||||
def atMost(topValue: Long): Long = min(self, topValue)
|
||||
|
||||
def squeeze(bottom: Long, top: Long): Long = max(min(self, top), bottom)
|
||||
|
||||
def truncInt: Int =
|
||||
if (self.toInt == self) self.toInt
|
||||
else if (self > 0) Integer.MAX_VALUE
|
||||
|
@ -42,6 +44,8 @@ final class PimpedInt(private val self: Int) extends AnyVal {
|
|||
def atLeast(bottomValue: Int): Int = max(self, bottomValue)
|
||||
|
||||
def atMost(topValue: Int): Int = min(self, topValue)
|
||||
|
||||
def squeeze(bottom: Int, top: Int): Int = max(min(self, top), bottom)
|
||||
}
|
||||
|
||||
final class PimpedFloat(private val self: Float) extends AnyVal {
|
||||
|
@ -49,6 +53,8 @@ final class PimpedFloat(private val self: Float) extends AnyVal {
|
|||
def atLeast(bottomValue: Float): Float = max(self, bottomValue)
|
||||
|
||||
def atMost(topValue: Float): Float = min(self, topValue)
|
||||
|
||||
def squeeze(bottom: Float, top: Float): Float = max(min(self, top), bottom)
|
||||
}
|
||||
|
||||
final class PimpedDouble(private val self: Double) extends AnyVal {
|
||||
|
@ -56,4 +62,6 @@ final class PimpedDouble(private val self: Double) extends AnyVal {
|
|||
def atLeast(bottomValue: Double): Double = max(self, bottomValue)
|
||||
|
||||
def atMost(topValue: Double): Double = min(self, topValue)
|
||||
|
||||
def squeeze(bottom: Double, top: Double): Double = max(min(self, top), bottom)
|
||||
}
|
|
@ -10,6 +10,7 @@ final class Env(
|
|||
config: Config,
|
||||
db: lila.db.Env,
|
||||
hub: lila.hub.Env,
|
||||
perfStat: lila.perfStat.Env,
|
||||
system: ActorSystem,
|
||||
scheduler: lila.common.Scheduler,
|
||||
firewall: Firewall,
|
||||
|
@ -54,7 +55,8 @@ final class Env(
|
|||
notifier = notifier,
|
||||
historyApi = historyApi,
|
||||
rankingApi = rankingApi,
|
||||
wasUnengined = logApi.wasUnengined
|
||||
wasUnengined = logApi.wasUnengined,
|
||||
perfStatter = perfStat.get _
|
||||
)
|
||||
|
||||
lazy val publicChat = new PublicChat(chatApi, tournamentApi, simulEnv)
|
||||
|
@ -134,6 +136,7 @@ object Env {
|
|||
config = lila.common.PlayApp loadConfig "mod",
|
||||
db = lila.db.Env.current,
|
||||
hub = lila.hub.Env.current,
|
||||
perfStat = lila.perfStat.Env.current,
|
||||
system = lila.common.PlayApp.system,
|
||||
scheduler = lila.common.PlayApp.scheduler,
|
||||
firewall = lila.security.Env.current.firewall,
|
||||
|
|
|
@ -10,13 +10,15 @@ import lila.game.{ Game, GameRepo, Query }
|
|||
import lila.rating.PerfType
|
||||
import lila.user.{ User, UserRepo }
|
||||
import lila.report.{ Suspect, Victim }
|
||||
import lila.perfStat.PerfStat
|
||||
|
||||
private final class RatingRefund(
|
||||
scheduler: lila.common.Scheduler,
|
||||
notifier: ModNotifier,
|
||||
historyApi: lila.history.HistoryApi,
|
||||
rankingApi: lila.user.RankingApi,
|
||||
wasUnengined: Suspect => Fu[Boolean]
|
||||
wasUnengined: Suspect => Fu[Boolean],
|
||||
perfStatter: (User, PerfType) => Fu[PerfStat]
|
||||
) {
|
||||
|
||||
import RatingRefund._
|
||||
|
@ -47,9 +49,10 @@ private final class RatingRefund(
|
|||
} yield refs.add(victim, perf, -diff, rating)) | refs
|
||||
}
|
||||
|
||||
def pointsToRefund(ref: Refund, user: User): Int = {
|
||||
ref.diff - user.perfs(ref.perf).intRating + 100 + ref.topRating
|
||||
} min ref.diff min 200 max 0
|
||||
def pointsToRefund(ref: Refund, curRating: Int, perfs: PerfStat): Int = {
|
||||
ref.diff - (ref.diff + curRating - ref.topRating atLeast 0) / 2 atMost
|
||||
perfs.highest.fold(100) { _.int - curRating + 50 }
|
||||
} squeeze (0, 150)
|
||||
|
||||
def refundPoints(victim: Victim, pt: PerfType, points: Int): Funit = {
|
||||
val newPerf = victim.user.perfs(pt) refund points
|
||||
|
@ -62,9 +65,17 @@ private final class RatingRefund(
|
|||
def applyRefund(ref: Refund) =
|
||||
UserRepo byId ref.victim flatMap {
|
||||
_ ?? { user =>
|
||||
val points = pointsToRefund(ref, user)
|
||||
logger.info(s"Refunding $ref -> $points")
|
||||
(points > 0) ?? refundPoints(Victim(user), ref.perf, points)
|
||||
perfStatter(user, ref.perf) flatMap { perfs =>
|
||||
val points = pointsToRefund(
|
||||
ref,
|
||||
curRating = user.perfs(ref.perf).intRating,
|
||||
perfs = perfs
|
||||
)
|
||||
(points > 0) ?? {
|
||||
logger.info(s"Refunding $ref -> $points")
|
||||
refundPoints(Victim(user), ref.perf, points)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue