openskill 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b2559ed1bbd59204cee9143bc49fc51ce1c0048abc5a84b03ba4793d437a4d31
4
- data.tar.gz: 692090c1a809b7645f8acb0bd10be874ec01a32ae2d8d4177d1eacfebfbc041b
3
+ metadata.gz: f012ac1b290e25006cbe383d1ea48aacebc5d4aac2660d5e0388cbeaa91fd16e
4
+ data.tar.gz: b7de5159790ba4e6cd4017437e75706784906e8381211523c377eeaf31d6610d
5
5
  SHA512:
6
- metadata.gz: 1533d76307745a38d728ba4a0a35d093f0270cca0e36b77bc21d276bfa250107f10668260748bebd886fc2177e33001479297839e3890ba158235d2216a8c8d8
7
- data.tar.gz: '09866e5514cac8a47f4534c404871cd8e15a15b8d94e4d00fe9b6c31cc907852c31ed3f2cd4b1320cd38636df49a5968085de62a1c2580171adb27a9853fef63'
6
+ metadata.gz: dd0515dac71798ba088d399f3a888a028106444803a9faaaa7e584aa7e05cdd5363729e923a34207c26c6eae98a736410920007385f578a47cb917781c2ca069
7
+ data.tar.gz: 3710b5bff94f1ae66799e390874580b3d40c7257b2e1465068ac9cb9afaef807ed50ed206eb52a9784359bab23fbb4f0e2086aa3481aa44dc5ce9fdadb4f6f3a
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'securerandom'
4
- require_relative '../statistics/normal'
5
- require_relative 'common'
3
+ require "securerandom"
4
+ require_relative "../statistics/normal"
5
+ require_relative "common"
6
6
 
7
7
  module OpenSkill
8
8
  module Models
@@ -71,8 +71,8 @@ module OpenSkill
71
71
  # @raise [ArgumentError] if rating_array is invalid
72
72
  def load_rating(rating_array, name: nil)
73
73
  raise ArgumentError, "Rating must be an Array, got #{rating_array.class}" unless rating_array.is_a?(Array)
74
- raise ArgumentError, 'Rating array must have exactly 2 elements' unless rating_array.size == 2
75
- raise ArgumentError, 'Rating values must be numeric' unless rating_array.all? { |v| v.is_a?(Numeric) }
74
+ raise ArgumentError, "Rating array must have exactly 2 elements" unless rating_array.size == 2
75
+ raise ArgumentError, "Rating values must be numeric" unless rating_array.all? { |v| v.is_a?(Numeric) }
76
76
 
77
77
  Rating.new(mu: rating_array[0], sigma: rating_array[1], name: name)
78
78
  end
@@ -92,7 +92,7 @@ module OpenSkill
92
92
  validate_scores!(teams, scores) if scores
93
93
  validate_weights!(teams, weights) if weights
94
94
 
95
- raise ArgumentError, 'Cannot provide both ranks and scores' if ranks && scores
95
+ raise ArgumentError, "Cannot provide both ranks and scores" if ranks && scores
96
96
 
97
97
  # Deep copy teams to avoid mutating input
98
98
  original_teams = teams
@@ -299,25 +299,25 @@ module OpenSkill
299
299
  end
300
300
 
301
301
  def <(other)
302
- raise ArgumentError, 'comparison with non-Rating' unless other.is_a?(Rating)
302
+ raise ArgumentError, "comparison with non-Rating" unless other.is_a?(Rating)
303
303
 
304
304
  ordinal < other.ordinal
305
305
  end
306
306
 
307
307
  def >(other)
308
- raise ArgumentError, 'comparison with non-Rating' unless other.is_a?(Rating)
308
+ raise ArgumentError, "comparison with non-Rating" unless other.is_a?(Rating)
309
309
 
310
310
  ordinal > other.ordinal
311
311
  end
312
312
 
313
313
  def <=(other)
314
- raise ArgumentError, 'comparison with non-Rating' unless other.is_a?(Rating)
314
+ raise ArgumentError, "comparison with non-Rating" unless other.is_a?(Rating)
315
315
 
316
316
  ordinal <= other.ordinal
317
317
  end
318
318
 
319
319
  def >=(other)
320
- raise ArgumentError, 'comparison with non-Rating' unless other.is_a?(Rating)
320
+ raise ArgumentError, "comparison with non-Rating" unless other.is_a?(Rating)
321
321
 
322
322
  ordinal >= other.ordinal
323
323
  end
@@ -376,8 +376,8 @@ module OpenSkill
376
376
 
377
377
  # Validate teams structure
378
378
  def validate_teams!(teams)
379
- raise ArgumentError, 'Teams must be an Array' unless teams.is_a?(Array)
380
- raise ArgumentError, 'Must have at least 2 teams' if teams.size < 2
379
+ raise ArgumentError, "Teams must be an Array" unless teams.is_a?(Array)
380
+ raise ArgumentError, "Must have at least 2 teams" if teams.size < 2
381
381
 
382
382
  teams.each_with_index do |team, idx|
383
383
  raise ArgumentError, "Team #{idx} must be an Array" unless team.is_a?(Array)
@@ -392,7 +392,7 @@ module OpenSkill
392
392
  # Validate ranks
393
393
  def validate_ranks!(teams, ranks)
394
394
  raise ArgumentError, "Ranks must be an Array, got #{ranks.class}" unless ranks.is_a?(Array)
395
- raise ArgumentError, 'Ranks must have same length as teams' if ranks.size != teams.size
395
+ raise ArgumentError, "Ranks must have same length as teams" if ranks.size != teams.size
396
396
 
397
397
  ranks.each do |rank|
398
398
  raise ArgumentError, "All ranks must be numeric, got #{rank.class}" unless rank.is_a?(Numeric)
@@ -402,7 +402,7 @@ module OpenSkill
402
402
  # Validate scores
403
403
  def validate_scores!(teams, scores)
404
404
  raise ArgumentError, "Scores must be an Array, got #{scores.class}" unless scores.is_a?(Array)
405
- raise ArgumentError, 'Scores must have same length as teams' if scores.size != teams.size
405
+ raise ArgumentError, "Scores must have same length as teams" if scores.size != teams.size
406
406
 
407
407
  scores.each do |score|
408
408
  raise ArgumentError, "All scores must be numeric, got #{score.class}" unless score.is_a?(Numeric)
@@ -412,7 +412,7 @@ module OpenSkill
412
412
  # Validate weights
413
413
  def validate_weights!(teams, weights)
414
414
  raise ArgumentError, "Weights must be an Array, got #{weights.class}" unless weights.is_a?(Array)
415
- raise ArgumentError, 'Weights must have same length as teams' if weights.size != teams.size
415
+ raise ArgumentError, "Weights must have same length as teams" if weights.size != teams.size
416
416
 
417
417
  weights.each_with_index do |team_weights, idx|
418
418
  raise ArgumentError, "Weights for team #{idx} must be an Array" unless team_weights.is_a?(Array)
@@ -450,11 +450,11 @@ module OpenSkill
450
450
 
451
451
  sorted_team.each do |player|
452
452
  balance_weight = if @balance
453
- ordinal_diff = max_ordinal - player.ordinal
454
- 1 + (ordinal_diff / (max_ordinal + @kappa))
455
- else
456
- 1.0
457
- end
453
+ ordinal_diff = max_ordinal - player.ordinal
454
+ 1 + (ordinal_diff / (max_ordinal + @kappa))
455
+ else
456
+ 1.0
457
+ end
458
458
 
459
459
  mu_sum += player.mu * balance_weight
460
460
  sigma_squared_sum += (player.sigma * balance_weight)**2
@@ -474,10 +474,10 @@ module OpenSkill
474
474
  return [] if game.empty?
475
475
 
476
476
  team_scores = if ranks
477
- ranks.each_with_index.map { |rank, idx| rank || idx }
478
- else
479
- game.each_index.to_a
480
- end
477
+ ranks.each_with_index.map { |rank, idx| rank || idx }
478
+ else
479
+ game.each_index.to_a
480
+ end
481
481
 
482
482
  sorted_scores = team_scores.sort
483
483
  rank_map = {}
@@ -535,12 +535,12 @@ module OpenSkill
535
535
 
536
536
  # Calculate s based on rank comparison
537
537
  s = if team_q.rank > team_i.rank
538
- 1.0 # team_i won
539
- elsif team_q.rank == team_i.rank
540
- 0.5 # draw
541
- else
542
- 0.0 # team_i lost
543
- end
538
+ 1.0 # team_i won
539
+ elsif team_q.rank == team_i.rank
540
+ 0.5 # draw
541
+ else
542
+ 0.0 # team_i lost
543
+ end
544
544
 
545
545
  # Accumulate omega
546
546
  omega += sigma_squared_to_ciq * (s - piq)
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'securerandom'
4
- require_relative '../statistics/normal'
5
- require_relative 'common'
3
+ require "securerandom"
4
+ require_relative "../statistics/normal"
5
+ require_relative "common"
6
6
 
7
7
  module OpenSkill
8
8
  module Models
@@ -74,8 +74,8 @@ module OpenSkill
74
74
  # @raise [ArgumentError] if rating_array is invalid
75
75
  def load_rating(rating_array, name: nil)
76
76
  raise ArgumentError, "Rating must be an Array, got #{rating_array.class}" unless rating_array.is_a?(Array)
77
- raise ArgumentError, 'Rating array must have exactly 2 elements' unless rating_array.size == 2
78
- raise ArgumentError, 'Rating values must be numeric' unless rating_array.all? { |v| v.is_a?(Numeric) }
77
+ raise ArgumentError, "Rating array must have exactly 2 elements" unless rating_array.size == 2
78
+ raise ArgumentError, "Rating values must be numeric" unless rating_array.all? { |v| v.is_a?(Numeric) }
79
79
 
80
80
  Rating.new(mu: rating_array[0], sigma: rating_array[1], name: name)
81
81
  end
@@ -95,7 +95,7 @@ module OpenSkill
95
95
  validate_scores!(teams, scores) if scores
96
96
  validate_weights!(teams, weights) if weights
97
97
 
98
- raise ArgumentError, 'Cannot provide both ranks and scores' if ranks && scores
98
+ raise ArgumentError, "Cannot provide both ranks and scores" if ranks && scores
99
99
 
100
100
  # Deep copy teams to avoid mutating input
101
101
  original_teams = teams
@@ -302,25 +302,25 @@ module OpenSkill
302
302
  end
303
303
 
304
304
  def <(other)
305
- raise ArgumentError, 'comparison with non-Rating' unless other.is_a?(Rating)
305
+ raise ArgumentError, "comparison with non-Rating" unless other.is_a?(Rating)
306
306
 
307
307
  ordinal < other.ordinal
308
308
  end
309
309
 
310
310
  def >(other)
311
- raise ArgumentError, 'comparison with non-Rating' unless other.is_a?(Rating)
311
+ raise ArgumentError, "comparison with non-Rating" unless other.is_a?(Rating)
312
312
 
313
313
  ordinal > other.ordinal
314
314
  end
315
315
 
316
316
  def <=(other)
317
- raise ArgumentError, 'comparison with non-Rating' unless other.is_a?(Rating)
317
+ raise ArgumentError, "comparison with non-Rating" unless other.is_a?(Rating)
318
318
 
319
319
  ordinal <= other.ordinal
320
320
  end
321
321
 
322
322
  def >=(other)
323
- raise ArgumentError, 'comparison with non-Rating' unless other.is_a?(Rating)
323
+ raise ArgumentError, "comparison with non-Rating" unless other.is_a?(Rating)
324
324
 
325
325
  ordinal >= other.ordinal
326
326
  end
@@ -379,8 +379,8 @@ module OpenSkill
379
379
 
380
380
  # Validate teams structure
381
381
  def validate_teams!(teams)
382
- raise ArgumentError, 'Teams must be an Array' unless teams.is_a?(Array)
383
- raise ArgumentError, 'Must have at least 2 teams' if teams.size < 2
382
+ raise ArgumentError, "Teams must be an Array" unless teams.is_a?(Array)
383
+ raise ArgumentError, "Must have at least 2 teams" if teams.size < 2
384
384
 
385
385
  teams.each_with_index do |team, idx|
386
386
  raise ArgumentError, "Team #{idx} must be an Array" unless team.is_a?(Array)
@@ -395,7 +395,7 @@ module OpenSkill
395
395
  # Validate ranks
396
396
  def validate_ranks!(teams, ranks)
397
397
  raise ArgumentError, "Ranks must be an Array, got #{ranks.class}" unless ranks.is_a?(Array)
398
- raise ArgumentError, 'Ranks must have same length as teams' if ranks.size != teams.size
398
+ raise ArgumentError, "Ranks must have same length as teams" if ranks.size != teams.size
399
399
 
400
400
  ranks.each do |rank|
401
401
  raise ArgumentError, "All ranks must be numeric, got #{rank.class}" unless rank.is_a?(Numeric)
@@ -405,7 +405,7 @@ module OpenSkill
405
405
  # Validate scores
406
406
  def validate_scores!(teams, scores)
407
407
  raise ArgumentError, "Scores must be an Array, got #{scores.class}" unless scores.is_a?(Array)
408
- raise ArgumentError, 'Scores must have same length as teams' if scores.size != teams.size
408
+ raise ArgumentError, "Scores must have same length as teams" if scores.size != teams.size
409
409
 
410
410
  scores.each do |score|
411
411
  raise ArgumentError, "All scores must be numeric, got #{score.class}" unless score.is_a?(Numeric)
@@ -415,7 +415,7 @@ module OpenSkill
415
415
  # Validate weights
416
416
  def validate_weights!(teams, weights)
417
417
  raise ArgumentError, "Weights must be an Array, got #{weights.class}" unless weights.is_a?(Array)
418
- raise ArgumentError, 'Weights must have same length as teams' if weights.size != teams.size
418
+ raise ArgumentError, "Weights must have same length as teams" if weights.size != teams.size
419
419
 
420
420
  weights.each_with_index do |team_weights, idx|
421
421
  raise ArgumentError, "Weights for team #{idx} must be an Array" unless team_weights.is_a?(Array)
@@ -453,11 +453,11 @@ module OpenSkill
453
453
 
454
454
  sorted_team.each do |player|
455
455
  balance_weight = if @balance
456
- ordinal_diff = max_ordinal - player.ordinal
457
- 1 + (ordinal_diff / (max_ordinal + @kappa))
458
- else
459
- 1.0
460
- end
456
+ ordinal_diff = max_ordinal - player.ordinal
457
+ 1 + (ordinal_diff / (max_ordinal + @kappa))
458
+ else
459
+ 1.0
460
+ end
461
461
 
462
462
  mu_sum += player.mu * balance_weight
463
463
  sigma_squared_sum += (player.sigma * balance_weight)**2
@@ -477,10 +477,10 @@ module OpenSkill
477
477
  return [] if game.empty?
478
478
 
479
479
  team_scores = if ranks
480
- ranks.each_with_index.map { |rank, idx| rank || idx }
481
- else
482
- game.each_index.to_a
483
- end
480
+ ranks.each_with_index.map { |rank, idx| rank || idx }
481
+ else
482
+ game.each_index.to_a
483
+ end
484
484
 
485
485
  sorted_scores = team_scores.sort
486
486
  rank_map = {}
@@ -536,12 +536,12 @@ module OpenSkill
536
536
 
537
537
  # Calculate s based on rank comparison
538
538
  s = if team_q.rank > team_i.rank
539
- 1.0 # team_i won
540
- elsif team_q.rank == team_i.rank
541
- 0.5 # draw
542
- else
543
- 0.0 # team_i lost
544
- end
539
+ 1.0 # team_i won
540
+ elsif team_q.rank == team_i.rank
541
+ 0.5 # draw
542
+ else
543
+ 0.0 # team_i lost
544
+ end
545
545
 
546
546
  # Accumulate omega and delta
547
547
  omega_sum += (team_i.sigma_squared / c_iq) * (s - piq)
@@ -563,8 +563,8 @@ module OpenSkill
563
563
  end
564
564
 
565
565
  # Average over comparisons
566
- omega = comparisons > 0 ? omega_sum / comparisons : 0.0
567
- delta = comparisons > 0 ? delta_sum / comparisons : 0.0
566
+ omega = (comparisons > 0) ? omega_sum / comparisons : 0.0
567
+ delta = (comparisons > 0) ? delta_sum / comparisons : 0.0
568
568
 
569
569
  # Update each player in the team
570
570
  team_i.team.each_with_index.map do |player, j|
@@ -84,7 +84,7 @@ module OpenSkill
84
84
  denominator = Statistics::Normal.cdf(xt)
85
85
 
86
86
  if denominator < Float::EPSILON
87
- return x < 0 ? 1.0 : 0.0
87
+ return (x < 0) ? 1.0 : 0.0
88
88
  end
89
89
 
90
90
  v_val = v(x, t)
@@ -102,11 +102,11 @@ module OpenSkill
102
102
  b = Statistics::Normal.cdf(t - xx) - Statistics::Normal.cdf(-t - xx)
103
103
 
104
104
  if b < 1e-5
105
- return x < 0 ? (-x - t) : (-x + t)
105
+ return (x < 0) ? (-x - t) : (-x + t)
106
106
  end
107
107
 
108
108
  a = Statistics::Normal.pdf(-t - xx) - Statistics::Normal.pdf(t - xx)
109
- (x < 0 ? -a : a) / b
109
+ ((x < 0) ? -a : a) / b
110
110
  end
111
111
 
112
112
  # The W-tilde function for draws as defined in Weng-Lin 2011
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'securerandom'
4
- require_relative '../statistics/normal'
5
- require_relative 'common'
3
+ require "securerandom"
4
+ require_relative "../statistics/normal"
5
+ require_relative "common"
6
6
 
7
7
  module OpenSkill
8
8
  module Models
@@ -71,8 +71,8 @@ module OpenSkill
71
71
  # @raise [ArgumentError] if rating_array is invalid
72
72
  def load_rating(rating_array, name: nil)
73
73
  raise ArgumentError, "Rating must be an Array, got #{rating_array.class}" unless rating_array.is_a?(Array)
74
- raise ArgumentError, 'Rating array must have exactly 2 elements' unless rating_array.size == 2
75
- raise ArgumentError, 'Rating values must be numeric' unless rating_array.all? { |v| v.is_a?(Numeric) }
74
+ raise ArgumentError, "Rating array must have exactly 2 elements" unless rating_array.size == 2
75
+ raise ArgumentError, "Rating values must be numeric" unless rating_array.all? { |v| v.is_a?(Numeric) }
76
76
 
77
77
  Rating.new(mu: rating_array[0], sigma: rating_array[1], name: name)
78
78
  end
@@ -93,7 +93,7 @@ module OpenSkill
93
93
  validate_weights!(teams, weights) if weights
94
94
 
95
95
  # Can't have both ranks and scores
96
- raise ArgumentError, 'Cannot provide both ranks and scores' if ranks && scores
96
+ raise ArgumentError, "Cannot provide both ranks and scores" if ranks && scores
97
97
 
98
98
  # Deep copy teams to avoid mutating input
99
99
  original_teams = teams
@@ -300,25 +300,25 @@ module OpenSkill
300
300
  end
301
301
 
302
302
  def <(other)
303
- raise ArgumentError, 'comparison with non-Rating' unless other.is_a?(Rating)
303
+ raise ArgumentError, "comparison with non-Rating" unless other.is_a?(Rating)
304
304
 
305
305
  ordinal < other.ordinal
306
306
  end
307
307
 
308
308
  def >(other)
309
- raise ArgumentError, 'comparison with non-Rating' unless other.is_a?(Rating)
309
+ raise ArgumentError, "comparison with non-Rating" unless other.is_a?(Rating)
310
310
 
311
311
  ordinal > other.ordinal
312
312
  end
313
313
 
314
314
  def <=(other)
315
- raise ArgumentError, 'comparison with non-Rating' unless other.is_a?(Rating)
315
+ raise ArgumentError, "comparison with non-Rating" unless other.is_a?(Rating)
316
316
 
317
317
  ordinal <= other.ordinal
318
318
  end
319
319
 
320
320
  def >=(other)
321
- raise ArgumentError, 'comparison with non-Rating' unless other.is_a?(Rating)
321
+ raise ArgumentError, "comparison with non-Rating" unless other.is_a?(Rating)
322
322
 
323
323
  ordinal >= other.ordinal
324
324
  end
@@ -377,8 +377,8 @@ module OpenSkill
377
377
 
378
378
  # Validate teams structure
379
379
  def validate_teams!(teams)
380
- raise ArgumentError, 'Teams must be an Array' unless teams.is_a?(Array)
381
- raise ArgumentError, 'Must have at least 2 teams' if teams.size < 2
380
+ raise ArgumentError, "Teams must be an Array" unless teams.is_a?(Array)
381
+ raise ArgumentError, "Must have at least 2 teams" if teams.size < 2
382
382
 
383
383
  teams.each_with_index do |team, idx|
384
384
  raise ArgumentError, "Team #{idx} must be an Array" unless team.is_a?(Array)
@@ -393,7 +393,7 @@ module OpenSkill
393
393
  # Validate ranks
394
394
  def validate_ranks!(teams, ranks)
395
395
  raise ArgumentError, "Ranks must be an Array, got #{ranks.class}" unless ranks.is_a?(Array)
396
- raise ArgumentError, 'Ranks must have same length as teams' if ranks.size != teams.size
396
+ raise ArgumentError, "Ranks must have same length as teams" if ranks.size != teams.size
397
397
 
398
398
  ranks.each do |rank|
399
399
  raise ArgumentError, "All ranks must be numeric, got #{rank.class}" unless rank.is_a?(Numeric)
@@ -403,7 +403,7 @@ module OpenSkill
403
403
  # Validate scores
404
404
  def validate_scores!(teams, scores)
405
405
  raise ArgumentError, "Scores must be an Array, got #{scores.class}" unless scores.is_a?(Array)
406
- raise ArgumentError, 'Scores must have same length as teams' if scores.size != teams.size
406
+ raise ArgumentError, "Scores must have same length as teams" if scores.size != teams.size
407
407
 
408
408
  scores.each do |score|
409
409
  raise ArgumentError, "All scores must be numeric, got #{score.class}" unless score.is_a?(Numeric)
@@ -413,7 +413,7 @@ module OpenSkill
413
413
  # Validate weights
414
414
  def validate_weights!(teams, weights)
415
415
  raise ArgumentError, "Weights must be an Array, got #{weights.class}" unless weights.is_a?(Array)
416
- raise ArgumentError, 'Weights must have same length as teams' if weights.size != teams.size
416
+ raise ArgumentError, "Weights must have same length as teams" if weights.size != teams.size
417
417
 
418
418
  weights.each_with_index do |team_weights, idx|
419
419
  raise ArgumentError, "Weights for team #{idx} must be an Array" unless team_weights.is_a?(Array)
@@ -481,7 +481,7 @@ module OpenSkill
481
481
  comparison_count += 1
482
482
  end
483
483
 
484
- adjusted_mu += comparison_count > 0 ? (margin_adjustment / comparison_count) : margin_adjustment
484
+ adjusted_mu += (comparison_count > 0) ? (margin_adjustment / comparison_count) : margin_adjustment
485
485
  end
486
486
 
487
487
  summed = Math.exp(adjusted_mu / c_value)
@@ -516,11 +516,11 @@ module OpenSkill
516
516
 
517
517
  sorted_team.each do |player|
518
518
  balance_weight = if @balance
519
- ordinal_diff = max_ordinal - player.ordinal
520
- 1 + (ordinal_diff / (max_ordinal + @kappa))
521
- else
522
- 1.0
523
- end
519
+ ordinal_diff = max_ordinal - player.ordinal
520
+ 1 + (ordinal_diff / (max_ordinal + @kappa))
521
+ else
522
+ 1.0
523
+ end
524
524
 
525
525
  mu_sum += player.mu * balance_weight
526
526
  sigma_squared_sum += (player.sigma * balance_weight)**2
@@ -540,10 +540,10 @@ module OpenSkill
540
540
  return [] if game.empty?
541
541
 
542
542
  team_scores = if ranks
543
- ranks.each_with_index.map { |rank, idx| rank || idx }
544
- else
545
- game.each_index.to_a
546
- end
543
+ ranks.each_with_index.map { |rank, idx| rank || idx }
544
+ else
545
+ game.each_index.to_a
546
+ end
547
547
 
548
548
  sorted_scores = team_scores.sort
549
549
  rank_map = {}
@@ -603,7 +603,7 @@ module OpenSkill
603
603
  comparison_count += 1
604
604
  end
605
605
 
606
- adjusted_mu_i += comparison_count > 0 ? (margin_adjustment / comparison_count) : margin_adjustment
606
+ adjusted_mu_i += (comparison_count > 0) ? (margin_adjustment / comparison_count) : margin_adjustment
607
607
  end
608
608
 
609
609
  i_mu_over_c = Math.exp(adjusted_mu_i / c_value)
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'securerandom'
4
- require_relative '../statistics/normal'
5
- require_relative 'common'
3
+ require "securerandom"
4
+ require_relative "../statistics/normal"
5
+ require_relative "common"
6
6
 
7
7
  module OpenSkill
8
8
  module Models
@@ -74,8 +74,8 @@ module OpenSkill
74
74
  # @raise [ArgumentError] if rating_array is invalid
75
75
  def load_rating(rating_array, name: nil)
76
76
  raise ArgumentError, "Rating must be an Array, got #{rating_array.class}" unless rating_array.is_a?(Array)
77
- raise ArgumentError, 'Rating array must have exactly 2 elements' unless rating_array.size == 2
78
- raise ArgumentError, 'Rating values must be numeric' unless rating_array.all? { |v| v.is_a?(Numeric) }
77
+ raise ArgumentError, "Rating array must have exactly 2 elements" unless rating_array.size == 2
78
+ raise ArgumentError, "Rating values must be numeric" unless rating_array.all? { |v| v.is_a?(Numeric) }
79
79
 
80
80
  Rating.new(mu: rating_array[0], sigma: rating_array[1], name: name)
81
81
  end
@@ -95,7 +95,7 @@ module OpenSkill
95
95
  validate_scores!(teams, scores) if scores
96
96
  validate_weights!(teams, weights) if weights
97
97
 
98
- raise ArgumentError, 'Cannot provide both ranks and scores' if ranks && scores
98
+ raise ArgumentError, "Cannot provide both ranks and scores" if ranks && scores
99
99
 
100
100
  # Deep copy teams to avoid mutating input
101
101
  original_teams = teams
@@ -302,25 +302,25 @@ module OpenSkill
302
302
  end
303
303
 
304
304
  def <(other)
305
- raise ArgumentError, 'comparison with non-Rating' unless other.is_a?(Rating)
305
+ raise ArgumentError, "comparison with non-Rating" unless other.is_a?(Rating)
306
306
 
307
307
  ordinal < other.ordinal
308
308
  end
309
309
 
310
310
  def >(other)
311
- raise ArgumentError, 'comparison with non-Rating' unless other.is_a?(Rating)
311
+ raise ArgumentError, "comparison with non-Rating" unless other.is_a?(Rating)
312
312
 
313
313
  ordinal > other.ordinal
314
314
  end
315
315
 
316
316
  def <=(other)
317
- raise ArgumentError, 'comparison with non-Rating' unless other.is_a?(Rating)
317
+ raise ArgumentError, "comparison with non-Rating" unless other.is_a?(Rating)
318
318
 
319
319
  ordinal <= other.ordinal
320
320
  end
321
321
 
322
322
  def >=(other)
323
- raise ArgumentError, 'comparison with non-Rating' unless other.is_a?(Rating)
323
+ raise ArgumentError, "comparison with non-Rating" unless other.is_a?(Rating)
324
324
 
325
325
  ordinal >= other.ordinal
326
326
  end
@@ -379,8 +379,8 @@ module OpenSkill
379
379
 
380
380
  # Validate teams structure
381
381
  def validate_teams!(teams)
382
- raise ArgumentError, 'Teams must be an Array' unless teams.is_a?(Array)
383
- raise ArgumentError, 'Must have at least 2 teams' if teams.size < 2
382
+ raise ArgumentError, "Teams must be an Array" unless teams.is_a?(Array)
383
+ raise ArgumentError, "Must have at least 2 teams" if teams.size < 2
384
384
 
385
385
  teams.each_with_index do |team, idx|
386
386
  raise ArgumentError, "Team #{idx} must be an Array" unless team.is_a?(Array)
@@ -395,7 +395,7 @@ module OpenSkill
395
395
  # Validate ranks
396
396
  def validate_ranks!(teams, ranks)
397
397
  raise ArgumentError, "Ranks must be an Array, got #{ranks.class}" unless ranks.is_a?(Array)
398
- raise ArgumentError, 'Ranks must have same length as teams' if ranks.size != teams.size
398
+ raise ArgumentError, "Ranks must have same length as teams" if ranks.size != teams.size
399
399
 
400
400
  ranks.each do |rank|
401
401
  raise ArgumentError, "All ranks must be numeric, got #{rank.class}" unless rank.is_a?(Numeric)
@@ -405,7 +405,7 @@ module OpenSkill
405
405
  # Validate scores
406
406
  def validate_scores!(teams, scores)
407
407
  raise ArgumentError, "Scores must be an Array, got #{scores.class}" unless scores.is_a?(Array)
408
- raise ArgumentError, 'Scores must have same length as teams' if scores.size != teams.size
408
+ raise ArgumentError, "Scores must have same length as teams" if scores.size != teams.size
409
409
 
410
410
  scores.each do |score|
411
411
  raise ArgumentError, "All scores must be numeric, got #{score.class}" unless score.is_a?(Numeric)
@@ -415,7 +415,7 @@ module OpenSkill
415
415
  # Validate weights
416
416
  def validate_weights!(teams, weights)
417
417
  raise ArgumentError, "Weights must be an Array, got #{weights.class}" unless weights.is_a?(Array)
418
- raise ArgumentError, 'Weights must have same length as teams' if weights.size != teams.size
418
+ raise ArgumentError, "Weights must have same length as teams" if weights.size != teams.size
419
419
 
420
420
  weights.each_with_index do |team_weights, idx|
421
421
  raise ArgumentError, "Weights for team #{idx} must be an Array" unless team_weights.is_a?(Array)
@@ -453,11 +453,11 @@ module OpenSkill
453
453
 
454
454
  sorted_team.each do |player|
455
455
  balance_weight = if @balance
456
- ordinal_diff = max_ordinal - player.ordinal
457
- 1 + (ordinal_diff / (max_ordinal + @kappa))
458
- else
459
- 1.0
460
- end
456
+ ordinal_diff = max_ordinal - player.ordinal
457
+ 1 + (ordinal_diff / (max_ordinal + @kappa))
458
+ else
459
+ 1.0
460
+ end
461
461
 
462
462
  mu_sum += player.mu * balance_weight
463
463
  sigma_squared_sum += (player.sigma * balance_weight)**2
@@ -477,10 +477,10 @@ module OpenSkill
477
477
  return [] if game.empty?
478
478
 
479
479
  team_scores = if ranks
480
- ranks.each_with_index.map { |rank, idx| rank || idx }
481
- else
482
- game.each_index.to_a
483
- end
480
+ ranks.each_with_index.map { |rank, idx| rank || idx }
481
+ else
482
+ game.each_index.to_a
483
+ end
484
484
 
485
485
  sorted_scores = team_scores.sort
486
486
  rank_map = {}
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'securerandom'
4
- require_relative '../statistics/normal'
5
- require_relative 'common'
3
+ require "securerandom"
4
+ require_relative "../statistics/normal"
5
+ require_relative "common"
6
6
 
7
7
  module OpenSkill
8
8
  module Models
@@ -77,8 +77,8 @@ module OpenSkill
77
77
  # @raise [ArgumentError] if rating_array is invalid
78
78
  def load_rating(rating_array, name: nil)
79
79
  raise ArgumentError, "Rating must be an Array, got #{rating_array.class}" unless rating_array.is_a?(Array)
80
- raise ArgumentError, 'Rating array must have exactly 2 elements' unless rating_array.size == 2
81
- raise ArgumentError, 'Rating values must be numeric' unless rating_array.all? { |v| v.is_a?(Numeric) }
80
+ raise ArgumentError, "Rating array must have exactly 2 elements" unless rating_array.size == 2
81
+ raise ArgumentError, "Rating values must be numeric" unless rating_array.all? { |v| v.is_a?(Numeric) }
82
82
 
83
83
  Rating.new(mu: rating_array[0], sigma: rating_array[1], name: name)
84
84
  end
@@ -98,7 +98,7 @@ module OpenSkill
98
98
  validate_scores!(teams, scores) if scores
99
99
  validate_weights!(teams, weights) if weights
100
100
 
101
- raise ArgumentError, 'Cannot provide both ranks and scores' if ranks && scores
101
+ raise ArgumentError, "Cannot provide both ranks and scores" if ranks && scores
102
102
 
103
103
  # Deep copy teams to avoid mutating input
104
104
  original_teams = teams
@@ -305,25 +305,25 @@ module OpenSkill
305
305
  end
306
306
 
307
307
  def <(other)
308
- raise ArgumentError, 'comparison with non-Rating' unless other.is_a?(Rating)
308
+ raise ArgumentError, "comparison with non-Rating" unless other.is_a?(Rating)
309
309
 
310
310
  ordinal < other.ordinal
311
311
  end
312
312
 
313
313
  def >(other)
314
- raise ArgumentError, 'comparison with non-Rating' unless other.is_a?(Rating)
314
+ raise ArgumentError, "comparison with non-Rating" unless other.is_a?(Rating)
315
315
 
316
316
  ordinal > other.ordinal
317
317
  end
318
318
 
319
319
  def <=(other)
320
- raise ArgumentError, 'comparison with non-Rating' unless other.is_a?(Rating)
320
+ raise ArgumentError, "comparison with non-Rating" unless other.is_a?(Rating)
321
321
 
322
322
  ordinal <= other.ordinal
323
323
  end
324
324
 
325
325
  def >=(other)
326
- raise ArgumentError, 'comparison with non-Rating' unless other.is_a?(Rating)
326
+ raise ArgumentError, "comparison with non-Rating" unless other.is_a?(Rating)
327
327
 
328
328
  ordinal >= other.ordinal
329
329
  end
@@ -382,8 +382,8 @@ module OpenSkill
382
382
 
383
383
  # Validate teams structure
384
384
  def validate_teams!(teams)
385
- raise ArgumentError, 'Teams must be an Array' unless teams.is_a?(Array)
386
- raise ArgumentError, 'Must have at least 2 teams' if teams.size < 2
385
+ raise ArgumentError, "Teams must be an Array" unless teams.is_a?(Array)
386
+ raise ArgumentError, "Must have at least 2 teams" if teams.size < 2
387
387
 
388
388
  teams.each_with_index do |team, idx|
389
389
  raise ArgumentError, "Team #{idx} must be an Array" unless team.is_a?(Array)
@@ -398,7 +398,7 @@ module OpenSkill
398
398
  # Validate ranks
399
399
  def validate_ranks!(teams, ranks)
400
400
  raise ArgumentError, "Ranks must be an Array, got #{ranks.class}" unless ranks.is_a?(Array)
401
- raise ArgumentError, 'Ranks must have same length as teams' if ranks.size != teams.size
401
+ raise ArgumentError, "Ranks must have same length as teams" if ranks.size != teams.size
402
402
 
403
403
  ranks.each do |rank|
404
404
  raise ArgumentError, "All ranks must be numeric, got #{rank.class}" unless rank.is_a?(Numeric)
@@ -408,7 +408,7 @@ module OpenSkill
408
408
  # Validate scores
409
409
  def validate_scores!(teams, scores)
410
410
  raise ArgumentError, "Scores must be an Array, got #{scores.class}" unless scores.is_a?(Array)
411
- raise ArgumentError, 'Scores must have same length as teams' if scores.size != teams.size
411
+ raise ArgumentError, "Scores must have same length as teams" if scores.size != teams.size
412
412
 
413
413
  scores.each do |score|
414
414
  raise ArgumentError, "All scores must be numeric, got #{score.class}" unless score.is_a?(Numeric)
@@ -418,7 +418,7 @@ module OpenSkill
418
418
  # Validate weights
419
419
  def validate_weights!(teams, weights)
420
420
  raise ArgumentError, "Weights must be an Array, got #{weights.class}" unless weights.is_a?(Array)
421
- raise ArgumentError, 'Weights must have same length as teams' if weights.size != teams.size
421
+ raise ArgumentError, "Weights must have same length as teams" if weights.size != teams.size
422
422
 
423
423
  weights.each_with_index do |team_weights, idx|
424
424
  raise ArgumentError, "Weights for team #{idx} must be an Array" unless team_weights.is_a?(Array)
@@ -456,11 +456,11 @@ module OpenSkill
456
456
 
457
457
  sorted_team.each do |player|
458
458
  balance_weight = if @balance
459
- ordinal_diff = max_ordinal - player.ordinal
460
- 1 + (ordinal_diff / (max_ordinal + @kappa))
461
- else
462
- 1.0
463
- end
459
+ ordinal_diff = max_ordinal - player.ordinal
460
+ 1 + (ordinal_diff / (max_ordinal + @kappa))
461
+ else
462
+ 1.0
463
+ end
464
464
 
465
465
  mu_sum += player.mu * balance_weight
466
466
  sigma_squared_sum += (player.sigma * balance_weight)**2
@@ -480,10 +480,10 @@ module OpenSkill
480
480
  return [] if game.empty?
481
481
 
482
482
  team_scores = if ranks
483
- ranks.each_with_index.map { |rank, idx| rank || idx }
484
- else
485
- game.each_index.to_a
486
- end
483
+ ranks.each_with_index.map { |rank, idx| rank || idx }
484
+ else
485
+ game.each_index.to_a
486
+ end
487
487
 
488
488
  sorted_scores = team_scores.sort
489
489
  rank_map = {}
@@ -567,8 +567,8 @@ module OpenSkill
567
567
  end
568
568
 
569
569
  # Average over comparisons
570
- omega = comparisons > 0 ? omega_sum / comparisons : 0.0
571
- delta = comparisons > 0 ? delta_sum / comparisons : 0.0
570
+ omega = (comparisons > 0) ? omega_sum / comparisons : 0.0
571
+ delta = (comparisons > 0) ? delta_sum / comparisons : 0.0
572
572
 
573
573
  # Update each player in the team
574
574
  team_i.team.each_with_index.map do |player, j|
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'distribution'
3
+ require "distribution"
4
4
 
5
5
  module OpenSkill
6
6
  module Statistics
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OpenSkill
4
- VERSION = '1.0.0'
4
+ VERSION = "1.0.1"
5
5
  end
data/lib/openskill.rb CHANGED
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'openskill/version'
4
- require_relative 'openskill/statistics/normal'
5
- require_relative 'openskill/models/common'
6
- require_relative 'openskill/models/plackett_luce'
7
- require_relative 'openskill/models/bradley_terry_full'
8
- require_relative 'openskill/models/bradley_terry_part'
9
- require_relative 'openskill/models/thurstone_mosteller_full'
10
- require_relative 'openskill/models/thurstone_mosteller_part'
3
+ require_relative "openskill/version"
4
+ require_relative "openskill/statistics/normal"
5
+ require_relative "openskill/models/common"
6
+ require_relative "openskill/models/plackett_luce"
7
+ require_relative "openskill/models/bradley_terry_full"
8
+ require_relative "openskill/models/bradley_terry_part"
9
+ require_relative "openskill/models/thurstone_mosteller_full"
10
+ require_relative "openskill/models/thurstone_mosteller_part"
11
11
 
12
12
  module OpenSkill
13
13
  class Error < StandardError; end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openskill
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tamas Erdos
@@ -10,45 +10,45 @@ cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
- name: bigdecimal
13
+ name: distribution
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: '3.1'
18
+ version: '0.8'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: '3.1'
25
+ version: '0.8'
26
26
  - !ruby/object:Gem::Dependency
27
- name: distribution
27
+ name: bigdecimal
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
- - - "~>"
30
+ - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: '0.8'
32
+ version: '3.1'
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - "~>"
37
+ - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: '0.8'
39
+ version: '3.1'
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: prime
42
42
  requirement: !ruby/object:Gem::Requirement
43
43
  requirements:
44
- - - "~>"
44
+ - - ">="
45
45
  - !ruby/object:Gem::Version
46
46
  version: '0.1'
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - "~>"
51
+ - - ">="
52
52
  - !ruby/object:Gem::Version
53
53
  version: '0.1'
54
54
  - !ruby/object:Gem::Dependency
@@ -79,6 +79,20 @@ dependencies:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
81
  version: '13.0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: standardrb
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
82
96
  description: A Ruby implementation of the OpenSkill rating system, providing Bayesian
83
97
  skill ratings for multiplayer games
84
98
  email:
@@ -116,7 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
116
130
  - !ruby/object:Gem::Version
117
131
  version: '0'
118
132
  requirements: []
119
- rubygems_version: 3.6.9
133
+ rubygems_version: 4.0.20
120
134
  specification_version: 4
121
135
  summary: Multiplayer rating system for Ruby
122
136
  test_files: []