multiplayer_elo 0.0.1 → 0.0.2

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: 75099833c68a10003e851f282b82423429d78077
4
- data.tar.gz: 9d93d3d28c2a5bba8cea4a989a1ffa8485b6b9bc
3
+ metadata.gz: 0c78e907b29d478234ebdcabcaf56be21c6e8fdb
4
+ data.tar.gz: e1fc166fb70c4f4a260c81da114db054c8571735
5
5
  SHA512:
6
- metadata.gz: c086a5a977ddeb7bb408d341c0aa9d02b554de053ae070af6758a4c5e87a6ca3ffefa8812e427cbd13041af8d3452b4ce31ccb8e305a978f6764e53402509287
7
- data.tar.gz: 1a65bc2f52ce1ec4b7c04736a585bc8a1dbc9da3d0d109cc217fd1c25e941b89ac0209e3bff397cad7eb25365e67c8c67ac22e016bd7d1d3e310e048fd9ab43a
6
+ metadata.gz: 01c87d2c6fbaf2ae12d85bd8cd77cde5bf2887ccacaf0ba2e569753ba65d92bdd75f3a3ff9105bd17b13028d32ebaf85b2bfee247eda023fb47b3e727bed14cc
7
+ data.tar.gz: cd45fe6a281b9047963e6cfd47510750df1a20ca4a3abd21a6b282f0eced385a23e5ff975f5d552cff7ae21742efe9a16caee54148be76091bc9993b99432de9
@@ -0,0 +1,38 @@
1
+ class EloManager
2
+ attr_accessor :k_factor
3
+
4
+ def initialize
5
+ @k_factor = 20
6
+ end
7
+
8
+ def expected_percentage(elo1, elo2)
9
+ 1.0 / ( 1.0 + ( 10.0 ** ((elo2.to_f - elo1.to_f) / 400.0) ) )
10
+ end
11
+
12
+ # result is 0 for a loss 1 for a win or .5 for a tie
13
+ def points_change(elo1, elo2, result)
14
+ (@k_factor.to_f * (result.to_f - expected_percentage(elo1, elo2))).round
15
+ end
16
+
17
+ def evaulate_results(results)
18
+ results.each do |i|
19
+ elo_change = 0
20
+ results.each do |j|
21
+ next if i == j
22
+
23
+ # we are using places so first place < 2nd place means a win
24
+ if i[:place] > j[:place]
25
+ winner = 0
26
+ elsif i[:place] == j[:place]
27
+ winner = 0.5
28
+ else
29
+ winner = 1
30
+ end
31
+
32
+ elo_change += points_change(i[:elo], j[:elo], winner)
33
+ end
34
+
35
+ i[:new_elo] = i[:elo] + elo_change
36
+ end
37
+ end
38
+ end
@@ -1,3 +1,3 @@
1
1
  module MultiplayerElo
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -1,8 +1,10 @@
1
1
  require "multiplayer_elo/version"
2
2
  require 'multiplayer_elo/rating_manager'
3
+ require 'multiplayer_elo/elo_manager'
3
4
 
4
5
  module MultiplayerElo
5
6
  module Rateable
7
+ extend ActiveSupport::Concern
6
8
 
7
9
  module ClassMethods
8
10
  def acts_as_rateable(options = {})
@@ -10,4 +12,6 @@ module MultiplayerElo
10
12
  end
11
13
  end
12
14
  end
13
- end
15
+ end
16
+
17
+ ActiveRecord::Base.send(:include, MultiplayerElo::Rateable)
@@ -2,10 +2,9 @@ require 'spec_helper'
2
2
 
3
3
  describe MultiplayerElo do
4
4
  it 'adding acts_as_rateable should be included in active record' do
5
- expect do
6
- class Foo < ActiveRecord::Base
7
- acts_as_rateable
8
- end
5
+ class Foo < ActiveRecord::Base
6
+ acts_as_rateable
9
7
  end
10
8
  end
9
+
11
10
  end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ describe EloManager do
4
+ before(:all) do
5
+ @elo_manager = EloManager.new
6
+ end
7
+
8
+ it 'should have a default k-factor of 20' do
9
+ expect(@elo_manager.k_factor).to eq(20)
10
+ end
11
+
12
+ it 'should have a method to predict the chance of a player to win' do
13
+ expect(@elo_manager.expected_percentage(1500,1500)).to eq (0.5)
14
+ expect(@elo_manager.expected_percentage(2000,1500)).to be > (0.94)
15
+ expect(@elo_manager.expected_percentage(2000,1500)).to be < (0.95)
16
+ expect(@elo_manager.expected_percentage(1500,2000)).to be > (0.05)
17
+ expect(@elo_manager.expected_percentage(1500,2000)).to be < (0.06)
18
+ expect(@elo_manager.expected_percentage(1500,1600)).to be > (0.24)
19
+ end
20
+
21
+ it 'should have a method which tells you the points change for 2 elos' do
22
+ expect(@elo_manager.points_change(1500,1500, 1)).to eq(10)
23
+ expect(@elo_manager.points_change(1510,1490, 1)).to eq(9)
24
+ expect(@elo_manager.points_change(1500,2000, 1)).to eq(19)
25
+ expect(@elo_manager.points_change(1500,1500, 0)).to eq(-10)
26
+ expect(@elo_manager.points_change(1500,1500, 0.5)).to eq(0)
27
+ end
28
+
29
+ it 'should have a method which returns the new elo in the result' do
30
+ game_results = [{id: 1, elo: 1500, place: 1}, {id: 2, elo: 1500, place: 2}]
31
+ results = @elo_manager.evaulate_results(game_results)
32
+ expect(results[0].keys).to eq([:id, :elo, :place, :new_elo])
33
+ expect(results[0][:new_elo]).to eq(1510)
34
+ expect(results[1][:new_elo]).to eq(1490)
35
+ end
36
+
37
+ it 'should support multiple players' do
38
+ players = [ {id: 1, elo: 1500, place: 1}, {id: 2, elo: 1500, place: 2},
39
+ {id: 3, elo: 1500, place: 3}, {id: 4, elo: 1500, place: 4} ]
40
+
41
+ results = @elo_manager.evaulate_results(players)
42
+
43
+ expect(results[0][:new_elo]).to eq(1530)
44
+ expect(results[1][:new_elo]).to eq(1510)
45
+ expect(results[2][:new_elo]).to eq(1490)
46
+ expect(results[3][:new_elo]).to eq(1470)
47
+ end
48
+
49
+ it 'should support ties' do
50
+ players = [ {id: 1, elo: 1500, place: 1}, {id: 2, elo: 1500, place: 2},
51
+ {id: 3, elo: 1500, place: 2}, {id: 4, elo: 1500, place: 3} ]
52
+
53
+ results = @elo_manager.evaulate_results(players)
54
+
55
+ expect(results[0][:new_elo]).to eq(1530)
56
+ expect(results[1][:new_elo]).to eq(1500)
57
+ expect(results[2][:new_elo]).to eq(1500)
58
+ expect(results[3][:new_elo]).to eq(1470)
59
+ end
60
+
61
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require 'active_record'
2
2
  require 'multiplayer_elo'
3
- require 'multiplayer_elo/test_user'
4
3
 
5
4
  ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => File.dirname(__FILE__) + "/test.sqlite3")
6
5
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: multiplayer_elo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Marks
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-10 00:00:00.000000000 Z
11
+ date: 2014-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -93,12 +93,11 @@ files:
93
93
  - README.md
94
94
  - Rakefile
95
95
  - lib/multiplayer_elo.rb
96
- - lib/multiplayer_elo/rating_manager.rb
97
- - lib/multiplayer_elo/test_user.rb
96
+ - lib/multiplayer_elo/elo_manager.rb
98
97
  - lib/multiplayer_elo/version.rb
99
98
  - multiplayer_elo.gemspec
100
99
  - spec/acts_as_rateable_spec.rb
101
- - spec/ratings_manager_spec.rb
100
+ - spec/elo_manager_spec.rb
102
101
  - spec/spec_helper.rb
103
102
  homepage: ''
104
103
  licenses:
@@ -126,5 +125,5 @@ specification_version: 4
126
125
  summary: Elo library for single and multiplayer games
127
126
  test_files:
128
127
  - spec/acts_as_rateable_spec.rb
129
- - spec/ratings_manager_spec.rb
128
+ - spec/elo_manager_spec.rb
130
129
  - spec/spec_helper.rb
@@ -1,26 +0,0 @@
1
- class RatingManager
2
- @k_factor = 20
3
-
4
- def self.expected_percentage(elo1, elo2)
5
- 1.0 / ( 1.0 + ( 10.0 ** ((elo2.to_f - elo1.to_f) / 400.0) ) )
6
- end
7
-
8
- def self.update_ratings!(player1, player2, winner=1)
9
-
10
- percent = self.expected_percentage(player1.rating, player2.rating)
11
- points = (percent * @k_factor.to_f).round
12
-
13
- case winner
14
- when 1
15
- player1.rating += (@k_factor - points)
16
- player2.rating -= (@k_factor - points)
17
- when 2
18
- player2.rating += points
19
- player1.rating -= points
20
- else
21
- difference = (@k_factor.to_f * (0.5 - percent)).round
22
- player1.rating += difference
23
- player2.rating -= difference
24
- end
25
- end
26
- end
@@ -1,7 +0,0 @@
1
- class TestUser < ActiveRecord::Base
2
- attr_accessor :rating
3
-
4
- def initialize
5
- self.rating = 1500
6
- end
7
- end
@@ -1,28 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe RatingManager do
4
-
5
- it 'should update the ranking of the winner and loser' do
6
- winning_player = TestUser.new
7
- losing_player = TestUser.new
8
-
9
- RatingManager.update_ratings!(winning_player, losing_player, 1)
10
- expect(winning_player.rating).to eq(1510)
11
- expect(losing_player.rating).to eq(1490)
12
-
13
- RatingManager.update_ratings!(winning_player, losing_player, 1)
14
- expect(winning_player.rating).to eq(1519)
15
- expect(losing_player.rating).to eq(1481)
16
-
17
- RatingManager.update_ratings!(winning_player, losing_player, 0)
18
- expect(winning_player.rating).to eq(1518)
19
- expect(losing_player.rating).to eq(1482)
20
-
21
- winning_player.rating = 1500
22
- losing_player.rating = 2000
23
- RatingManager.update_ratings!(losing_player, winning_player, 2)
24
- expect(winning_player.rating).to eq(1519)
25
- expect(losing_player.rating).to eq(1981)
26
-
27
- end
28
- end