Make PlackettLuce a class initialized with model
Assisted-by: Claude Opus 4.6 via pi
change trpornqntzkuuwzqzytryqmymyyklqsp
commit 74b625621ddac92e0386af331d1285e51150e10d
author Alpha Chen <alpha@kejadlen.dev>
date
parent vpponslz
diff --git a/lib/open_skill/model.rb b/lib/open_skill/model.rb
index c756628..34809de 100644
--- a/lib/open_skill/model.rb
+++ b/lib/open_skill/model.rb
@@ -19,6 +19,8 @@ module OpenSkill
       @target = target
       @tau = tau
       @limit_sigma = limit_sigma
+
+      @plackett_luce = PlackettLuce.new(self)
     end
 
     def rating
@@ -44,7 +46,7 @@ module OpenSkill
       ordered_teams = ordered.map(&:first)
       sorted_rank = ordered.map(&:last)
 
-      new_ratings = PlackettLuce.rate(ordered_teams, self, rank: sorted_rank)
+      new_ratings = @plackett_luce.rate(ordered_teams, rank: sorted_rank)
 
       result = rank.zip(new_ratings).sort_by(&:first).map(&:last)
 
diff --git a/lib/open_skill/plackett_luce.rb b/lib/open_skill/plackett_luce.rb
index 75ed34f..dba4e44 100644
--- a/lib/open_skill/plackett_luce.rb
+++ b/lib/open_skill/plackett_luce.rb
@@ -3,12 +3,17 @@
 # Port of https://github.com/philihp/openskill.js/blob/main/src/models/plackett-luce.ts
 
 module OpenSkill
-  module PlackettLuce
-    def self.rate(game, model, rank: nil)
+  class PlackettLuce
+    def initialize(model)
+      @beta_sq = model.beta_sq
+      @epsilon = model.epsilon
+    end
+
+    def rate(game, rank: nil)
       return game if game.length <= 1
 
       team_ratings = Util.team_rating(game, rank: rank)
-      c = Util.util_c(team_ratings, model.beta_sq)
+      c = Util.util_c(team_ratings, @beta_sq)
       sum_q = Util.util_sum_q(team_ratings, c)
       a = Util.util_a(team_ratings)
 
@@ -33,7 +38,7 @@ module OpenSkill
         tr.team.map { |player|
           share = player.sigma**2 / tr.sigma_sq
           new_mu = player.mu + share * omega
-          new_sigma = player.sigma * Math.sqrt([1 - share * delta, model.epsilon].max)
+          new_sigma = player.sigma * Math.sqrt([1 - share * delta, @epsilon].max)
           Rating.new(new_mu, new_sigma)
         }
       }
diff --git a/test/test_open_skill.rb b/test/test_open_skill.rb
index 57f6b56..c3744a1 100644
--- a/test/test_open_skill.rb
+++ b/test/test_open_skill.rb
@@ -439,20 +439,20 @@ class TestPlackettLuce < Minitest::Test
 
   def test_solo_game_unchanged
     r = @model.rating
-    result = OpenSkill::PlackettLuce.rate([[r]], @model)
+    result = OpenSkill::PlackettLuce.new(@model).rate([[r]])
     assert_equal [[r]], result
   end
 
   def test_2p_ffa
     r = @model.rating
-    result = OpenSkill::PlackettLuce.rate([[r], [r]], @model)
+    result = OpenSkill::PlackettLuce.new(@model).rate([[r], [r]])
     assert_rating 27.63523138347365, 8.065506316323548, result[0][0]
     assert_rating 22.36476861652635, 8.065506316323548, result[1][0]
   end
 
   def test_3p_ffa
     r = @model.rating
-    result = OpenSkill::PlackettLuce.rate([[r], [r], [r]], @model)
+    result = OpenSkill::PlackettLuce.new(@model).rate([[r], [r], [r]])
     assert_rating 27.868876552746237, 8.204837030780652, result[0][0]
     assert_rating 25.717219138186557, 8.057829747583874, result[1][0]
     assert_rating 21.413904309067206, 8.057829747583874, result[2][0]
@@ -460,7 +460,7 @@ class TestPlackettLuce < Minitest::Test
 
   def test_4p_ffa
     r = @model.rating
-    result = OpenSkill::PlackettLuce.rate([[r], [r], [r], [r]], @model)
+    result = OpenSkill::PlackettLuce.new(@model).rate([[r], [r], [r], [r]])
     assert_rating 27.795084971874736, 8.263160757613477, result[0][0]
     assert_rating 26.552824984374855, 8.179213704945203, result[1][0]
     assert_rating 24.68943500312503, 8.083731307186588, result[2][0]
@@ -469,7 +469,7 @@ class TestPlackettLuce < Minitest::Test
 
   def test_5p_ffa
     r = @model.rating
-    result = OpenSkill::PlackettLuce.rate([[r], [r], [r], [r], [r]], @model)
+    result = OpenSkill::PlackettLuce.new(@model).rate([[r], [r], [r], [r], [r]])
     assert_rating 27.666666666666668, 8.290556877154474, result[0][0]
     assert_rating 26.833333333333332, 8.240145629781066, result[1][0]
     assert_rating 25.72222222222222, 8.179996679645559, result[2][0]
@@ -479,7 +479,7 @@ class TestPlackettLuce < Minitest::Test
 
   def test_3_teams_different_sizes
     r = @model.rating
-    result = OpenSkill::PlackettLuce.rate([[r, r, r], [r], [r, r]], @model)
+    result = OpenSkill::PlackettLuce.new(@model).rate([[r, r, r], [r], [r, r]])
     assert_rating 25.939870821784513, 8.247641552260456, result[0][0]
     assert_rating 25.939870821784513, 8.247641552260456, result[0][1]
     assert_rating 25.939870821784513, 8.247641552260456, result[0][2]