skillz 0.0.1 → 1.0.0

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
  SHA1:
3
- metadata.gz: 9668abe2cc46fea6d1be7f4d83d010b3b448db83
4
- data.tar.gz: 7d43232d6d2350c5ec6837abd1308c4b9f56e926
3
+ metadata.gz: 9aafccb1b92151740adced826a83b7fd56202086
4
+ data.tar.gz: 5d115d6930f74526772a8155f90e15b5934ac5cd
5
5
  SHA512:
6
- metadata.gz: e3a2d5f7ef1721ca20c7a508ecaa3de5cdd49248aba75dd625568de26dfbef4ddf6ec41593f70774aa33a8fe86ef5c795ecf8e8e0e5b1a82b8a9e533d0e01115
7
- data.tar.gz: 3efb7706bf2a463910c45ff20948c680990928394310bffa93e7813daa876a25a4635e426a2a8dd39fe20532610f14221a8b6a4c4b9b27cb147e150211895c96
6
+ metadata.gz: aebf90293ad5a8af150067ce186160f2489dddc2aaf13216f475e41c7f2d8a854d8da8202ae09243b14769f3c2401cf26b4e5025b3d5f1cd25a54a90e11c55b8
7
+ data.tar.gz: b6401741ab2288dcec785e8161e60f49e31b656a2c6123a7daa0d776d960205b934353cc65e8fa1afd5c56a0fdecff76c729705c8ad59cea5e79672459502ffa
@@ -2,5 +2,6 @@ language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
+ - 2.1.0
5
6
  - jruby-19mode # JRuby in 1.9 mode
6
7
  - rbx-19mode
data/README.md CHANGED
@@ -38,7 +38,7 @@ Or install it yourself as:
38
38
  team2 = Skillz::Team.new([p3, p4], 2)
39
39
 
40
40
  Skillz::Match.score(Skillz::Team.new([p1, p2], 1), Skillz::Team.new([p2], 2))
41
- # players are now update with their new skill_level and uncertainty_in_skill_level
41
+ # players are now update with their new skill_level and skill_uncertainty
42
42
 
43
43
  ## Contributing
44
44
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 1.0.0
@@ -28,9 +28,9 @@ module Skillz
28
28
  end
29
29
 
30
30
  team1.players.map do |player|
31
- uncertainty_squared = player.uncertainty_in_skill_level**2
31
+ uncertainty_squared = player.skill_uncertainty**2
32
32
  player.skill_level += uncertainty_squared/team1.uncertainty * omega
33
- player.uncertainty_in_skill_level *= Math.sqrt([1 - uncertainty_squared / team1.uncertainty * delta, 0.0001].max)
33
+ player.skill_uncertainty *= Math.sqrt([1 - uncertainty_squared / team1.uncertainty * delta, 0.0001].max)
34
34
  player
35
35
  end
36
36
  end
@@ -1,21 +1,29 @@
1
+ require 'securerandom'
2
+
1
3
  module Skillz
2
4
  class Player
3
5
 
4
- attr_accessor :skill_level, :uncertainty_in_skill_level
6
+ attr_accessor :skill_level, :skill_uncertainty, :temporary_id
5
7
 
6
- def initialize(skill_level=nil, uncertainty=nil, last_match_time=nil)
8
+ def initialize(skill_level=nil, uncertainty=nil, last_match_time=nil, temporary_id=nil)
7
9
  @skill_level = skill_level || Skillz::INITIAL_SKILL_LEVEL
8
- @uncertainty_in_skill_level = uncertainty || Skillz::UNCERTAINTY
9
- if last_match_time
10
- days = (Time.now - last_match_time).to_i / (24 * 60 * 60)
11
- time_decay = 1 + -Math.exp((days * -1.0)/365)
12
- time_decay *= [[uncertainty_in_skill_level, 4].max, 10].min
13
- @uncertainty_in_skill_level += time_decay
14
- end
10
+ @skill_uncertainty = uncertainty || Skillz::UNCERTAINTY
11
+ @temporary_id = temporary_id || SecureRandom.uuid
12
+ adjust_for_inactivity(last_match_time) if last_match_time
15
13
  end
16
14
 
17
15
  def adjusted_skill_level
18
- @skill_level - @uncertainty_in_skill_level
16
+ @skill_level - (@skill_uncertainty * 0.5)
17
+ end
18
+
19
+ private
20
+
21
+ def adjust_for_inactivity(last_match_time)
22
+ days = (Time.now - last_match_time).to_i / (24 * 60 * 60)
23
+ return if days <= 25
24
+ time_decay = 1 - Math.exp((days * -1.0)/365)
25
+ time_decay *= [[skill_uncertainty, 4].max, 10].min
26
+ @skill_uncertainty += time_decay
19
27
  end
20
28
  end
21
29
  end
@@ -15,7 +15,7 @@ module Skillz
15
15
  def uncertainty
16
16
  @uncertainty_squared ||= begin
17
17
  @players.map do |player|
18
- player.uncertainty_in_skill_level * player.uncertainty_in_skill_level
18
+ player.skill_uncertainty * player.skill_uncertainty
19
19
  end.sum
20
20
  end
21
21
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "skillz"
8
- s.version = "0.0.1"
8
+ s.version = "1.0.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["frausto"]
12
- s.date = "2013-08-16"
12
+ s.date = "2014-04-05"
13
13
  s.description = "A ruby library implementing a competitive ranking system based on trueskill and other similar systems. Built to address issues such as cheating, tournaments, team-play, matching, etc.. "
14
14
  s.email = "nrfrausto@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -43,22 +43,22 @@ describe Skillz::Match do
43
43
  end
44
44
  end
45
45
 
46
- describe 'uncertainty_in_skill_level' do
46
+ describe 'skill_uncertainty' do
47
47
  it "one ceratin player beats uncertain player" do
48
48
  p1 = Skillz::Player.new(25, 2.3)
49
49
  p2 = Skillz::Player.new(25, 10)
50
50
 
51
51
  p1.skill_level.should == 25
52
52
  p2.skill_level.should == 25
53
- p1.uncertainty_in_skill_level.should == 2.3
54
- p2.uncertainty_in_skill_level.should == 10
53
+ p1.skill_uncertainty.should == 2.3
54
+ p2.skill_uncertainty.should == 10
55
55
 
56
56
  Skillz::Match.score(Skillz::Team.new([p1], 1), Skillz::Team.new([p2], 2))
57
57
 
58
58
  p1.skill_level.round(7).should == 25.2235335
59
59
  p2.skill_level.round(7).should == 20.7744132
60
- p1.uncertainty_in_skill_level.round(7).should == 2.2978876
61
- p2.uncertainty_in_skill_level.round(7).should == 9.2146587
60
+ p1.skill_uncertainty.round(7).should == 2.2978876
61
+ p2.skill_uncertainty.round(7).should == 9.2146587
62
62
  end
63
63
 
64
64
  it "one unceratin player beats certain player" do
@@ -67,15 +67,15 @@ describe Skillz::Match do
67
67
 
68
68
  p1.skill_level.should == 25
69
69
  p2.skill_level.should == 25
70
- p1.uncertainty_in_skill_level.should == 2.3
71
- p2.uncertainty_in_skill_level.should == 10
70
+ p1.skill_uncertainty.should == 2.3
71
+ p2.skill_uncertainty.should == 10
72
72
 
73
73
  Skillz::Match.score(Skillz::Team.new([p1], 2), Skillz::Team.new([p2], 1))
74
74
 
75
75
  p1.skill_level.round(7).should == 24.7764665
76
76
  p2.skill_level.round(7).should == 29.2255868
77
- p1.uncertainty_in_skill_level.round(7).should == 2.2978876
78
- p2.uncertainty_in_skill_level.round(7).should == 9.2146587
77
+ p1.skill_uncertainty.round(7).should == 2.2978876
78
+ p2.skill_uncertainty.round(7).should == 9.2146587
79
79
  end
80
80
 
81
81
 
@@ -83,8 +83,8 @@ describe Skillz::Match do
83
83
  p1 = Skillz::Player.new(30, 9.9)
84
84
  p2 = Skillz::Player.new(10, 3)
85
85
 
86
- p1.uncertainty_in_skill_level.should == 9.9
87
- p2.uncertainty_in_skill_level.should == 3
86
+ p1.skill_uncertainty.should == 9.9
87
+ p2.skill_uncertainty.should == 3
88
88
  p1.skill_level.should == 30
89
89
  p2.skill_level.should == 10
90
90
 
@@ -92,8 +92,8 @@ describe Skillz::Match do
92
92
 
93
93
  p1.skill_level.round(7).should == 23.0607762
94
94
  p2.skill_level.round(7).should == 10.6372106
95
- p1.uncertainty_in_skill_level.round(7).should == 9.5156031
96
- p2.uncertainty_in_skill_level.round(7).should == 2.9968199
95
+ p1.skill_uncertainty.round(7).should == 9.5156031
96
+ p2.skill_uncertainty.round(7).should == 2.9968199
97
97
  end
98
98
 
99
99
 
@@ -101,8 +101,8 @@ describe Skillz::Match do
101
101
  p1 = Skillz::Player.new(30, 9.9)
102
102
  p2 = Skillz::Player.new(10, 3)
103
103
 
104
- p1.uncertainty_in_skill_level.should == 9.9
105
- p2.uncertainty_in_skill_level.should == 3
104
+ p1.skill_uncertainty.should == 9.9
105
+ p2.skill_uncertainty.should == 3
106
106
  p1.skill_level.should == 30
107
107
  p2.skill_level.should == 10
108
108
 
@@ -110,16 +110,16 @@ describe Skillz::Match do
110
110
 
111
111
  p1.skill_level.round(7).should == 31.2933587
112
112
  p2.skill_level.round(7).should == 9.8812343
113
- p1.uncertainty_in_skill_level.round(7).should == 9.5156031
114
- p2.uncertainty_in_skill_level.round(7).should == 2.9968199
113
+ p1.skill_uncertainty.round(7).should == 9.5156031
114
+ p2.skill_uncertainty.round(7).should == 2.9968199
115
115
  end
116
116
 
117
117
  it "certain high level loses to uncertain low level player" do
118
118
  p1 = Skillz::Player.new(30, 3)
119
119
  p2 = Skillz::Player.new(10, 9.9)
120
120
 
121
- p1.uncertainty_in_skill_level.should == 3
122
- p2.uncertainty_in_skill_level.should == 9.9
121
+ p1.skill_uncertainty.should == 3
122
+ p2.skill_uncertainty.should == 9.9
123
123
  p1.skill_level.should == 30
124
124
  p2.skill_level.should == 10
125
125
 
@@ -127,16 +127,16 @@ describe Skillz::Match do
127
127
 
128
128
  p1.skill_level.round(7).should == 29.3627894
129
129
  p2.skill_level.round(7).should == 16.9392238
130
- p1.uncertainty_in_skill_level.round(7).should == 2.9968199
131
- p2.uncertainty_in_skill_level.round(7).should == 9.5156031
130
+ p1.skill_uncertainty.round(7).should == 2.9968199
131
+ p2.skill_uncertainty.round(7).should == 9.5156031
132
132
  end
133
133
 
134
134
  it "certain high level wins against uncertain low level player" do
135
135
  p1 = Skillz::Player.new(30, 3)
136
136
  p2 = Skillz::Player.new(10, 9.9)
137
137
 
138
- p1.uncertainty_in_skill_level.should == 3
139
- p2.uncertainty_in_skill_level.should == 9.9
138
+ p1.skill_uncertainty.should == 3
139
+ p2.skill_uncertainty.should == 9.9
140
140
  p1.skill_level.should == 30
141
141
  p2.skill_level.should == 10
142
142
 
@@ -144,8 +144,36 @@ describe Skillz::Match do
144
144
 
145
145
  p1.skill_level.round(7).should == 30.1187657
146
146
  p2.skill_level.round(7).should == 8.7066413
147
- p1.uncertainty_in_skill_level.round(7).should == 2.9968199
148
- p2.uncertainty_in_skill_level.round(7).should == 9.5156031
147
+ p1.skill_uncertainty.round(7).should == 2.9968199
148
+ p2.skill_uncertainty.round(7).should == 9.5156031
149
+ end
150
+
151
+
152
+ it "works for team matches" do
153
+ p1 = Skillz::Player.new(30, 3)
154
+ p2 = Skillz::Player.new(20, 9.9)
155
+ p3 = Skillz::Player.new(25, 7.9)
156
+ p4 = Skillz::Player.new(32, 4.9)
157
+
158
+ p1.skill_uncertainty.should == 3
159
+ p2.skill_uncertainty.should == 9.9
160
+ p3.skill_uncertainty.should == 7.9
161
+ p4.skill_uncertainty.should == 4.9
162
+ p1.skill_level.should == 30
163
+ p2.skill_level.should == 20
164
+ p3.skill_level.should == 25
165
+ p4.skill_level.should == 32
166
+
167
+ Skillz::Match.score(Skillz::Team.new([p1, p3], 1), Skillz::Team.new([p4, p2], 2))
168
+
169
+ p1.skill_level.round(7).should == 30.2684317
170
+ p2.skill_level.round(7).should == 17.0767787
171
+ p3.skill_level.round(7).should == 26.8614248
172
+ p4.skill_level.round(7).should == 31.2838839
173
+ p1.skill_uncertainty.round(7).should == 2.9917939
174
+ p2.skill_uncertainty.round(7).should == 9.5072471
175
+ p3.skill_uncertainty.round(7).should == 7.7489117
176
+ p4.skill_uncertainty.round(7).should == 4.8530988
149
177
  end
150
178
  end
151
179
  end
@@ -1,10 +1,37 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Skillz::Player do
4
+ before do
5
+ @now = Time.now
6
+ Time.stub(:now => @now)
7
+ end
8
+
4
9
  it "should increase uncertainty based on when the last match was played" do
5
- now = Time.now
6
- Time.stub(:now => now)
7
- Skillz::Player.new(25, 4, now - 60.days).uncertainty_in_skill_level.round(7).should == 4.6063338
8
- Skillz::Player.new(25, 4, now - 10.days).uncertainty_in_skill_level.round(7).should == 4.1081014
10
+ Skillz::Player.new(25, 5, @now - 60.days).skill_uncertainty.round(7).should == 5.7462792
11
+ end
12
+
13
+ it "does not adjust if inactive for less than 25 days" do
14
+ Skillz::Player.new(25, 5, @now - 25.days).skill_uncertainty.round(7).should == 5
15
+ Skillz::Player.new(25, 5, @now - 26.days).skill_uncertainty.round(7).should == 5.343775
16
+ end
17
+
18
+ it "time decay assumes 4 for sigma lower than 4" do
19
+ smaller = Skillz::Player.new(25, 2, @now - 60.days).skill_uncertainty.round(7) - 2
20
+ larger = Skillz::Player.new(25, 4, @now - 60.days).skill_uncertainty.round(7) - 4
21
+ smaller.round(7).should == larger.round(7)
22
+ end
23
+
24
+ it "time decay assumes 10 for sigma larger than 10" do
25
+ smaller = Skillz::Player.new(25, 11, @now - 60.days).skill_uncertainty.round(7) - 11
26
+ larger = Skillz::Player.new(25, 10, @now - 60.days).skill_uncertainty.round(7) - 10
27
+ smaller.should == larger
28
+ smaller = Skillz::Player.new(25, 13, @now - 13.days).skill_uncertainty.round(7) - 13
29
+ larger = Skillz::Player.new(25, 10, @now - 13.days).skill_uncertainty.round(7) - 10
30
+ smaller.should == larger
31
+ end
32
+
33
+ it "sets a temporary_id" do
34
+ one = Skillz::Player.new(25, 11).temporary_id.should be_present
35
+ two = Skillz::Player.new(25, 10, nil, 5).temporary_id.should == 5
9
36
  end
10
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skillz
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - frausto
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-16 00:00:00.000000000 Z
11
+ date: 2014-04-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport