From cbfa35c9a4195cf18b34ee94be13856238bcdd66 Mon Sep 17 00:00:00 2001 From: atomflunder <80397293+atomflunder@users.noreply.github.com> Date: Thu, 25 Aug 2022 13:33:59 +0200 Subject: [PATCH] Add new and default for DWZRating --- CHANGELOG.md | 5 +++++ Cargo.toml | 2 +- README.md | 4 ++-- src/config.rs | 8 ++++---- src/dwz.rs | 14 +++++++++++-- src/glicko2.rs | 2 +- src/ingo.rs | 1 - src/lib.rs | 2 +- src/outcomes.rs | 5 +++-- src/rating.rs | 53 +++++++++++++++++++++++++++++++++--------------- src/trueskill.rs | 2 +- 11 files changed, 67 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb8d200..0288bd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ This is a broad overview of the changes that have been made over the lifespan of this library. +## v0.11.0 - 2022-08-26 + +- Add `new` and `default` implementations for `DWZRating` +- `new` implementation for `IngoRating` now requires an age to be set + ## v0.10.2 - 2022-08-25 - Fix typos diff --git a/Cargo.toml b/Cargo.toml index cd23e51..bebee5e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "skillratings" -version = "0.10.2" +version = "0.11.0" edition = "2021" description = "Calculate a player's skill rating using Elo, DWZ, Ingo, TrueSkill, Glicko and Glicko-2 algorithms." readme= "README.md" diff --git a/README.md b/README.md index 6b55db6..5d0c547 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![](https://codecov.io/gh/atomflunder/skillratings/branch/master/graph/badge.svg?token=JFSA86GAX1)](https://codecov.io/gh/atomflunder/skillratings) [![](https://img.shields.io/crates/d/skillratings)](https://crates.io/crates/skillratings) -Skillratings allows you to calculate the player's skill instantly or after tournaments/rating periods with a list of results using a variety of known and lesser known skill rating algorithms. +Skillratings allows you to calculate the player's skill instantly, or after tournaments/rating periods with a list of results using a variety of known and lesser known skill rating algorithms. Currently supported algorithms: @@ -24,7 +24,7 @@ Add the following to your `Cargo.toml` file: ```toml [dependencies] -skillratings = "0.10.2" +skillratings = "0.11.0" ``` ## Basic Usage diff --git a/src/config.rs b/src/config.rs index 9b966c5..e409cbf 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,6 +1,6 @@ //! Contains structs to configure key variables used in the different rating algorithms. -/// Constants used in the `Elo` calculation. +/// Constants used in the Elo calculation. pub struct EloConfig { /// The k-value is the maximum amount of rating change from a single match. /// In chess, k-values from 40 to 10 are used, with the most common being 32, 24, 16 or 10. @@ -23,7 +23,7 @@ impl Default for EloConfig { } } -/// Constants used in the `Glicko` calculation. +/// Constants used in the Glicko calculation. pub struct GlickoConfig { /// The c value describes how much the rating deviation should decay in each step. /// The higher the value, the more the rating deviation will decay. @@ -46,7 +46,7 @@ impl Default for GlickoConfig { } } -/// Constants used in the `Glicko-2` calculation. +/// Constants used in the Glicko-2 calculation. pub struct Glicko2Config { /// The tau constant constrains the change in volatility over time. /// To cite Mark Glickman himself: "Reasonable choices are between 0.3 and 1.2". @@ -76,7 +76,7 @@ impl Default for Glicko2Config { } } -/// Constants used in the `TrueSkill` calculation. +/// Constants used in the TrueSkill calculation. pub struct TrueSkillConfig { /// The probability of draws occurring in match. /// The higher the probability, the bigger the updates to the ratings in a non-drawn outcome. diff --git a/src/dwz.rs b/src/dwz.rs index a67534f..30d93ae 100644 --- a/src/dwz.rs +++ b/src/dwz.rs @@ -230,8 +230,9 @@ pub fn expected_score(player_one: DWZRating, player_two: DWZRating) -> (f64, f64 #[must_use] /// Gets a proper first [`DWZRating`]. /// -/// If you do not have enough opponents, and have an [`EloRating`](crate::rating::EloRating) -/// consider using [`DWZRating::from()`](DWZRating#impl-From). +/// In the case that you do not have enough opponents to rate a player against, +/// consider using [`DWZRating::from()`](DWZRating) if you have an [`EloRating`](crate::rating::EloRating) +/// or [`DWZRating::new()`](DWZRating) if not. /// /// Takes in the player's age and their results as a Vec of tuples containing the opponent and the outcome. /// If the actual player's age is unavailable or unknown, choose something `>25`. @@ -780,4 +781,13 @@ mod tests { assert_eq!(player_one_dwz.index, 6); assert_eq!(player_one_dwz.age, 26); } + + #[test] + fn default_new() { + let player_one = DWZRating::default(); + + let player_two = DWZRating::new(26); + + assert_eq!(player_one, player_two); + } } diff --git a/src/glicko2.rs b/src/glicko2.rs index 24f8d2b..7668f6a 100644 --- a/src/glicko2.rs +++ b/src/glicko2.rs @@ -1,7 +1,7 @@ //! The Glicko-2 algorithm, an improvement on Glicko and widely used in online games, //! like Counter Strike: Global Offensive, Team Fortress 2, Splatoon 2 and most online chess platforms. //! -//! //! For Glicko, please see [`crate::glicko`]. +//! For Glicko, please see [`crate::glicko`]. //! //! The main improvement over Glicko is the rating volatility which is the expected fluctuation of a players rating, //! based on how consistent a player is performing. The lower the volatility, the more consistent a player performs. diff --git a/src/ingo.rs b/src/ingo.rs index ae0c5c1..c4699fd 100644 --- a/src/ingo.rs +++ b/src/ingo.rs @@ -5,7 +5,6 @@ //! and negative values are possible, though unlikely. //! A player with an Ingo rating of 0 has an equivalent Elo rating of 2840, and an Ingo rating of -1 equals 2848 Elo. //! -//! //! # More Information //! //! - [Wikipedia Article (German, no english version available)](https://de.wikipedia.org/wiki/Ingo-Zahl) diff --git a/src/lib.rs b/src/lib.rs index 61c05bf..528213e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,7 +28,7 @@ //! Add the following to your `Cargo.toml` file: //! ```toml //! [dependencies] -//! skillratings = "0.10.2" +//! skillratings = "0.11.0" //! ``` //! //! # Examples and Usage diff --git a/src/outcomes.rs b/src/outcomes.rs index 797efc6..872de5c 100644 --- a/src/outcomes.rs +++ b/src/outcomes.rs @@ -1,8 +1,9 @@ //! The possible outcomes of a match. /// The possible outcomes for a match: Win, Draw, Loss. -/// Note that this is always from the perspective of player one. -/// So a win is a win for player one and a loss is a win for player two. +/// +/// Note that this is always from the perspective of player one. +/// That means a win is a win for player one and a loss is a win for player two. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum Outcomes { diff --git a/src/rating.rs b/src/rating.rs index f931319..bc21a94 100644 --- a/src/rating.rs +++ b/src/rating.rs @@ -32,7 +32,9 @@ impl From for EloRating { } #[derive(Copy, Clone, Debug, PartialEq)] -/// The Glicko rating for a player. **For the glicko-2 rating, please see [`Glicko2Rating`]**. +/// The Glicko rating for a player. +/// +/// For the Glicko-2 rating, please see [`Glicko2Rating`]. /// /// The default rating is 1500.0. /// The default deviation is 350.0. @@ -62,6 +64,8 @@ impl Default for GlickoRating { /// The Glicko-2 rating of a player. /// +/// For the Glicko rating, please see [`GlickoRating`]. +/// /// The default rating is 1500.0. /// The default deviation is 350.0. /// The default volatility is 0.06. @@ -96,13 +100,10 @@ impl Default for Glicko2Rating { #[derive(Copy, Clone, Debug, PartialEq)] /// The DWZ (Deutsche Wertungszahl) rating for a player. /// -/// Note there is no default value for this, -/// you either have to convert an existing [`EloRating`] -/// using `DWZRating::from(EloRating { ... })`, -/// or use the [`crate::dwz::get_first_dwz`] function. -/// /// The age is the actual age of the player, if unsure or unavailable set this to `>25`. -/// Using `from` will set the age to 26. +/// Converting from an `EloRating` or using `DWZRating::default()` will set the age to 26. +/// +/// The default rating is 1000.0. pub struct DWZRating { /// The player's DWZ rating number. pub rating: f64, @@ -112,6 +113,25 @@ pub struct DWZRating { pub age: usize, } +impl DWZRating { + #[must_use] + /// Initialize a new `DWZRating` with a rating of 1000.0, an index of 1 and the specified age. + /// The age is the actual age of the player, if unsure or unavailable set this to `>25`. + pub const fn new(age: usize) -> Self { + Self { + rating: 1000.0, + index: 1, + age, + } + } +} + +impl Default for DWZRating { + fn default() -> Self { + Self::new(26) + } +} + impl From for DWZRating { fn from(e: EloRating) -> Self { Self { @@ -123,7 +143,7 @@ impl From for DWZRating { } #[derive(Copy, Clone, Debug, PartialEq)] -/// The `TrueSkill` rating of a player. +/// The TrueSkill rating of a player. /// /// The default rating is 25.0. /// The default uncertainty is 25/3 ≈ 8.33. @@ -154,9 +174,12 @@ impl Default for TrueSkillRating { #[derive(Copy, Clone, Debug, PartialEq)] /// The Ingo rating of a player. /// -/// Note that unlike in the other systems, a lower score is better than a higher score. +/// Note that unlike in the other systems, a lower score is better than a higher score. /// Negative values are possible. /// +/// The age is the actual age of the player, if unsure or unavailable set this to `>25`. +/// Converting from an `EloRating` or using `IngoRating::default()` will set the age to 26. +/// /// The default rating is 230.0. pub struct IngoRating { /// The rating value for a player, by default 230.0. @@ -168,18 +191,16 @@ pub struct IngoRating { impl IngoRating { #[must_use] - /// Initialize a new `IngoRating` with a rating of 230.0 - pub const fn new() -> Self { - Self { - rating: 230.0, - age: 26, - } + /// Initialize a new `IngoRating` with a rating of 230.0 and the given age. + /// The age is the actual age of the player, if unsure or unavailable set this to `>25`. + pub const fn new(age: usize) -> Self { + Self { rating: 230.0, age } } } impl Default for IngoRating { fn default() -> Self { - Self::new() + Self::new(26) } } diff --git a/src/trueskill.rs b/src/trueskill.rs index 3b9812b..476cd99 100644 --- a/src/trueskill.rs +++ b/src/trueskill.rs @@ -562,7 +562,7 @@ pub fn expected_score( clippy::as_conversions, clippy::cast_precision_loss )] -/// Calculates the expected outcome of two teams based on `TrueSkill`. +/// Calculates the expected outcome of two teams based on TrueSkill. /// /// Takes in two teams as Vec of [`TrueSkillRating`]s and returns the probability of victory for each player as an [`f64`] between 1.0 and 0.0. /// 1.0 means a certain victory for the player, 0.0 means certain loss.