Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
CRAP
100.00% covered (success)
100.00%
1 / 1
Elo
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
1 / 1
 rating
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
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 */
13declare(strict_types=1);
14
15namespace 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 */
26final 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}