Skip to content

Commit 725704c

Browse files
authored
Merge pull request #8279 from ddugovic/rating-advantage
Ratings - account for first player advantage #6818
2 parents e09edd4 + 4136df6 commit 725704c

File tree

3 files changed

+41
-12
lines changed

3 files changed

+41
-12
lines changed

modules/rating/src/main/java/glicko2/Rating.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*/
2020
public class Rating {
2121

22+
private final double advantage;
2223
private double rating;
2324
private double ratingDeviation;
2425
private double volatility;
@@ -31,17 +32,35 @@ public class Rating {
3132
private double workingVolatility;
3233

3334
public Rating(double initRating, double initRatingDeviation, double initVolatility, int nbResults) {
34-
this(initRating, initRatingDeviation, initVolatility, nbResults, null);
35+
this(0.0d, initRating, initRatingDeviation, initVolatility, nbResults, null);
3536
}
3637

3738
public Rating(double initRating, double initRatingDeviation, double initVolatility, int nbResults, DateTime lastRatingPeriodEndDate) {
39+
this(0.0d, initRating, initRatingDeviation, initVolatility, nbResults, lastRatingPeriodEndDate);
40+
}
41+
42+
public Rating(double advantage, double initRating, double initRatingDeviation, double initVolatility, int nbResults, DateTime lastRatingPeriodEndDate) {
43+
this.advantage = advantage;
3844
this.rating = initRating;
3945
this.ratingDeviation = initRatingDeviation;
4046
this.volatility = initVolatility;
4147
this.numberOfResults = nbResults;
4248
this.lastRatingPeriodEndDate = lastRatingPeriodEndDate;
4349
}
4450

51+
public Rating withAdvantage(double advantage) {
52+
return new Rating(advantage, rating, ratingDeviation, volatility, numberOfResults, lastRatingPeriodEndDate);
53+
}
54+
55+
/**
56+
* Return the skill advantage (first-player handicap) value.
57+
*
58+
* @return double
59+
*/
60+
public double getAdvantage() {
61+
return this.advantage;
62+
}
63+
4564
/**
4665
* Return the average skill value of the player.
4766
*
@@ -55,6 +74,16 @@ public void setRating(double rating) {
5574
this.rating = rating;
5675
}
5776

77+
/**
78+
* Return the average skill value of the player scaled down
79+
* to the scale used by the algorithm's internal workings.
80+
*
81+
* @return double
82+
*/
83+
public double getGlicko2RatingWithAdvantage() {
84+
return RatingCalculator.convertRatingToGlicko2Scale(this.rating + advantage);
85+
}
86+
5887
/**
5988
* Return the average skill value of the player scaled down
6089
* to the scale used by the algorithm's internal workings.
@@ -70,7 +99,7 @@ public double getGlicko2Rating() {
7099
*
71100
* @param double
72101
*/
73-
public void setGlicko2Rating(double rating) {
102+
private void setGlicko2Rating(double rating) {
74103
this.rating = RatingCalculator.convertRatingToOriginalGlickoScale(rating);
75104
}
76105

modules/rating/src/main/java/glicko2/RatingCalculator.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public class RatingCalculator {
2525
private final static double DEFAULT_TAU = 0.75;
2626
private final static double MULTIPLIER = 173.7178;
2727
private final static double CONVERGENCE_TOLERANCE = 0.000001;
28-
private final static int ITERATION_MAX = 3000;
28+
private final static int ITERATION_MAX = 1000;
2929
private final static double DAYS_PER_MILLI = 1.0 / (1000 * 60 * 60 * 24);
3030

3131
private final double tau; // constrains volatility over time
@@ -254,11 +254,11 @@ private double v(Rating player, List<Result> results) {
254254
for ( Result result: results ) {
255255
v = v + (
256256
( Math.pow( g(result.getOpponent(player).getGlicko2RatingDeviation()), 2) )
257-
* E(player.getGlicko2Rating(),
258-
result.getOpponent(player).getGlicko2Rating(),
257+
* E(player.getGlicko2RatingWithAdvantage(),
258+
result.getOpponent(player).getGlicko2RatingWithAdvantage(),
259259
result.getOpponent(player).getGlicko2RatingDeviation())
260-
* ( 1.0 - E(player.getGlicko2Rating(),
261-
result.getOpponent(player).getGlicko2Rating(),
260+
* ( 1.0 - E(player.getGlicko2RatingWithAdvantage(),
261+
result.getOpponent(player).getGlicko2RatingWithAdvantage(),
262262
result.getOpponent(player).getGlicko2RatingDeviation())
263263
));
264264
}
@@ -293,8 +293,8 @@ private double outcomeBasedRating(Rating player, List<Result> results) {
293293
outcomeBasedRating = outcomeBasedRating
294294
+ ( g(result.getOpponent(player).getGlicko2RatingDeviation())
295295
* ( result.getScore(player) - E(
296-
player.getGlicko2Rating(),
297-
result.getOpponent(player).getGlicko2Rating(),
296+
player.getGlicko2RatingWithAdvantage(),
297+
result.getOpponent(player).getGlicko2RatingWithAdvantage(),
298298
result.getOpponent(player).getGlicko2RatingDeviation() ))
299299
);
300300
}

modules/round/src/main/PerfsUpdater.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,9 @@ final class PerfsUpdater(
124124
private def updateRatings(white: Rating, black: Rating, result: Glicko.Result): Unit = {
125125
val results = new RatingPeriodResults()
126126
result match {
127-
case Glicko.Result.Draw => results.addDraw(white, black)
128-
case Glicko.Result.Win => results.addResult(white, black)
129-
case Glicko.Result.Loss => results.addResult(black, white)
127+
case Glicko.Result.Draw => results.addDraw(white.withAdvantage(5), black.withAdvantage(-5))
128+
case Glicko.Result.Win => results.addResult(white.withAdvantage(5), black.withAdvantage(-5))
129+
case Glicko.Result.Loss => results.addResult(black.withAdvantage(-5), white.withAdvantage(5))
130130
}
131131
try {
132132
Glicko.system.updateRatings(results, true)

0 commit comments

Comments
 (0)