From 3135c1713e9101a71cfec72d78bf080fc1005796 Mon Sep 17 00:00:00 2001 From: Arkadiusz Klonowski Date: Fri, 27 Sep 2024 15:31:26 +0200 Subject: [PATCH 01/12] fix tests for FIDE table --- test-kit/src/test/scala/EloTest.scala | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test-kit/src/test/scala/EloTest.scala b/test-kit/src/test/scala/EloTest.scala index 1a9e3935..03e5db61 100644 --- a/test-kit/src/test/scala/EloTest.scala +++ b/test-kit/src/test/scala/EloTest.scala @@ -15,12 +15,12 @@ class EloTest extends ChessTest: ratingDiff(1500, 40, 1500, One, 20) ratingDiff(1500, 40, 1500, Zero, -20) ratingDiff(1500, 40, 1500, Half, 0) - ratingDiff(1500, 40, 1900, One, 36) - ratingDiff(1500, 40, 1900, Zero, -4) - ratingDiff(1500, 40, 1900, Half, 16) - ratingDiff(1500, 40, 2900, One, 36) - ratingDiff(1500, 40, 2900, Zero, -4) - ratingDiff(1500, 40, 2900, Half, 16) + ratingDiff(1500, 40, 1900, One, 37) + ratingDiff(1500, 40, 1900, Zero, -3) + ratingDiff(1500, 40, 1900, Half, 17) + ratingDiff(1500, 40, 2900, One, 37) + ratingDiff(1500, 40, 2900, Zero, -3) + ratingDiff(1500, 40, 2900, Half, 17) ratingDiff(1500, 40, 1600, One, 26) ratingDiff(1500, 40, 1600, Zero, -14) ratingDiff(1500, 40, 1600, Half, 6) From 28bcee13edd1893f8fc473e49721cc317903129a Mon Sep 17 00:00:00 2001 From: Arkadiusz Klonowski Date: Fri, 27 Sep 2024 15:49:12 +0200 Subject: [PATCH 02/12] implement FIDE table for ranking change calculation --- core/src/main/scala/Elo.scala | 58 +++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/Elo.scala b/core/src/main/scala/Elo.scala index 06de8bb9..d9d4f2c5 100644 --- a/core/src/main/scala/Elo.scala +++ b/core/src/main/scala/Elo.scala @@ -23,11 +23,10 @@ object Elo extends OpaqueInt[Elo]: def playersRatingDiff(a: Elo, b: Elo): Int = Math.min(400, Math.max(-400, b - a)) - // https://en.wikipedia.org/wiki/Elo_rating_system#Mathematical_details def computeNewRating(player: Player, games: Seq[Game]): Elo = val expectedScore = games.foldMap: game => val prd = playersRatingDiff(player.rating, game.opponentRating) - 1 / (1 + Math.pow(10, prd / 400d)) + getExpectedScore(prd) val achievedScore = games.foldMap(_.points.value) val ratingDiff = Math.round(player.kFactor * (achievedScore - expectedScore)).toInt @@ -36,6 +35,14 @@ object Elo extends OpaqueInt[Elo]: def computeRatingDiff(player: Player, games: Seq[Game]): Int = computeNewRating(player, games) - player.rating + def getExpectedScore(ratingDiff: Int): Double = + val absRatingDiff = ratingDiff.abs + val expectedScore = conversionTableFIDE.collectFirst { + case (range, pd) if range.contains(absRatingDiff) => pd + }.get + + if ratingDiff <= 0 then expectedScore else 1.0 - expectedScore + def computePerformanceRating(games: Seq[Game]): Option[Elo] = val winBonus = 400 games.nonEmpty.option: @@ -46,3 +53,50 @@ object Elo extends OpaqueInt[Elo]: case Outcome.Points.Half => 0 case Outcome.Points.One => 1 (ratings + points * winBonus) / games.size + + // 8.2.1 FIDE table + val conversionTableFIDE: List[(Range, Double)] = List( + (0 to 3) -> 0.50, + (4 to 10) -> 0.51, + (11 to 17) -> 0.52, + (18 to 25) -> 0.53, + (26 to 32) -> 0.54, + (33 to 39) -> 0.55, + (40 to 46) -> 0.56, + (47 to 53) -> 0.57, + (54 to 61) -> 0.58, + (62 to 68) -> 0.59, + (69 to 76) -> 0.60, + (77 to 83) -> 0.61, + (84 to 91) -> 0.62, + (92 to 98) -> 0.63, + (99 to 106) -> 0.64, + (107 to 113) -> 0.65, + (114 to 121) -> 0.66, + (122 to 129) -> 0.67, + (130 to 137) -> 0.68, + (138 to 145) -> 0.69, + (146 to 153) -> 0.70, + (154 to 162) -> 0.71, + (163 to 170) -> 0.72, + (171 to 179) -> 0.73, + (180 to 188) -> 0.74, + (189 to 197) -> 0.75, + (198 to 206) -> 0.76, + (207 to 215) -> 0.77, + (216 to 225) -> 0.78, + (226 to 235) -> 0.79, + (236 to 245) -> 0.80, + (246 to 256) -> 0.81, + (257 to 267) -> 0.82, + (268 to 278) -> 0.83, + (279 to 290) -> 0.84, + (291 to 302) -> 0.85, + (303 to 315) -> 0.86, + (316 to 328) -> 0.87, + (329 to 344) -> 0.88, + (345 to 357) -> 0.89, + (358 to 374) -> 0.90, + (375 to 391) -> 0.91, + (392 to Int.MaxValue) -> 0.92 + ) From 2ab70042c695a198cbb1452c1727441d8f57a0f9 Mon Sep 17 00:00:00 2001 From: Arkadiusz Klonowski Date: Fri, 27 Sep 2024 15:50:13 +0200 Subject: [PATCH 03/12] fix FIDE rule number --- core/src/main/scala/Elo.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/Elo.scala b/core/src/main/scala/Elo.scala index d9d4f2c5..29d7b645 100644 --- a/core/src/main/scala/Elo.scala +++ b/core/src/main/scala/Elo.scala @@ -54,7 +54,7 @@ object Elo extends OpaqueInt[Elo]: case Outcome.Points.One => 1 (ratings + points * winBonus) / games.size - // 8.2.1 FIDE table + // 8.1.2 FIDE table val conversionTableFIDE: List[(Range, Double)] = List( (0 to 3) -> 0.50, (4 to 10) -> 0.51, From 605bd715b0b43a7572bdec53dbf2b26ebfe72df4 Mon Sep 17 00:00:00 2001 From: Arkadiusz Klonowski Date: Fri, 27 Sep 2024 18:24:22 +0200 Subject: [PATCH 04/12] add more tests --- test-kit/src/test/scala/EloTest.scala | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test-kit/src/test/scala/EloTest.scala b/test-kit/src/test/scala/EloTest.scala index 03e5db61..b4266e02 100644 --- a/test-kit/src/test/scala/EloTest.scala +++ b/test-kit/src/test/scala/EloTest.scala @@ -24,6 +24,15 @@ class EloTest extends ChessTest: ratingDiff(1500, 40, 1600, One, 26) ratingDiff(1500, 40, 1600, Zero, -14) ratingDiff(1500, 40, 1600, Half, 6) + ratingDiff(2000, 40, 1600, One, 3) + ratingDiff(2000, 40, 1600, Zero, -37) + ratingDiff(2000, 40, 1600, Half, -17) + ratingDiff(2000, 40, 1000, One, 3) + ratingDiff(2000, 40, 1000, Zero, -37) + ratingDiff(2000, 40, 1000, Half, -17) + ratingDiff(2000, 40, 1900, One, 14) + ratingDiff(2000, 40, 1900, Zero, -26) + ratingDiff(2000, 40, 1900, Half, -6) private def perfRating(games: Seq[Elo.Game], expected: Int)(using munit.Location) = assertEquals(Elo.computePerformanceRating(games), Some(Elo(expected))) From 599cda4334fb1fcc71b17a1c8b96f870fd4d35e6 Mon Sep 17 00:00:00 2001 From: Arkadiusz Klonowski Date: Fri, 27 Sep 2024 18:25:07 +0200 Subject: [PATCH 05/12] refactor list to map, use getOrElse --- core/src/main/scala/Elo.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/Elo.scala b/core/src/main/scala/Elo.scala index 29d7b645..20fb1e53 100644 --- a/core/src/main/scala/Elo.scala +++ b/core/src/main/scala/Elo.scala @@ -39,7 +39,9 @@ object Elo extends OpaqueInt[Elo]: val absRatingDiff = ratingDiff.abs val expectedScore = conversionTableFIDE.collectFirst { case (range, pd) if range.contains(absRatingDiff) => pd - }.get + }.getOrElse { + throw new IllegalArgumentException(s"Invalid rating difference: $ratingDiff") + } if ratingDiff <= 0 then expectedScore else 1.0 - expectedScore @@ -55,7 +57,7 @@ object Elo extends OpaqueInt[Elo]: (ratings + points * winBonus) / games.size // 8.1.2 FIDE table - val conversionTableFIDE: List[(Range, Double)] = List( + val conversionTableFIDE: Map[Range.Inclusive, Double] = Map( (0 to 3) -> 0.50, (4 to 10) -> 0.51, (11 to 17) -> 0.52, From 0e7ce08d18abeda5ab0d8400dc03bf069f969e71 Mon Sep 17 00:00:00 2001 From: Arkadiusz Klonowski Date: Fri, 27 Sep 2024 18:32:00 +0200 Subject: [PATCH 06/12] fix formatting --- core/src/main/scala/Elo.scala | 84 +++++++++++++++++------------------ 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/core/src/main/scala/Elo.scala b/core/src/main/scala/Elo.scala index 20fb1e53..be610633 100644 --- a/core/src/main/scala/Elo.scala +++ b/core/src/main/scala/Elo.scala @@ -58,47 +58,47 @@ object Elo extends OpaqueInt[Elo]: // 8.1.2 FIDE table val conversionTableFIDE: Map[Range.Inclusive, Double] = Map( - (0 to 3) -> 0.50, - (4 to 10) -> 0.51, - (11 to 17) -> 0.52, - (18 to 25) -> 0.53, - (26 to 32) -> 0.54, - (33 to 39) -> 0.55, - (40 to 46) -> 0.56, - (47 to 53) -> 0.57, - (54 to 61) -> 0.58, - (62 to 68) -> 0.59, - (69 to 76) -> 0.60, - (77 to 83) -> 0.61, - (84 to 91) -> 0.62, - (92 to 98) -> 0.63, - (99 to 106) -> 0.64, - (107 to 113) -> 0.65, - (114 to 121) -> 0.66, - (122 to 129) -> 0.67, - (130 to 137) -> 0.68, - (138 to 145) -> 0.69, - (146 to 153) -> 0.70, - (154 to 162) -> 0.71, - (163 to 170) -> 0.72, - (171 to 179) -> 0.73, - (180 to 188) -> 0.74, - (189 to 197) -> 0.75, - (198 to 206) -> 0.76, - (207 to 215) -> 0.77, - (216 to 225) -> 0.78, - (226 to 235) -> 0.79, - (236 to 245) -> 0.80, - (246 to 256) -> 0.81, - (257 to 267) -> 0.82, - (268 to 278) -> 0.83, - (279 to 290) -> 0.84, - (291 to 302) -> 0.85, - (303 to 315) -> 0.86, - (316 to 328) -> 0.87, - (329 to 344) -> 0.88, - (345 to 357) -> 0.89, - (358 to 374) -> 0.90, - (375 to 391) -> 0.91, + (0 to 3) -> 0.50, + (4 to 10) -> 0.51, + (11 to 17) -> 0.52, + (18 to 25) -> 0.53, + (26 to 32) -> 0.54, + (33 to 39) -> 0.55, + (40 to 46) -> 0.56, + (47 to 53) -> 0.57, + (54 to 61) -> 0.58, + (62 to 68) -> 0.59, + (69 to 76) -> 0.60, + (77 to 83) -> 0.61, + (84 to 91) -> 0.62, + (92 to 98) -> 0.63, + (99 to 106) -> 0.64, + (107 to 113) -> 0.65, + (114 to 121) -> 0.66, + (122 to 129) -> 0.67, + (130 to 137) -> 0.68, + (138 to 145) -> 0.69, + (146 to 153) -> 0.70, + (154 to 162) -> 0.71, + (163 to 170) -> 0.72, + (171 to 179) -> 0.73, + (180 to 188) -> 0.74, + (189 to 197) -> 0.75, + (198 to 206) -> 0.76, + (207 to 215) -> 0.77, + (216 to 225) -> 0.78, + (226 to 235) -> 0.79, + (236 to 245) -> 0.80, + (246 to 256) -> 0.81, + (257 to 267) -> 0.82, + (268 to 278) -> 0.83, + (279 to 290) -> 0.84, + (291 to 302) -> 0.85, + (303 to 315) -> 0.86, + (316 to 328) -> 0.87, + (329 to 344) -> 0.88, + (345 to 357) -> 0.89, + (358 to 374) -> 0.90, + (375 to 391) -> 0.91, (392 to Int.MaxValue) -> 0.92 ) From e9d25b7dbcb3edffd776513955c66d504ef3ee1f Mon Sep 17 00:00:00 2001 From: Arkadiusz Klonowski Date: Fri, 27 Sep 2024 18:46:29 +0200 Subject: [PATCH 07/12] fix formatting --- core/src/main/scala/Elo.scala | 106 +++++++++++++++++----------------- 1 file changed, 54 insertions(+), 52 deletions(-) diff --git a/core/src/main/scala/Elo.scala b/core/src/main/scala/Elo.scala index be610633..73526f82 100644 --- a/core/src/main/scala/Elo.scala +++ b/core/src/main/scala/Elo.scala @@ -37,11 +37,13 @@ object Elo extends OpaqueInt[Elo]: def getExpectedScore(ratingDiff: Int): Double = val absRatingDiff = ratingDiff.abs - val expectedScore = conversionTableFIDE.collectFirst { - case (range, pd) if range.contains(absRatingDiff) => pd - }.getOrElse { - throw new IllegalArgumentException(s"Invalid rating difference: $ratingDiff") - } + val expectedScore = conversionTableFIDE + .collectFirst { + case (range, pd) if range.contains(absRatingDiff) => pd + } + .getOrElse { + throw new IllegalArgumentException(s"Invalid rating difference: $ratingDiff") + } if ratingDiff <= 0 then expectedScore else 1.0 - expectedScore @@ -53,52 +55,52 @@ object Elo extends OpaqueInt[Elo]: _.points.match case Outcome.Points.Zero => -1 case Outcome.Points.Half => 0 - case Outcome.Points.One => 1 + case Outcome.Points.One => 1 (ratings + points * winBonus) / games.size - // 8.1.2 FIDE table - val conversionTableFIDE: Map[Range.Inclusive, Double] = Map( - (0 to 3) -> 0.50, - (4 to 10) -> 0.51, - (11 to 17) -> 0.52, - (18 to 25) -> 0.53, - (26 to 32) -> 0.54, - (33 to 39) -> 0.55, - (40 to 46) -> 0.56, - (47 to 53) -> 0.57, - (54 to 61) -> 0.58, - (62 to 68) -> 0.59, - (69 to 76) -> 0.60, - (77 to 83) -> 0.61, - (84 to 91) -> 0.62, - (92 to 98) -> 0.63, - (99 to 106) -> 0.64, - (107 to 113) -> 0.65, - (114 to 121) -> 0.66, - (122 to 129) -> 0.67, - (130 to 137) -> 0.68, - (138 to 145) -> 0.69, - (146 to 153) -> 0.70, - (154 to 162) -> 0.71, - (163 to 170) -> 0.72, - (171 to 179) -> 0.73, - (180 to 188) -> 0.74, - (189 to 197) -> 0.75, - (198 to 206) -> 0.76, - (207 to 215) -> 0.77, - (216 to 225) -> 0.78, - (226 to 235) -> 0.79, - (236 to 245) -> 0.80, - (246 to 256) -> 0.81, - (257 to 267) -> 0.82, - (268 to 278) -> 0.83, - (279 to 290) -> 0.84, - (291 to 302) -> 0.85, - (303 to 315) -> 0.86, - (316 to 328) -> 0.87, - (329 to 344) -> 0.88, - (345 to 357) -> 0.89, - (358 to 374) -> 0.90, - (375 to 391) -> 0.91, - (392 to Int.MaxValue) -> 0.92 - ) +// 8.1.2 FIDE table +val conversionTableFIDE: Map[Range.Inclusive, Double] = Map( + (0 to 3) -> 0.50, + (4 to 10) -> 0.51, + (11 to 17) -> 0.52, + (18 to 25) -> 0.53, + (26 to 32) -> 0.54, + (33 to 39) -> 0.55, + (40 to 46) -> 0.56, + (47 to 53) -> 0.57, + (54 to 61) -> 0.58, + (62 to 68) -> 0.59, + (69 to 76) -> 0.60, + (77 to 83) -> 0.61, + (84 to 91) -> 0.62, + (92 to 98) -> 0.63, + (99 to 106) -> 0.64, + (107 to 113) -> 0.65, + (114 to 121) -> 0.66, + (122 to 129) -> 0.67, + (130 to 137) -> 0.68, + (138 to 145) -> 0.69, + (146 to 153) -> 0.70, + (154 to 162) -> 0.71, + (163 to 170) -> 0.72, + (171 to 179) -> 0.73, + (180 to 188) -> 0.74, + (189 to 197) -> 0.75, + (198 to 206) -> 0.76, + (207 to 215) -> 0.77, + (216 to 225) -> 0.78, + (226 to 235) -> 0.79, + (236 to 245) -> 0.80, + (246 to 256) -> 0.81, + (257 to 267) -> 0.82, + (268 to 278) -> 0.83, + (279 to 290) -> 0.84, + (291 to 302) -> 0.85, + (303 to 315) -> 0.86, + (316 to 328) -> 0.87, + (329 to 344) -> 0.88, + (345 to 357) -> 0.89, + (358 to 374) -> 0.90, + (375 to 391) -> 0.91, + (392 to Int.MaxValue) -> 0.92 +) \ No newline at end of file From c41936af5d2c18ac3d3eb3bc8b729a91fe2393b0 Mon Sep 17 00:00:00 2001 From: Arkadiusz Klonowski Date: Fri, 27 Sep 2024 18:53:01 +0200 Subject: [PATCH 08/12] fix formatting --- core/src/main/scala/Elo.scala | 109 +++++++++++++++++----------------- 1 file changed, 55 insertions(+), 54 deletions(-) diff --git a/core/src/main/scala/Elo.scala b/core/src/main/scala/Elo.scala index 73526f82..c5f5567c 100644 --- a/core/src/main/scala/Elo.scala +++ b/core/src/main/scala/Elo.scala @@ -14,14 +14,8 @@ object KFactor extends OpaqueInt[KFactor]: * */ object Elo extends OpaqueInt[Elo]: - final class Player(val rating: Elo, val kFactor: KFactor) - final class Game(val points: Outcome.Points, val opponentRating: Elo) - - /* 8.3.1 - * For each game played against a rated player, determine the difference in rating between the player and their opponent. - * A difference in rating of more than 400 points shall be counted for rating purposes as though it were a difference of 400 points. In any tournament, a player may benefit from only one upgrade under this rule, for the game in which the rating difference is greatest. */ - def playersRatingDiff(a: Elo, b: Elo): Int = - Math.min(400, Math.max(-400, b - a)) + def computeRatingDiff(player: Player, games: Seq[Game]): Int = + computeNewRating(player, games) - player.rating def computeNewRating(player: Player, games: Seq[Game]): Elo = val expectedScore = games.foldMap: game => @@ -32,8 +26,11 @@ object Elo extends OpaqueInt[Elo]: Math.round(player.kFactor * (achievedScore - expectedScore)).toInt player.rating + ratingDiff - def computeRatingDiff(player: Player, games: Seq[Game]): Int = - computeNewRating(player, games) - player.rating + /* 8.3.1 + * For each game played against a rated player, determine the difference in rating between the player and their opponent. + * A difference in rating of more than 400 points shall be counted for rating purposes as though it were a difference of 400 points. In any tournament, a player may benefit from only one upgrade under this rule, for the game in which the rating difference is greatest. */ + def playersRatingDiff(a: Elo, b: Elo): Int = + Math.min(400, Math.max(-400, b - a)) def getExpectedScore(ratingDiff: Int): Double = val absRatingDiff = ratingDiff.abs @@ -55,52 +52,56 @@ object Elo extends OpaqueInt[Elo]: _.points.match case Outcome.Points.Zero => -1 case Outcome.Points.Half => 0 - case Outcome.Points.One => 1 + case Outcome.Points.One => 1 (ratings + points * winBonus) / games.size + final class Player(val rating: Elo, val kFactor: KFactor) + + final class Game(val points: Outcome.Points, val opponentRating: Elo) + // 8.1.2 FIDE table val conversionTableFIDE: Map[Range.Inclusive, Double] = Map( - (0 to 3) -> 0.50, - (4 to 10) -> 0.51, - (11 to 17) -> 0.52, - (18 to 25) -> 0.53, - (26 to 32) -> 0.54, - (33 to 39) -> 0.55, - (40 to 46) -> 0.56, - (47 to 53) -> 0.57, - (54 to 61) -> 0.58, - (62 to 68) -> 0.59, - (69 to 76) -> 0.60, - (77 to 83) -> 0.61, - (84 to 91) -> 0.62, - (92 to 98) -> 0.63, - (99 to 106) -> 0.64, - (107 to 113) -> 0.65, - (114 to 121) -> 0.66, - (122 to 129) -> 0.67, - (130 to 137) -> 0.68, - (138 to 145) -> 0.69, - (146 to 153) -> 0.70, - (154 to 162) -> 0.71, - (163 to 170) -> 0.72, - (171 to 179) -> 0.73, - (180 to 188) -> 0.74, - (189 to 197) -> 0.75, - (198 to 206) -> 0.76, - (207 to 215) -> 0.77, - (216 to 225) -> 0.78, - (226 to 235) -> 0.79, - (236 to 245) -> 0.80, - (246 to 256) -> 0.81, - (257 to 267) -> 0.82, - (268 to 278) -> 0.83, - (279 to 290) -> 0.84, - (291 to 302) -> 0.85, - (303 to 315) -> 0.86, - (316 to 328) -> 0.87, - (329 to 344) -> 0.88, - (345 to 357) -> 0.89, - (358 to 374) -> 0.90, - (375 to 391) -> 0.91, + (0 to 3) -> 0.50, + (4 to 10) -> 0.51, + (11 to 17) -> 0.52, + (18 to 25) -> 0.53, + (26 to 32) -> 0.54, + (33 to 39) -> 0.55, + (40 to 46) -> 0.56, + (47 to 53) -> 0.57, + (54 to 61) -> 0.58, + (62 to 68) -> 0.59, + (69 to 76) -> 0.60, + (77 to 83) -> 0.61, + (84 to 91) -> 0.62, + (92 to 98) -> 0.63, + (99 to 106) -> 0.64, + (107 to 113) -> 0.65, + (114 to 121) -> 0.66, + (122 to 129) -> 0.67, + (130 to 137) -> 0.68, + (138 to 145) -> 0.69, + (146 to 153) -> 0.70, + (154 to 162) -> 0.71, + (163 to 170) -> 0.72, + (171 to 179) -> 0.73, + (180 to 188) -> 0.74, + (189 to 197) -> 0.75, + (198 to 206) -> 0.76, + (207 to 215) -> 0.77, + (216 to 225) -> 0.78, + (226 to 235) -> 0.79, + (236 to 245) -> 0.80, + (246 to 256) -> 0.81, + (257 to 267) -> 0.82, + (268 to 278) -> 0.83, + (279 to 290) -> 0.84, + (291 to 302) -> 0.85, + (303 to 315) -> 0.86, + (316 to 328) -> 0.87, + (329 to 344) -> 0.88, + (345 to 357) -> 0.89, + (358 to 374) -> 0.90, + (375 to 391) -> 0.91, (392 to Int.MaxValue) -> 0.92 -) \ No newline at end of file +) From a0bbf647eec29f271b444026382b57713642de21 Mon Sep 17 00:00:00 2001 From: Arkadiusz Klonowski Date: Fri, 27 Sep 2024 22:30:01 +0200 Subject: [PATCH 09/12] add tests, migrate table to BigDecimal --- core/src/main/scala/Elo.scala | 6 +++--- test-kit/src/test/scala/EloTest.scala | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/core/src/main/scala/Elo.scala b/core/src/main/scala/Elo.scala index c5f5567c..c82037df 100644 --- a/core/src/main/scala/Elo.scala +++ b/core/src/main/scala/Elo.scala @@ -23,7 +23,7 @@ object Elo extends OpaqueInt[Elo]: getExpectedScore(prd) val achievedScore = games.foldMap(_.points.value) val ratingDiff = - Math.round(player.kFactor * (achievedScore - expectedScore)).toInt + Math.round(player.kFactor * (achievedScore - expectedScore.doubleValue)).toInt player.rating + ratingDiff /* 8.3.1 @@ -32,7 +32,7 @@ object Elo extends OpaqueInt[Elo]: def playersRatingDiff(a: Elo, b: Elo): Int = Math.min(400, Math.max(-400, b - a)) - def getExpectedScore(ratingDiff: Int): Double = + def getExpectedScore(ratingDiff: Int): BigDecimal = val absRatingDiff = ratingDiff.abs val expectedScore = conversionTableFIDE .collectFirst { @@ -60,7 +60,7 @@ object Elo extends OpaqueInt[Elo]: final class Game(val points: Outcome.Points, val opponentRating: Elo) // 8.1.2 FIDE table -val conversionTableFIDE: Map[Range.Inclusive, Double] = Map( +val conversionTableFIDE: Map[Range.Inclusive, BigDecimal] = Map( (0 to 3) -> 0.50, (4 to 10) -> 0.51, (11 to 17) -> 0.52, diff --git a/test-kit/src/test/scala/EloTest.scala b/test-kit/src/test/scala/EloTest.scala index b4266e02..53b73948 100644 --- a/test-kit/src/test/scala/EloTest.scala +++ b/test-kit/src/test/scala/EloTest.scala @@ -34,6 +34,20 @@ class EloTest extends ChessTest: ratingDiff(2000, 40, 1900, Zero, -26) ratingDiff(2000, 40, 1900, Half, -6) + private def expectedScore(ratingDiff: Int, expScore: BigDecimal)(using munit.Location) = + assertEquals(Elo.getExpectedScore(ratingDiff), expScore) + + test("expected score"): + expectedScore(0, 0.5) + expectedScore(100, 0.36) + expectedScore(-100, 0.64) + expectedScore(300, 0.15) + expectedScore(-300, 0.85) + expectedScore(400, 0.08) + expectedScore(-400, 0.92) + expectedScore(800, 0.08) + expectedScore(-800, 0.92) + private def perfRating(games: Seq[Elo.Game], expected: Int)(using munit.Location) = assertEquals(Elo.computePerformanceRating(games), Some(Elo(expected))) From 1d52c256d1d443680a088c78871252b350db275a Mon Sep 17 00:00:00 2001 From: Arkadiusz Klonowski Date: Sat, 28 Sep 2024 14:48:57 +0200 Subject: [PATCH 10/12] convert Fide table to Map[Int, Float] --- core/src/main/scala/Elo.scala | 456 ++++++++++++++++++++++---- test-kit/src/test/scala/EloTest.scala | 22 +- 2 files changed, 410 insertions(+), 68 deletions(-) diff --git a/core/src/main/scala/Elo.scala b/core/src/main/scala/Elo.scala index c82037df..939aad8b 100644 --- a/core/src/main/scala/Elo.scala +++ b/core/src/main/scala/Elo.scala @@ -23,7 +23,7 @@ object Elo extends OpaqueInt[Elo]: getExpectedScore(prd) val achievedScore = games.foldMap(_.points.value) val ratingDiff = - Math.round(player.kFactor * (achievedScore - expectedScore.doubleValue)).toInt + Math.round(player.kFactor * (achievedScore - expectedScore)) player.rating + ratingDiff /* 8.3.1 @@ -32,17 +32,10 @@ object Elo extends OpaqueInt[Elo]: def playersRatingDiff(a: Elo, b: Elo): Int = Math.min(400, Math.max(-400, b - a)) - def getExpectedScore(ratingDiff: Int): BigDecimal = + def getExpectedScore(ratingDiff: Int): Float = val absRatingDiff = ratingDiff.abs - val expectedScore = conversionTableFIDE - .collectFirst { - case (range, pd) if range.contains(absRatingDiff) => pd - } - .getOrElse { - throw new IllegalArgumentException(s"Invalid rating difference: $ratingDiff") - } - - if ratingDiff <= 0 then expectedScore else 1.0 - expectedScore + val expectedScore = conversionTableFIDE.getOrElse(absRatingDiff, 0.92f) + if ratingDiff <= 0 then expectedScore else 1.0f - expectedScore def computePerformanceRating(games: Seq[Game]): Option[Elo] = val winBonus = 400 @@ -59,49 +52,398 @@ object Elo extends OpaqueInt[Elo]: final class Game(val points: Outcome.Points, val opponentRating: Elo) -// 8.1.2 FIDE table -val conversionTableFIDE: Map[Range.Inclusive, BigDecimal] = Map( - (0 to 3) -> 0.50, - (4 to 10) -> 0.51, - (11 to 17) -> 0.52, - (18 to 25) -> 0.53, - (26 to 32) -> 0.54, - (33 to 39) -> 0.55, - (40 to 46) -> 0.56, - (47 to 53) -> 0.57, - (54 to 61) -> 0.58, - (62 to 68) -> 0.59, - (69 to 76) -> 0.60, - (77 to 83) -> 0.61, - (84 to 91) -> 0.62, - (92 to 98) -> 0.63, - (99 to 106) -> 0.64, - (107 to 113) -> 0.65, - (114 to 121) -> 0.66, - (122 to 129) -> 0.67, - (130 to 137) -> 0.68, - (138 to 145) -> 0.69, - (146 to 153) -> 0.70, - (154 to 162) -> 0.71, - (163 to 170) -> 0.72, - (171 to 179) -> 0.73, - (180 to 188) -> 0.74, - (189 to 197) -> 0.75, - (198 to 206) -> 0.76, - (207 to 215) -> 0.77, - (216 to 225) -> 0.78, - (226 to 235) -> 0.79, - (236 to 245) -> 0.80, - (246 to 256) -> 0.81, - (257 to 267) -> 0.82, - (268 to 278) -> 0.83, - (279 to 290) -> 0.84, - (291 to 302) -> 0.85, - (303 to 315) -> 0.86, - (316 to 328) -> 0.87, - (329 to 344) -> 0.88, - (345 to 357) -> 0.89, - (358 to 374) -> 0.90, - (375 to 391) -> 0.91, - (392 to Int.MaxValue) -> 0.92 -) + // 8.1.2 FIDE table + val conversionTableFIDE: Map[Int, Float] = Map( + 0 -> 0.50f, + 1 -> 0.50f, + 2 -> 0.50f, + 3 -> 0.50f, + 4 -> 0.51f, + 5 -> 0.51f, + 6 -> 0.51f, + 7 -> 0.51f, + 8 -> 0.51f, + 9 -> 0.51f, + 10 -> 0.51f, + 11 -> 0.52f, + 12 -> 0.52f, + 13 -> 0.52f, + 14 -> 0.52f, + 15 -> 0.52f, + 16 -> 0.52f, + 17 -> 0.52f, + 18 -> 0.53f, + 19 -> 0.53f, + 20 -> 0.53f, + 21 -> 0.53f, + 22 -> 0.53f, + 23 -> 0.53f, + 24 -> 0.53f, + 25 -> 0.53f, + 26 -> 0.54f, + 27 -> 0.54f, + 28 -> 0.54f, + 29 -> 0.54f, + 30 -> 0.54f, + 31 -> 0.54f, + 32 -> 0.54f, + 33 -> 0.55f, + 34 -> 0.55f, + 35 -> 0.55f, + 36 -> 0.55f, + 37 -> 0.55f, + 38 -> 0.55f, + 39 -> 0.55f, + 40 -> 0.56f, + 41 -> 0.56f, + 42 -> 0.56f, + 43 -> 0.56f, + 44 -> 0.56f, + 45 -> 0.56f, + 46 -> 0.56f, + 47 -> 0.57f, + 48 -> 0.57f, + 49 -> 0.57f, + 50 -> 0.57f, + 51 -> 0.57f, + 52 -> 0.57f, + 53 -> 0.57f, + 54 -> 0.58f, + 55 -> 0.58f, + 56 -> 0.58f, + 57 -> 0.58f, + 58 -> 0.58f, + 59 -> 0.58f, + 60 -> 0.58f, + 61 -> 0.58f, + 62 -> 0.59f, + 63 -> 0.59f, + 64 -> 0.59f, + 65 -> 0.59f, + 66 -> 0.59f, + 67 -> 0.59f, + 68 -> 0.59f, + 69 -> 0.60f, + 70 -> 0.60f, + 71 -> 0.60f, + 72 -> 0.60f, + 73 -> 0.60f, + 74 -> 0.60f, + 75 -> 0.60f, + 76 -> 0.60f, + 77 -> 0.61f, + 78 -> 0.61f, + 79 -> 0.61f, + 80 -> 0.61f, + 81 -> 0.61f, + 82 -> 0.61f, + 83 -> 0.61f, + 84 -> 0.62f, + 85 -> 0.62f, + 86 -> 0.62f, + 87 -> 0.62f, + 88 -> 0.62f, + 89 -> 0.62f, + 90 -> 0.62f, + 91 -> 0.62f, + 92 -> 0.63f, + 93 -> 0.63f, + 94 -> 0.63f, + 95 -> 0.63f, + 96 -> 0.63f, + 97 -> 0.63f, + 98 -> 0.63f, + 99 -> 0.64f, + 100 -> 0.64f, + 101 -> 0.64f, + 102 -> 0.64f, + 103 -> 0.64f, + 104 -> 0.64f, + 105 -> 0.64f, + 106 -> 0.64f, + 107 -> 0.65f, + 108 -> 0.65f, + 109 -> 0.65f, + 110 -> 0.65f, + 111 -> 0.65f, + 112 -> 0.65f, + 113 -> 0.65f, + 114 -> 0.66f, + 115 -> 0.66f, + 116 -> 0.66f, + 117 -> 0.66f, + 118 -> 0.66f, + 119 -> 0.66f, + 120 -> 0.66f, + 121 -> 0.66f, + 122 -> 0.67f, + 123 -> 0.67f, + 124 -> 0.67f, + 125 -> 0.67f, + 126 -> 0.67f, + 127 -> 0.67f, + 128 -> 0.67f, + 129 -> 0.67f, + 130 -> 0.68f, + 131 -> 0.68f, + 132 -> 0.68f, + 133 -> 0.68f, + 134 -> 0.68f, + 135 -> 0.68f, + 136 -> 0.68f, + 137 -> 0.68f, + 138 -> 0.69f, + 139 -> 0.69f, + 140 -> 0.69f, + 141 -> 0.69f, + 142 -> 0.69f, + 143 -> 0.69f, + 144 -> 0.69f, + 145 -> 0.69f, + 146 -> 0.70f, + 147 -> 0.70f, + 148 -> 0.70f, + 149 -> 0.70f, + 150 -> 0.70f, + 151 -> 0.70f, + 152 -> 0.70f, + 153 -> 0.70f, + 154 -> 0.71f, + 155 -> 0.71f, + 156 -> 0.71f, + 157 -> 0.71f, + 158 -> 0.71f, + 159 -> 0.71f, + 160 -> 0.71f, + 161 -> 0.71f, + 162 -> 0.71f, + 163 -> 0.72f, + 164 -> 0.72f, + 165 -> 0.72f, + 166 -> 0.72f, + 167 -> 0.72f, + 168 -> 0.72f, + 169 -> 0.72f, + 170 -> 0.72f, + 171 -> 0.73f, + 172 -> 0.73f, + 173 -> 0.73f, + 174 -> 0.73f, + 175 -> 0.73f, + 176 -> 0.73f, + 177 -> 0.73f, + 178 -> 0.73f, + 179 -> 0.73f, + 180 -> 0.74f, + 181 -> 0.74f, + 182 -> 0.74f, + 183 -> 0.74f, + 184 -> 0.74f, + 185 -> 0.74f, + 186 -> 0.74f, + 187 -> 0.74f, + 188 -> 0.74f, + 189 -> 0.75f, + 190 -> 0.75f, + 191 -> 0.75f, + 192 -> 0.75f, + 193 -> 0.75f, + 194 -> 0.75f, + 195 -> 0.75f, + 196 -> 0.75f, + 197 -> 0.75f, + 198 -> 0.76f, + 199 -> 0.76f, + 200 -> 0.76f, + 201 -> 0.76f, + 202 -> 0.76f, + 203 -> 0.76f, + 204 -> 0.76f, + 205 -> 0.76f, + 206 -> 0.76f, + 207 -> 0.77f, + 208 -> 0.77f, + 209 -> 0.77f, + 210 -> 0.77f, + 211 -> 0.77f, + 212 -> 0.77f, + 213 -> 0.77f, + 214 -> 0.77f, + 215 -> 0.77f, + 216 -> 0.78f, + 217 -> 0.78f, + 218 -> 0.78f, + 219 -> 0.78f, + 220 -> 0.78f, + 221 -> 0.78f, + 222 -> 0.78f, + 223 -> 0.78f, + 224 -> 0.78f, + 225 -> 0.78f, + 226 -> 0.79f, + 227 -> 0.79f, + 228 -> 0.79f, + 229 -> 0.79f, + 230 -> 0.79f, + 231 -> 0.79f, + 232 -> 0.79f, + 233 -> 0.79f, + 234 -> 0.79f, + 235 -> 0.79f, + 236 -> 0.80f, + 237 -> 0.80f, + 238 -> 0.80f, + 239 -> 0.80f, + 240 -> 0.80f, + 241 -> 0.80f, + 242 -> 0.80f, + 243 -> 0.80f, + 244 -> 0.80f, + 245 -> 0.80f, + 246 -> 0.81f, + 247 -> 0.81f, + 248 -> 0.81f, + 249 -> 0.81f, + 250 -> 0.81f, + 251 -> 0.81f, + 252 -> 0.81f, + 253 -> 0.81f, + 254 -> 0.81f, + 255 -> 0.81f, + 256 -> 0.81f, + 257 -> 0.82f, + 258 -> 0.82f, + 259 -> 0.82f, + 260 -> 0.82f, + 261 -> 0.82f, + 262 -> 0.82f, + 263 -> 0.82f, + 264 -> 0.82f, + 265 -> 0.82f, + 266 -> 0.82f, + 267 -> 0.82f, + 268 -> 0.83f, + 269 -> 0.83f, + 270 -> 0.83f, + 271 -> 0.83f, + 272 -> 0.83f, + 273 -> 0.83f, + 274 -> 0.83f, + 275 -> 0.83f, + 276 -> 0.83f, + 277 -> 0.83f, + 278 -> 0.83f, + 279 -> 0.84f, + 280 -> 0.84f, + 281 -> 0.84f, + 282 -> 0.84f, + 283 -> 0.84f, + 284 -> 0.84f, + 285 -> 0.84f, + 286 -> 0.84f, + 287 -> 0.84f, + 288 -> 0.84f, + 289 -> 0.84f, + 290 -> 0.84f, + 291 -> 0.85f, + 292 -> 0.85f, + 293 -> 0.85f, + 294 -> 0.85f, + 295 -> 0.85f, + 296 -> 0.85f, + 297 -> 0.85f, + 298 -> 0.85f, + 299 -> 0.85f, + 300 -> 0.85f, + 301 -> 0.85f, + 302 -> 0.85f, + 303 -> 0.86f, + 304 -> 0.86f, + 305 -> 0.86f, + 306 -> 0.86f, + 307 -> 0.86f, + 308 -> 0.86f, + 309 -> 0.86f, + 310 -> 0.86f, + 311 -> 0.86f, + 312 -> 0.86f, + 313 -> 0.86f, + 314 -> 0.86f, + 315 -> 0.86f, + 316 -> 0.87f, + 317 -> 0.87f, + 318 -> 0.87f, + 319 -> 0.87f, + 320 -> 0.87f, + 321 -> 0.87f, + 322 -> 0.87f, + 323 -> 0.87f, + 324 -> 0.87f, + 325 -> 0.87f, + 326 -> 0.87f, + 327 -> 0.87f, + 328 -> 0.87f, + 329 -> 0.88f, + 330 -> 0.88f, + 331 -> 0.88f, + 332 -> 0.88f, + 333 -> 0.88f, + 334 -> 0.88f, + 335 -> 0.88f, + 336 -> 0.88f, + 337 -> 0.88f, + 338 -> 0.88f, + 339 -> 0.88f, + 340 -> 0.88f, + 341 -> 0.88f, + 342 -> 0.88f, + 343 -> 0.88f, + 344 -> 0.88f, + 345 -> 0.89f, + 346 -> 0.89f, + 347 -> 0.89f, + 348 -> 0.89f, + 349 -> 0.89f, + 350 -> 0.89f, + 351 -> 0.89f, + 352 -> 0.89f, + 353 -> 0.89f, + 354 -> 0.89f, + 355 -> 0.89f, + 356 -> 0.89f, + 357 -> 0.89f, + 358 -> 0.90f, + 359 -> 0.90f, + 360 -> 0.90f, + 361 -> 0.90f, + 362 -> 0.90f, + 363 -> 0.90f, + 364 -> 0.90f, + 365 -> 0.90f, + 366 -> 0.90f, + 367 -> 0.90f, + 368 -> 0.90f, + 369 -> 0.90f, + 370 -> 0.90f, + 371 -> 0.90f, + 372 -> 0.90f, + 373 -> 0.90f, + 374 -> 0.90f, + 375 -> 0.91f, + 376 -> 0.91f, + 377 -> 0.91f, + 378 -> 0.91f, + 379 -> 0.91f, + 380 -> 0.91f, + 381 -> 0.91f, + 382 -> 0.91f, + 383 -> 0.91f, + 384 -> 0.91f, + 385 -> 0.91f, + 386 -> 0.91f, + 387 -> 0.91f, + 388 -> 0.91f, + 389 -> 0.91f, + 390 -> 0.91f, + 391 -> 0.91f + ) diff --git a/test-kit/src/test/scala/EloTest.scala b/test-kit/src/test/scala/EloTest.scala index 53b73948..3aa0a78e 100644 --- a/test-kit/src/test/scala/EloTest.scala +++ b/test-kit/src/test/scala/EloTest.scala @@ -34,19 +34,19 @@ class EloTest extends ChessTest: ratingDiff(2000, 40, 1900, Zero, -26) ratingDiff(2000, 40, 1900, Half, -6) - private def expectedScore(ratingDiff: Int, expScore: BigDecimal)(using munit.Location) = - assertEquals(Elo.getExpectedScore(ratingDiff), expScore) + private def expectedScore(ratingDiff: Int, expScore: Float)(using munit.Location) = + assertCloseTo(Elo.getExpectedScore(ratingDiff), expScore, 0.001f) test("expected score"): - expectedScore(0, 0.5) - expectedScore(100, 0.36) - expectedScore(-100, 0.64) - expectedScore(300, 0.15) - expectedScore(-300, 0.85) - expectedScore(400, 0.08) - expectedScore(-400, 0.92) - expectedScore(800, 0.08) - expectedScore(-800, 0.92) + expectedScore(0, 0.5f) + expectedScore(100, 0.36f) + expectedScore(-100, 0.64f) + expectedScore(300, 0.15f) + expectedScore(-300, 0.85f) + expectedScore(400, 0.08f) + expectedScore(-400, 0.92f) + expectedScore(800, 0.08f) + expectedScore(-800, 0.92f) private def perfRating(games: Seq[Elo.Game], expected: Int)(using munit.Location) = assertEquals(Elo.computePerformanceRating(games), Some(Elo(expected))) From e371ef0a6edd48c750d351d9f73f1c83e9fdc8eb Mon Sep 17 00:00:00 2001 From: Arkadiusz Klonowski Date: Sat, 28 Sep 2024 14:58:42 +0200 Subject: [PATCH 11/12] fix formatting --- core/src/main/scala/Elo.scala | 790 +++++++++++++++++----------------- 1 file changed, 395 insertions(+), 395 deletions(-) diff --git a/core/src/main/scala/Elo.scala b/core/src/main/scala/Elo.scala index 939aad8b..14b899bc 100644 --- a/core/src/main/scala/Elo.scala +++ b/core/src/main/scala/Elo.scala @@ -52,398 +52,398 @@ object Elo extends OpaqueInt[Elo]: final class Game(val points: Outcome.Points, val opponentRating: Elo) - // 8.1.2 FIDE table - val conversionTableFIDE: Map[Int, Float] = Map( - 0 -> 0.50f, - 1 -> 0.50f, - 2 -> 0.50f, - 3 -> 0.50f, - 4 -> 0.51f, - 5 -> 0.51f, - 6 -> 0.51f, - 7 -> 0.51f, - 8 -> 0.51f, - 9 -> 0.51f, - 10 -> 0.51f, - 11 -> 0.52f, - 12 -> 0.52f, - 13 -> 0.52f, - 14 -> 0.52f, - 15 -> 0.52f, - 16 -> 0.52f, - 17 -> 0.52f, - 18 -> 0.53f, - 19 -> 0.53f, - 20 -> 0.53f, - 21 -> 0.53f, - 22 -> 0.53f, - 23 -> 0.53f, - 24 -> 0.53f, - 25 -> 0.53f, - 26 -> 0.54f, - 27 -> 0.54f, - 28 -> 0.54f, - 29 -> 0.54f, - 30 -> 0.54f, - 31 -> 0.54f, - 32 -> 0.54f, - 33 -> 0.55f, - 34 -> 0.55f, - 35 -> 0.55f, - 36 -> 0.55f, - 37 -> 0.55f, - 38 -> 0.55f, - 39 -> 0.55f, - 40 -> 0.56f, - 41 -> 0.56f, - 42 -> 0.56f, - 43 -> 0.56f, - 44 -> 0.56f, - 45 -> 0.56f, - 46 -> 0.56f, - 47 -> 0.57f, - 48 -> 0.57f, - 49 -> 0.57f, - 50 -> 0.57f, - 51 -> 0.57f, - 52 -> 0.57f, - 53 -> 0.57f, - 54 -> 0.58f, - 55 -> 0.58f, - 56 -> 0.58f, - 57 -> 0.58f, - 58 -> 0.58f, - 59 -> 0.58f, - 60 -> 0.58f, - 61 -> 0.58f, - 62 -> 0.59f, - 63 -> 0.59f, - 64 -> 0.59f, - 65 -> 0.59f, - 66 -> 0.59f, - 67 -> 0.59f, - 68 -> 0.59f, - 69 -> 0.60f, - 70 -> 0.60f, - 71 -> 0.60f, - 72 -> 0.60f, - 73 -> 0.60f, - 74 -> 0.60f, - 75 -> 0.60f, - 76 -> 0.60f, - 77 -> 0.61f, - 78 -> 0.61f, - 79 -> 0.61f, - 80 -> 0.61f, - 81 -> 0.61f, - 82 -> 0.61f, - 83 -> 0.61f, - 84 -> 0.62f, - 85 -> 0.62f, - 86 -> 0.62f, - 87 -> 0.62f, - 88 -> 0.62f, - 89 -> 0.62f, - 90 -> 0.62f, - 91 -> 0.62f, - 92 -> 0.63f, - 93 -> 0.63f, - 94 -> 0.63f, - 95 -> 0.63f, - 96 -> 0.63f, - 97 -> 0.63f, - 98 -> 0.63f, - 99 -> 0.64f, - 100 -> 0.64f, - 101 -> 0.64f, - 102 -> 0.64f, - 103 -> 0.64f, - 104 -> 0.64f, - 105 -> 0.64f, - 106 -> 0.64f, - 107 -> 0.65f, - 108 -> 0.65f, - 109 -> 0.65f, - 110 -> 0.65f, - 111 -> 0.65f, - 112 -> 0.65f, - 113 -> 0.65f, - 114 -> 0.66f, - 115 -> 0.66f, - 116 -> 0.66f, - 117 -> 0.66f, - 118 -> 0.66f, - 119 -> 0.66f, - 120 -> 0.66f, - 121 -> 0.66f, - 122 -> 0.67f, - 123 -> 0.67f, - 124 -> 0.67f, - 125 -> 0.67f, - 126 -> 0.67f, - 127 -> 0.67f, - 128 -> 0.67f, - 129 -> 0.67f, - 130 -> 0.68f, - 131 -> 0.68f, - 132 -> 0.68f, - 133 -> 0.68f, - 134 -> 0.68f, - 135 -> 0.68f, - 136 -> 0.68f, - 137 -> 0.68f, - 138 -> 0.69f, - 139 -> 0.69f, - 140 -> 0.69f, - 141 -> 0.69f, - 142 -> 0.69f, - 143 -> 0.69f, - 144 -> 0.69f, - 145 -> 0.69f, - 146 -> 0.70f, - 147 -> 0.70f, - 148 -> 0.70f, - 149 -> 0.70f, - 150 -> 0.70f, - 151 -> 0.70f, - 152 -> 0.70f, - 153 -> 0.70f, - 154 -> 0.71f, - 155 -> 0.71f, - 156 -> 0.71f, - 157 -> 0.71f, - 158 -> 0.71f, - 159 -> 0.71f, - 160 -> 0.71f, - 161 -> 0.71f, - 162 -> 0.71f, - 163 -> 0.72f, - 164 -> 0.72f, - 165 -> 0.72f, - 166 -> 0.72f, - 167 -> 0.72f, - 168 -> 0.72f, - 169 -> 0.72f, - 170 -> 0.72f, - 171 -> 0.73f, - 172 -> 0.73f, - 173 -> 0.73f, - 174 -> 0.73f, - 175 -> 0.73f, - 176 -> 0.73f, - 177 -> 0.73f, - 178 -> 0.73f, - 179 -> 0.73f, - 180 -> 0.74f, - 181 -> 0.74f, - 182 -> 0.74f, - 183 -> 0.74f, - 184 -> 0.74f, - 185 -> 0.74f, - 186 -> 0.74f, - 187 -> 0.74f, - 188 -> 0.74f, - 189 -> 0.75f, - 190 -> 0.75f, - 191 -> 0.75f, - 192 -> 0.75f, - 193 -> 0.75f, - 194 -> 0.75f, - 195 -> 0.75f, - 196 -> 0.75f, - 197 -> 0.75f, - 198 -> 0.76f, - 199 -> 0.76f, - 200 -> 0.76f, - 201 -> 0.76f, - 202 -> 0.76f, - 203 -> 0.76f, - 204 -> 0.76f, - 205 -> 0.76f, - 206 -> 0.76f, - 207 -> 0.77f, - 208 -> 0.77f, - 209 -> 0.77f, - 210 -> 0.77f, - 211 -> 0.77f, - 212 -> 0.77f, - 213 -> 0.77f, - 214 -> 0.77f, - 215 -> 0.77f, - 216 -> 0.78f, - 217 -> 0.78f, - 218 -> 0.78f, - 219 -> 0.78f, - 220 -> 0.78f, - 221 -> 0.78f, - 222 -> 0.78f, - 223 -> 0.78f, - 224 -> 0.78f, - 225 -> 0.78f, - 226 -> 0.79f, - 227 -> 0.79f, - 228 -> 0.79f, - 229 -> 0.79f, - 230 -> 0.79f, - 231 -> 0.79f, - 232 -> 0.79f, - 233 -> 0.79f, - 234 -> 0.79f, - 235 -> 0.79f, - 236 -> 0.80f, - 237 -> 0.80f, - 238 -> 0.80f, - 239 -> 0.80f, - 240 -> 0.80f, - 241 -> 0.80f, - 242 -> 0.80f, - 243 -> 0.80f, - 244 -> 0.80f, - 245 -> 0.80f, - 246 -> 0.81f, - 247 -> 0.81f, - 248 -> 0.81f, - 249 -> 0.81f, - 250 -> 0.81f, - 251 -> 0.81f, - 252 -> 0.81f, - 253 -> 0.81f, - 254 -> 0.81f, - 255 -> 0.81f, - 256 -> 0.81f, - 257 -> 0.82f, - 258 -> 0.82f, - 259 -> 0.82f, - 260 -> 0.82f, - 261 -> 0.82f, - 262 -> 0.82f, - 263 -> 0.82f, - 264 -> 0.82f, - 265 -> 0.82f, - 266 -> 0.82f, - 267 -> 0.82f, - 268 -> 0.83f, - 269 -> 0.83f, - 270 -> 0.83f, - 271 -> 0.83f, - 272 -> 0.83f, - 273 -> 0.83f, - 274 -> 0.83f, - 275 -> 0.83f, - 276 -> 0.83f, - 277 -> 0.83f, - 278 -> 0.83f, - 279 -> 0.84f, - 280 -> 0.84f, - 281 -> 0.84f, - 282 -> 0.84f, - 283 -> 0.84f, - 284 -> 0.84f, - 285 -> 0.84f, - 286 -> 0.84f, - 287 -> 0.84f, - 288 -> 0.84f, - 289 -> 0.84f, - 290 -> 0.84f, - 291 -> 0.85f, - 292 -> 0.85f, - 293 -> 0.85f, - 294 -> 0.85f, - 295 -> 0.85f, - 296 -> 0.85f, - 297 -> 0.85f, - 298 -> 0.85f, - 299 -> 0.85f, - 300 -> 0.85f, - 301 -> 0.85f, - 302 -> 0.85f, - 303 -> 0.86f, - 304 -> 0.86f, - 305 -> 0.86f, - 306 -> 0.86f, - 307 -> 0.86f, - 308 -> 0.86f, - 309 -> 0.86f, - 310 -> 0.86f, - 311 -> 0.86f, - 312 -> 0.86f, - 313 -> 0.86f, - 314 -> 0.86f, - 315 -> 0.86f, - 316 -> 0.87f, - 317 -> 0.87f, - 318 -> 0.87f, - 319 -> 0.87f, - 320 -> 0.87f, - 321 -> 0.87f, - 322 -> 0.87f, - 323 -> 0.87f, - 324 -> 0.87f, - 325 -> 0.87f, - 326 -> 0.87f, - 327 -> 0.87f, - 328 -> 0.87f, - 329 -> 0.88f, - 330 -> 0.88f, - 331 -> 0.88f, - 332 -> 0.88f, - 333 -> 0.88f, - 334 -> 0.88f, - 335 -> 0.88f, - 336 -> 0.88f, - 337 -> 0.88f, - 338 -> 0.88f, - 339 -> 0.88f, - 340 -> 0.88f, - 341 -> 0.88f, - 342 -> 0.88f, - 343 -> 0.88f, - 344 -> 0.88f, - 345 -> 0.89f, - 346 -> 0.89f, - 347 -> 0.89f, - 348 -> 0.89f, - 349 -> 0.89f, - 350 -> 0.89f, - 351 -> 0.89f, - 352 -> 0.89f, - 353 -> 0.89f, - 354 -> 0.89f, - 355 -> 0.89f, - 356 -> 0.89f, - 357 -> 0.89f, - 358 -> 0.90f, - 359 -> 0.90f, - 360 -> 0.90f, - 361 -> 0.90f, - 362 -> 0.90f, - 363 -> 0.90f, - 364 -> 0.90f, - 365 -> 0.90f, - 366 -> 0.90f, - 367 -> 0.90f, - 368 -> 0.90f, - 369 -> 0.90f, - 370 -> 0.90f, - 371 -> 0.90f, - 372 -> 0.90f, - 373 -> 0.90f, - 374 -> 0.90f, - 375 -> 0.91f, - 376 -> 0.91f, - 377 -> 0.91f, - 378 -> 0.91f, - 379 -> 0.91f, - 380 -> 0.91f, - 381 -> 0.91f, - 382 -> 0.91f, - 383 -> 0.91f, - 384 -> 0.91f, - 385 -> 0.91f, - 386 -> 0.91f, - 387 -> 0.91f, - 388 -> 0.91f, - 389 -> 0.91f, - 390 -> 0.91f, - 391 -> 0.91f - ) +// 8.1.2 FIDE table +val conversionTableFIDE: Map[Int, Float] = Map( + 0 -> 0.50f, + 1 -> 0.50f, + 2 -> 0.50f, + 3 -> 0.50f, + 4 -> 0.51f, + 5 -> 0.51f, + 6 -> 0.51f, + 7 -> 0.51f, + 8 -> 0.51f, + 9 -> 0.51f, + 10 -> 0.51f, + 11 -> 0.52f, + 12 -> 0.52f, + 13 -> 0.52f, + 14 -> 0.52f, + 15 -> 0.52f, + 16 -> 0.52f, + 17 -> 0.52f, + 18 -> 0.53f, + 19 -> 0.53f, + 20 -> 0.53f, + 21 -> 0.53f, + 22 -> 0.53f, + 23 -> 0.53f, + 24 -> 0.53f, + 25 -> 0.53f, + 26 -> 0.54f, + 27 -> 0.54f, + 28 -> 0.54f, + 29 -> 0.54f, + 30 -> 0.54f, + 31 -> 0.54f, + 32 -> 0.54f, + 33 -> 0.55f, + 34 -> 0.55f, + 35 -> 0.55f, + 36 -> 0.55f, + 37 -> 0.55f, + 38 -> 0.55f, + 39 -> 0.55f, + 40 -> 0.56f, + 41 -> 0.56f, + 42 -> 0.56f, + 43 -> 0.56f, + 44 -> 0.56f, + 45 -> 0.56f, + 46 -> 0.56f, + 47 -> 0.57f, + 48 -> 0.57f, + 49 -> 0.57f, + 50 -> 0.57f, + 51 -> 0.57f, + 52 -> 0.57f, + 53 -> 0.57f, + 54 -> 0.58f, + 55 -> 0.58f, + 56 -> 0.58f, + 57 -> 0.58f, + 58 -> 0.58f, + 59 -> 0.58f, + 60 -> 0.58f, + 61 -> 0.58f, + 62 -> 0.59f, + 63 -> 0.59f, + 64 -> 0.59f, + 65 -> 0.59f, + 66 -> 0.59f, + 67 -> 0.59f, + 68 -> 0.59f, + 69 -> 0.60f, + 70 -> 0.60f, + 71 -> 0.60f, + 72 -> 0.60f, + 73 -> 0.60f, + 74 -> 0.60f, + 75 -> 0.60f, + 76 -> 0.60f, + 77 -> 0.61f, + 78 -> 0.61f, + 79 -> 0.61f, + 80 -> 0.61f, + 81 -> 0.61f, + 82 -> 0.61f, + 83 -> 0.61f, + 84 -> 0.62f, + 85 -> 0.62f, + 86 -> 0.62f, + 87 -> 0.62f, + 88 -> 0.62f, + 89 -> 0.62f, + 90 -> 0.62f, + 91 -> 0.62f, + 92 -> 0.63f, + 93 -> 0.63f, + 94 -> 0.63f, + 95 -> 0.63f, + 96 -> 0.63f, + 97 -> 0.63f, + 98 -> 0.63f, + 99 -> 0.64f, + 100 -> 0.64f, + 101 -> 0.64f, + 102 -> 0.64f, + 103 -> 0.64f, + 104 -> 0.64f, + 105 -> 0.64f, + 106 -> 0.64f, + 107 -> 0.65f, + 108 -> 0.65f, + 109 -> 0.65f, + 110 -> 0.65f, + 111 -> 0.65f, + 112 -> 0.65f, + 113 -> 0.65f, + 114 -> 0.66f, + 115 -> 0.66f, + 116 -> 0.66f, + 117 -> 0.66f, + 118 -> 0.66f, + 119 -> 0.66f, + 120 -> 0.66f, + 121 -> 0.66f, + 122 -> 0.67f, + 123 -> 0.67f, + 124 -> 0.67f, + 125 -> 0.67f, + 126 -> 0.67f, + 127 -> 0.67f, + 128 -> 0.67f, + 129 -> 0.67f, + 130 -> 0.68f, + 131 -> 0.68f, + 132 -> 0.68f, + 133 -> 0.68f, + 134 -> 0.68f, + 135 -> 0.68f, + 136 -> 0.68f, + 137 -> 0.68f, + 138 -> 0.69f, + 139 -> 0.69f, + 140 -> 0.69f, + 141 -> 0.69f, + 142 -> 0.69f, + 143 -> 0.69f, + 144 -> 0.69f, + 145 -> 0.69f, + 146 -> 0.70f, + 147 -> 0.70f, + 148 -> 0.70f, + 149 -> 0.70f, + 150 -> 0.70f, + 151 -> 0.70f, + 152 -> 0.70f, + 153 -> 0.70f, + 154 -> 0.71f, + 155 -> 0.71f, + 156 -> 0.71f, + 157 -> 0.71f, + 158 -> 0.71f, + 159 -> 0.71f, + 160 -> 0.71f, + 161 -> 0.71f, + 162 -> 0.71f, + 163 -> 0.72f, + 164 -> 0.72f, + 165 -> 0.72f, + 166 -> 0.72f, + 167 -> 0.72f, + 168 -> 0.72f, + 169 -> 0.72f, + 170 -> 0.72f, + 171 -> 0.73f, + 172 -> 0.73f, + 173 -> 0.73f, + 174 -> 0.73f, + 175 -> 0.73f, + 176 -> 0.73f, + 177 -> 0.73f, + 178 -> 0.73f, + 179 -> 0.73f, + 180 -> 0.74f, + 181 -> 0.74f, + 182 -> 0.74f, + 183 -> 0.74f, + 184 -> 0.74f, + 185 -> 0.74f, + 186 -> 0.74f, + 187 -> 0.74f, + 188 -> 0.74f, + 189 -> 0.75f, + 190 -> 0.75f, + 191 -> 0.75f, + 192 -> 0.75f, + 193 -> 0.75f, + 194 -> 0.75f, + 195 -> 0.75f, + 196 -> 0.75f, + 197 -> 0.75f, + 198 -> 0.76f, + 199 -> 0.76f, + 200 -> 0.76f, + 201 -> 0.76f, + 202 -> 0.76f, + 203 -> 0.76f, + 204 -> 0.76f, + 205 -> 0.76f, + 206 -> 0.76f, + 207 -> 0.77f, + 208 -> 0.77f, + 209 -> 0.77f, + 210 -> 0.77f, + 211 -> 0.77f, + 212 -> 0.77f, + 213 -> 0.77f, + 214 -> 0.77f, + 215 -> 0.77f, + 216 -> 0.78f, + 217 -> 0.78f, + 218 -> 0.78f, + 219 -> 0.78f, + 220 -> 0.78f, + 221 -> 0.78f, + 222 -> 0.78f, + 223 -> 0.78f, + 224 -> 0.78f, + 225 -> 0.78f, + 226 -> 0.79f, + 227 -> 0.79f, + 228 -> 0.79f, + 229 -> 0.79f, + 230 -> 0.79f, + 231 -> 0.79f, + 232 -> 0.79f, + 233 -> 0.79f, + 234 -> 0.79f, + 235 -> 0.79f, + 236 -> 0.80f, + 237 -> 0.80f, + 238 -> 0.80f, + 239 -> 0.80f, + 240 -> 0.80f, + 241 -> 0.80f, + 242 -> 0.80f, + 243 -> 0.80f, + 244 -> 0.80f, + 245 -> 0.80f, + 246 -> 0.81f, + 247 -> 0.81f, + 248 -> 0.81f, + 249 -> 0.81f, + 250 -> 0.81f, + 251 -> 0.81f, + 252 -> 0.81f, + 253 -> 0.81f, + 254 -> 0.81f, + 255 -> 0.81f, + 256 -> 0.81f, + 257 -> 0.82f, + 258 -> 0.82f, + 259 -> 0.82f, + 260 -> 0.82f, + 261 -> 0.82f, + 262 -> 0.82f, + 263 -> 0.82f, + 264 -> 0.82f, + 265 -> 0.82f, + 266 -> 0.82f, + 267 -> 0.82f, + 268 -> 0.83f, + 269 -> 0.83f, + 270 -> 0.83f, + 271 -> 0.83f, + 272 -> 0.83f, + 273 -> 0.83f, + 274 -> 0.83f, + 275 -> 0.83f, + 276 -> 0.83f, + 277 -> 0.83f, + 278 -> 0.83f, + 279 -> 0.84f, + 280 -> 0.84f, + 281 -> 0.84f, + 282 -> 0.84f, + 283 -> 0.84f, + 284 -> 0.84f, + 285 -> 0.84f, + 286 -> 0.84f, + 287 -> 0.84f, + 288 -> 0.84f, + 289 -> 0.84f, + 290 -> 0.84f, + 291 -> 0.85f, + 292 -> 0.85f, + 293 -> 0.85f, + 294 -> 0.85f, + 295 -> 0.85f, + 296 -> 0.85f, + 297 -> 0.85f, + 298 -> 0.85f, + 299 -> 0.85f, + 300 -> 0.85f, + 301 -> 0.85f, + 302 -> 0.85f, + 303 -> 0.86f, + 304 -> 0.86f, + 305 -> 0.86f, + 306 -> 0.86f, + 307 -> 0.86f, + 308 -> 0.86f, + 309 -> 0.86f, + 310 -> 0.86f, + 311 -> 0.86f, + 312 -> 0.86f, + 313 -> 0.86f, + 314 -> 0.86f, + 315 -> 0.86f, + 316 -> 0.87f, + 317 -> 0.87f, + 318 -> 0.87f, + 319 -> 0.87f, + 320 -> 0.87f, + 321 -> 0.87f, + 322 -> 0.87f, + 323 -> 0.87f, + 324 -> 0.87f, + 325 -> 0.87f, + 326 -> 0.87f, + 327 -> 0.87f, + 328 -> 0.87f, + 329 -> 0.88f, + 330 -> 0.88f, + 331 -> 0.88f, + 332 -> 0.88f, + 333 -> 0.88f, + 334 -> 0.88f, + 335 -> 0.88f, + 336 -> 0.88f, + 337 -> 0.88f, + 338 -> 0.88f, + 339 -> 0.88f, + 340 -> 0.88f, + 341 -> 0.88f, + 342 -> 0.88f, + 343 -> 0.88f, + 344 -> 0.88f, + 345 -> 0.89f, + 346 -> 0.89f, + 347 -> 0.89f, + 348 -> 0.89f, + 349 -> 0.89f, + 350 -> 0.89f, + 351 -> 0.89f, + 352 -> 0.89f, + 353 -> 0.89f, + 354 -> 0.89f, + 355 -> 0.89f, + 356 -> 0.89f, + 357 -> 0.89f, + 358 -> 0.90f, + 359 -> 0.90f, + 360 -> 0.90f, + 361 -> 0.90f, + 362 -> 0.90f, + 363 -> 0.90f, + 364 -> 0.90f, + 365 -> 0.90f, + 366 -> 0.90f, + 367 -> 0.90f, + 368 -> 0.90f, + 369 -> 0.90f, + 370 -> 0.90f, + 371 -> 0.90f, + 372 -> 0.90f, + 373 -> 0.90f, + 374 -> 0.90f, + 375 -> 0.91f, + 376 -> 0.91f, + 377 -> 0.91f, + 378 -> 0.91f, + 379 -> 0.91f, + 380 -> 0.91f, + 381 -> 0.91f, + 382 -> 0.91f, + 383 -> 0.91f, + 384 -> 0.91f, + 385 -> 0.91f, + 386 -> 0.91f, + 387 -> 0.91f, + 388 -> 0.91f, + 389 -> 0.91f, + 390 -> 0.91f, + 391 -> 0.91f +) From 63694c40202f668c4435a6d5903088d25b37a1ed Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Tue, 8 Oct 2024 20:26:56 +0200 Subject: [PATCH 12/12] compute the Fide ELO table --- core/src/main/scala/Elo.scala | 445 ++++------------------------------ 1 file changed, 50 insertions(+), 395 deletions(-) diff --git a/core/src/main/scala/Elo.scala b/core/src/main/scala/Elo.scala index 14b899bc..9ff0f9be 100644 --- a/core/src/main/scala/Elo.scala +++ b/core/src/main/scala/Elo.scala @@ -52,398 +52,53 @@ object Elo extends OpaqueInt[Elo]: final class Game(val points: Outcome.Points, val opponentRating: Elo) -// 8.1.2 FIDE table -val conversionTableFIDE: Map[Int, Float] = Map( - 0 -> 0.50f, - 1 -> 0.50f, - 2 -> 0.50f, - 3 -> 0.50f, - 4 -> 0.51f, - 5 -> 0.51f, - 6 -> 0.51f, - 7 -> 0.51f, - 8 -> 0.51f, - 9 -> 0.51f, - 10 -> 0.51f, - 11 -> 0.52f, - 12 -> 0.52f, - 13 -> 0.52f, - 14 -> 0.52f, - 15 -> 0.52f, - 16 -> 0.52f, - 17 -> 0.52f, - 18 -> 0.53f, - 19 -> 0.53f, - 20 -> 0.53f, - 21 -> 0.53f, - 22 -> 0.53f, - 23 -> 0.53f, - 24 -> 0.53f, - 25 -> 0.53f, - 26 -> 0.54f, - 27 -> 0.54f, - 28 -> 0.54f, - 29 -> 0.54f, - 30 -> 0.54f, - 31 -> 0.54f, - 32 -> 0.54f, - 33 -> 0.55f, - 34 -> 0.55f, - 35 -> 0.55f, - 36 -> 0.55f, - 37 -> 0.55f, - 38 -> 0.55f, - 39 -> 0.55f, - 40 -> 0.56f, - 41 -> 0.56f, - 42 -> 0.56f, - 43 -> 0.56f, - 44 -> 0.56f, - 45 -> 0.56f, - 46 -> 0.56f, - 47 -> 0.57f, - 48 -> 0.57f, - 49 -> 0.57f, - 50 -> 0.57f, - 51 -> 0.57f, - 52 -> 0.57f, - 53 -> 0.57f, - 54 -> 0.58f, - 55 -> 0.58f, - 56 -> 0.58f, - 57 -> 0.58f, - 58 -> 0.58f, - 59 -> 0.58f, - 60 -> 0.58f, - 61 -> 0.58f, - 62 -> 0.59f, - 63 -> 0.59f, - 64 -> 0.59f, - 65 -> 0.59f, - 66 -> 0.59f, - 67 -> 0.59f, - 68 -> 0.59f, - 69 -> 0.60f, - 70 -> 0.60f, - 71 -> 0.60f, - 72 -> 0.60f, - 73 -> 0.60f, - 74 -> 0.60f, - 75 -> 0.60f, - 76 -> 0.60f, - 77 -> 0.61f, - 78 -> 0.61f, - 79 -> 0.61f, - 80 -> 0.61f, - 81 -> 0.61f, - 82 -> 0.61f, - 83 -> 0.61f, - 84 -> 0.62f, - 85 -> 0.62f, - 86 -> 0.62f, - 87 -> 0.62f, - 88 -> 0.62f, - 89 -> 0.62f, - 90 -> 0.62f, - 91 -> 0.62f, - 92 -> 0.63f, - 93 -> 0.63f, - 94 -> 0.63f, - 95 -> 0.63f, - 96 -> 0.63f, - 97 -> 0.63f, - 98 -> 0.63f, - 99 -> 0.64f, - 100 -> 0.64f, - 101 -> 0.64f, - 102 -> 0.64f, - 103 -> 0.64f, - 104 -> 0.64f, - 105 -> 0.64f, - 106 -> 0.64f, - 107 -> 0.65f, - 108 -> 0.65f, - 109 -> 0.65f, - 110 -> 0.65f, - 111 -> 0.65f, - 112 -> 0.65f, - 113 -> 0.65f, - 114 -> 0.66f, - 115 -> 0.66f, - 116 -> 0.66f, - 117 -> 0.66f, - 118 -> 0.66f, - 119 -> 0.66f, - 120 -> 0.66f, - 121 -> 0.66f, - 122 -> 0.67f, - 123 -> 0.67f, - 124 -> 0.67f, - 125 -> 0.67f, - 126 -> 0.67f, - 127 -> 0.67f, - 128 -> 0.67f, - 129 -> 0.67f, - 130 -> 0.68f, - 131 -> 0.68f, - 132 -> 0.68f, - 133 -> 0.68f, - 134 -> 0.68f, - 135 -> 0.68f, - 136 -> 0.68f, - 137 -> 0.68f, - 138 -> 0.69f, - 139 -> 0.69f, - 140 -> 0.69f, - 141 -> 0.69f, - 142 -> 0.69f, - 143 -> 0.69f, - 144 -> 0.69f, - 145 -> 0.69f, - 146 -> 0.70f, - 147 -> 0.70f, - 148 -> 0.70f, - 149 -> 0.70f, - 150 -> 0.70f, - 151 -> 0.70f, - 152 -> 0.70f, - 153 -> 0.70f, - 154 -> 0.71f, - 155 -> 0.71f, - 156 -> 0.71f, - 157 -> 0.71f, - 158 -> 0.71f, - 159 -> 0.71f, - 160 -> 0.71f, - 161 -> 0.71f, - 162 -> 0.71f, - 163 -> 0.72f, - 164 -> 0.72f, - 165 -> 0.72f, - 166 -> 0.72f, - 167 -> 0.72f, - 168 -> 0.72f, - 169 -> 0.72f, - 170 -> 0.72f, - 171 -> 0.73f, - 172 -> 0.73f, - 173 -> 0.73f, - 174 -> 0.73f, - 175 -> 0.73f, - 176 -> 0.73f, - 177 -> 0.73f, - 178 -> 0.73f, - 179 -> 0.73f, - 180 -> 0.74f, - 181 -> 0.74f, - 182 -> 0.74f, - 183 -> 0.74f, - 184 -> 0.74f, - 185 -> 0.74f, - 186 -> 0.74f, - 187 -> 0.74f, - 188 -> 0.74f, - 189 -> 0.75f, - 190 -> 0.75f, - 191 -> 0.75f, - 192 -> 0.75f, - 193 -> 0.75f, - 194 -> 0.75f, - 195 -> 0.75f, - 196 -> 0.75f, - 197 -> 0.75f, - 198 -> 0.76f, - 199 -> 0.76f, - 200 -> 0.76f, - 201 -> 0.76f, - 202 -> 0.76f, - 203 -> 0.76f, - 204 -> 0.76f, - 205 -> 0.76f, - 206 -> 0.76f, - 207 -> 0.77f, - 208 -> 0.77f, - 209 -> 0.77f, - 210 -> 0.77f, - 211 -> 0.77f, - 212 -> 0.77f, - 213 -> 0.77f, - 214 -> 0.77f, - 215 -> 0.77f, - 216 -> 0.78f, - 217 -> 0.78f, - 218 -> 0.78f, - 219 -> 0.78f, - 220 -> 0.78f, - 221 -> 0.78f, - 222 -> 0.78f, - 223 -> 0.78f, - 224 -> 0.78f, - 225 -> 0.78f, - 226 -> 0.79f, - 227 -> 0.79f, - 228 -> 0.79f, - 229 -> 0.79f, - 230 -> 0.79f, - 231 -> 0.79f, - 232 -> 0.79f, - 233 -> 0.79f, - 234 -> 0.79f, - 235 -> 0.79f, - 236 -> 0.80f, - 237 -> 0.80f, - 238 -> 0.80f, - 239 -> 0.80f, - 240 -> 0.80f, - 241 -> 0.80f, - 242 -> 0.80f, - 243 -> 0.80f, - 244 -> 0.80f, - 245 -> 0.80f, - 246 -> 0.81f, - 247 -> 0.81f, - 248 -> 0.81f, - 249 -> 0.81f, - 250 -> 0.81f, - 251 -> 0.81f, - 252 -> 0.81f, - 253 -> 0.81f, - 254 -> 0.81f, - 255 -> 0.81f, - 256 -> 0.81f, - 257 -> 0.82f, - 258 -> 0.82f, - 259 -> 0.82f, - 260 -> 0.82f, - 261 -> 0.82f, - 262 -> 0.82f, - 263 -> 0.82f, - 264 -> 0.82f, - 265 -> 0.82f, - 266 -> 0.82f, - 267 -> 0.82f, - 268 -> 0.83f, - 269 -> 0.83f, - 270 -> 0.83f, - 271 -> 0.83f, - 272 -> 0.83f, - 273 -> 0.83f, - 274 -> 0.83f, - 275 -> 0.83f, - 276 -> 0.83f, - 277 -> 0.83f, - 278 -> 0.83f, - 279 -> 0.84f, - 280 -> 0.84f, - 281 -> 0.84f, - 282 -> 0.84f, - 283 -> 0.84f, - 284 -> 0.84f, - 285 -> 0.84f, - 286 -> 0.84f, - 287 -> 0.84f, - 288 -> 0.84f, - 289 -> 0.84f, - 290 -> 0.84f, - 291 -> 0.85f, - 292 -> 0.85f, - 293 -> 0.85f, - 294 -> 0.85f, - 295 -> 0.85f, - 296 -> 0.85f, - 297 -> 0.85f, - 298 -> 0.85f, - 299 -> 0.85f, - 300 -> 0.85f, - 301 -> 0.85f, - 302 -> 0.85f, - 303 -> 0.86f, - 304 -> 0.86f, - 305 -> 0.86f, - 306 -> 0.86f, - 307 -> 0.86f, - 308 -> 0.86f, - 309 -> 0.86f, - 310 -> 0.86f, - 311 -> 0.86f, - 312 -> 0.86f, - 313 -> 0.86f, - 314 -> 0.86f, - 315 -> 0.86f, - 316 -> 0.87f, - 317 -> 0.87f, - 318 -> 0.87f, - 319 -> 0.87f, - 320 -> 0.87f, - 321 -> 0.87f, - 322 -> 0.87f, - 323 -> 0.87f, - 324 -> 0.87f, - 325 -> 0.87f, - 326 -> 0.87f, - 327 -> 0.87f, - 328 -> 0.87f, - 329 -> 0.88f, - 330 -> 0.88f, - 331 -> 0.88f, - 332 -> 0.88f, - 333 -> 0.88f, - 334 -> 0.88f, - 335 -> 0.88f, - 336 -> 0.88f, - 337 -> 0.88f, - 338 -> 0.88f, - 339 -> 0.88f, - 340 -> 0.88f, - 341 -> 0.88f, - 342 -> 0.88f, - 343 -> 0.88f, - 344 -> 0.88f, - 345 -> 0.89f, - 346 -> 0.89f, - 347 -> 0.89f, - 348 -> 0.89f, - 349 -> 0.89f, - 350 -> 0.89f, - 351 -> 0.89f, - 352 -> 0.89f, - 353 -> 0.89f, - 354 -> 0.89f, - 355 -> 0.89f, - 356 -> 0.89f, - 357 -> 0.89f, - 358 -> 0.90f, - 359 -> 0.90f, - 360 -> 0.90f, - 361 -> 0.90f, - 362 -> 0.90f, - 363 -> 0.90f, - 364 -> 0.90f, - 365 -> 0.90f, - 366 -> 0.90f, - 367 -> 0.90f, - 368 -> 0.90f, - 369 -> 0.90f, - 370 -> 0.90f, - 371 -> 0.90f, - 372 -> 0.90f, - 373 -> 0.90f, - 374 -> 0.90f, - 375 -> 0.91f, - 376 -> 0.91f, - 377 -> 0.91f, - 378 -> 0.91f, - 379 -> 0.91f, - 380 -> 0.91f, - 381 -> 0.91f, - 382 -> 0.91f, - 383 -> 0.91f, - 384 -> 0.91f, - 385 -> 0.91f, - 386 -> 0.91f, - 387 -> 0.91f, - 388 -> 0.91f, - 389 -> 0.91f, - 390 -> 0.91f, - 391 -> 0.91f -) + // 8.1.2 FIDE table + val conversionTableFIDE: Map[Int, Float] = List( + 3 -> 0.50f, + 10 -> 0.51f, + 17 -> 0.52f, + 25 -> 0.53f, + 32 -> 0.54f, + 39 -> 0.55f, + 46 -> 0.56f, + 53 -> 0.57f, + 61 -> 0.58f, + 68 -> 0.59f, + 76 -> 0.60f, + 83 -> 0.61f, + 91 -> 0.62f, + 98 -> 0.63f, + 106 -> 0.64f, + 113 -> 0.65f, + 121 -> 0.66f, + 129 -> 0.67f, + 137 -> 0.68f, + 145 -> 0.69f, + 153 -> 0.70f, + 162 -> 0.71f, + 170 -> 0.72f, + 179 -> 0.73f, + 188 -> 0.74f, + 197 -> 0.75f, + 206 -> 0.76f, + 215 -> 0.77f, + 225 -> 0.78f, + 235 -> 0.79f, + 245 -> 0.80f, + 256 -> 0.81f, + 267 -> 0.82f, + 278 -> 0.83f, + 290 -> 0.84f, + 302 -> 0.85f, + 315 -> 0.86f, + 328 -> 0.87f, + 344 -> 0.88f, + 357 -> 0.89f, + 374 -> 0.90f, + 391 -> 0.91f + ).foldLeft(0 -> Map.empty[Int, Float]): + case ((low, table), (up, value)) => + val newTable = table ++ + (low to up).view.map(_ -> value).toMap + (up + 1) -> newTable + ._2