multiplayer_elo 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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