lib_rapid/math/ratings/elo/
player.rs

1use crate::math::general::NumTools;
2
3/// The player necessary for a Elo evaluation.
4pub struct EloPlayer {
5    pub elo:  (f32, u16),
6    pub age:  u8,
7    k_factor: u8
8}
9
10impl EloPlayer {
11    /// Create a new player.
12    /// # Arguments
13    /// * `elo: (f32, u16)` - The rating. `f32` is the actual rating, `u16` the index which indicates the played matches.
14    /// * `age: u8` - The age of the player.
15    /// # Examples
16    /// ```
17    /// use lib_rapid::math::ratings::elo::player::EloPlayer;
18    /// 
19    /// let mut player = EloPlayer::new((2306.0, 32), 43);
20    /// ```
21    pub fn new(elo: (f32, u16), age: u8) -> EloPlayer {
22        let mut res = EloPlayer { elo, age, k_factor: 0 };
23        res.update_k_factor();
24        res
25    }
26    /// Update a player's rating.
27    /// # Arguments
28    /// * `opponent_ratings: Vec<f32>` - All the opponent's ratings without the index.
29    /// * `scored: f32` - The scored points. 1 is a win, 0.5 a draw and 0 a loss.
30    /// # Examples
31    /// ```
32    /// use lib_rapid::math::ratings::elo::player::EloPlayer;
33    /// 
34    /// let mut player = EloPlayer::new((2306.0, 32), 43);
35    /// player.update_rating(2077.0, 0.0);
36    /// 
37    /// assert_eq!(2290.0, player.elo.0.round());
38    /// ```
39    pub fn update_rating(&mut self, opponent_rating: f32, scored: f32) {
40        self.update_k_factor();
41
42        let expected = (1.0+10.0_f32.powf((opponent_rating - self.elo.0) / 400.0)).recip();
43        
44        self.elo.0 = self.elo.0 + self.k_factor as f32 * (scored - expected);
45        self.elo.1.inc();
46    }
47
48    fn update_k_factor(&mut self) {
49        if (self.age >= 18 && self.elo.0 < 2300.0) || self.elo.1 < 30
50        { self.k_factor = 40; }
51        else if self.elo.0 < 2400.0 && self.elo.1 >= 30
52        { self.k_factor = 20; }
53        else
54        { self.k_factor = 10; }
55    }
56}