]> iEval git - games-ratings-logisticelo.git/blame - lib/Games/Ratings/LogisticElo.pm
Initial commit
[games-ratings-logisticelo.git] / lib / Games / Ratings / LogisticElo.pm
CommitLineData
dc4278d6
MG
1package Games::Ratings::LogisticElo;
2
3use 5.014000;
4use strict;
5use warnings;
6use parent qw/Exporter Games::Ratings/;
7
8our @EXPORT_OK = qw/multi_elo/;
9our @EXPORT = qw//;
10our $VERSION = '0.001';
11
12use List::Util qw/sum/;
13
14sub get_rating_change {
15 my ($self) = @_;
16
17 my $own_rating = $self->get_rating;
18 my $K = $self->get_coefficient;
19
20 my $expected = sum map {
21 my $exp = ($_->{opponent_rating} - $own_rating) / 400;
22 1 / (1 + 10 ** $exp)
23 } $self->get_all_games;
24
25 my $actual = sum map {
26 Games::Ratings::_get_numerical_result($_->{result})
27 } $self->get_all_games;
28
29 $K * ($actual - $expected)
30}
31
32sub get_new_rating {
33 my ($self) = @_;
34 $self->get_rating + $self->get_rating_change
35}
36
37sub multi_elo {
38 my @args = @_;
39 my $K = ref $args[0] ? 15 : shift @args;
40
41 my @newratings = map {
42 my $player = __PACKAGE__->new;
43 $player->set_rating($_->[0]);
44 $player->set_coefficient($K);
45 for my $opponent (@args) {
46 $player->add_game({
47 opponent_rating => $opponent->[0],
48 result =>
49 $_->[1] > $opponent->[1] ? 'win' :
50 $_->[1] < $opponent->[1] ? 'loss' : 'draw'
51 })
52 }
53 $player->get_new_rating
54 } @args;
55
56 wantarray ? @newratings : \@newratings
57}
58
591;
60__END__
61
62=encoding utf-8
63
64=head1 NAME
65
66Games::Ratings::LogisticElo - calculate changes to logistic curve Elo ratings
67
68=head1 SYNOPSIS
69
70 use Games::Ratings::LogisticElo;
71 my $player = Games::Ratings::LogisticElo->new;
72 $player->set_rating(2240);
73 $player->set_coefficient(15);
74 $player->add_game({
75 opponent_rating => 2114,
76 result => 'win', ## or 'draw' or 'loss'
77 });
78 say 'Rating change: ' . $player->get_rating_change;
79 say 'New rating: ' . $player->get_new_rating;
80
81 use Games::Ratings::LogisticElo qw/multi_elo/;
82 my @results = [2240, 3], [2114, 2], [2300, 1];
83 my @new_ratings = multi_elo 15, @results;
84 say 'Rating changes for this comp: ', join ', ',
85 map { $new_ratings[$_] - $results[$_]->[0] } 0 .. $#results;
86
87=head1 DESCRIPTION
88
89This module provides methods to calculate Elo rating changes. Unlike
90L<Games::Ratings::Chess::FIDE>, this Elo implementation uses the
91logistic distribution instead of the standard distribution.
92
93This module can be used both for a single player who played multiple
94rated games, and for a single competition with an arbitrary number of
95players.
96
97=head1 FUNCTIONS
98
99Games::Ratings::LogisticElo inherits from L<Games::Ratings>, see that
100module's documentation for information about the inherited methods.
101
102Nothing is exported by default, the function B<multi_elo> can be
103exported on request.
104
105=over
106
107=item B<$self>->I<get_rating_change>
108
109Computes and returns how much a player's rating changes after the
110games added.
111
112=item B<$self>->I<get_new_rating>
113
114Adds the result of I<get_rating_change> to the old rating of the
115player and returns this.
116
117=item B<multi_elo> [$coefficient], @results
118
119Computes the ratings after a competition with an arbitrary number of
120players.
121
122The first argument is the coefficient. It is optional, with the
123default coefficient being 15. The next arguments are the results of
124the players. Each result is a 2-element arrayref, the first element
125being the Elo rating of the player, and the second element being the
126score that player obtained. The scores are only used to compare
127players, their absolute values are irrelevant.
128
129The return value is a list (in list context) or arrayref (in scalar
130context) of ratings of all players after the competition, in the same
131order as the arguments.
132
133This function computes the ratings by considering that each player
134played a game with every other player, with the winner of every game
135being the player who got the highest score.
136
137=back
138
139
140=head1 SEE ALSO
141
142L<Games::Ratings::Chess::FIDE>, L<Games::Ratings>
143
144L<https://en.wikipedia.org/wiki/Elo_rating>
145
146=head1 AUTHOR
147
148Marius Gavrilescu <marius@ieval.ro>
149
150=head1 COPYRIGHT AND LICENSE
151
152Copyright (C) 2016 by Marius Gavrilescu
153
154This library is free software; you can redistribute it and/or modify
155it under the same terms as Perl itself, either Perl version 5.22.2 or,
156at your option, any later version of Perl 5 you may have available.
157
158
159=cut
This page took 0.036942 seconds and 4 git commands to generate.