Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
CRAP | |
100.00% |
1 / 1 |
Elo | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
2 | |
100.00% |
1 / 1 |
rating | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
2 |
1 | <?php |
2 | /** |
3 | * Jingga |
4 | * |
5 | * PHP Version 8.1 |
6 | * |
7 | * @package phpOMS\Algorithm\Rating |
8 | * @copyright Dennis Eichhorn |
9 | * @license OMS License 2.0 |
10 | * @version 1.0.0 |
11 | * @link https://jingga.app |
12 | */ |
13 | declare(strict_types=1); |
14 | |
15 | namespace phpOMS\Algorithm\Rating; |
16 | |
17 | /** |
18 | * Elo rating calculation using Elo rating |
19 | * |
20 | * @package phpOMS\Algorithm\Rating |
21 | * @license OMS License 2.0 |
22 | * @link https://jingga.app |
23 | * @see https://en.wikipedia.org/wiki/Elo_rating_system |
24 | * @since 1.0.0 |
25 | */ |
26 | final class Elo |
27 | { |
28 | /** |
29 | * ELO change rate |
30 | * |
31 | * @var int |
32 | * @since 1.0.0 |
33 | */ |
34 | public int $K = 32; |
35 | |
36 | /** |
37 | * Default elo to use for new players |
38 | * |
39 | * @var int |
40 | * @since 1.0.0 |
41 | */ |
42 | public int $DEFAULT_ELO = 1500; |
43 | |
44 | /** |
45 | * Lowest elo allowed |
46 | * |
47 | * @var int |
48 | * @since 1.0.0 |
49 | */ |
50 | public int $MIN_ELO = 100; |
51 | |
52 | /** |
53 | * Calculate the elo rating |
54 | * |
55 | * @param int $elo Current player elo |
56 | * @param int[] $oElo Current elo of all opponents |
57 | * @param float[] $s Match results against the opponents (1 = victor, 0 = loss, 0.5 = draw) |
58 | * |
59 | * @return array{elo:int} |
60 | * |
61 | * @since 1.0.0 |
62 | */ |
63 | public function rating(int $elo, array $oElo, array $s) : array |
64 | { |
65 | $eloNew = $elo; |
66 | foreach ($oElo as $idx => $o) { |
67 | $expected = 1 / (1 + 10 ** (($o - $elo) / 400)); |
68 | $r = $this->K * ($s[$idx] - $expected); |
69 | |
70 | $eloNew += (int) \round($r); |
71 | } |
72 | |
73 | return [ |
74 | 'elo' => (int) \max($eloNew, $this->MIN_ELO), |
75 | ]; |
76 | } |
77 | } |