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}