Skip to content

Commit

Permalink
Overhauled documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
atomflunder committed Aug 24, 2022
1 parent 80232b2 commit fed5bd3
Show file tree
Hide file tree
Showing 13 changed files with 254 additions and 140 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

This is a broad overview of the changes that have been made over the lifespan of this library.

## v0.10.1 - 2022-08-25

- Overhauled documentation

## v0.10.0 - 2022-08-24

- Add team calculations for TrueSkill
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "skillratings"
version = "0.10.0"
version = "0.10.1"
edition = "2021"
description = "Calculate a player's skill rating using Elo, DWZ, Ingo, TrueSkill, Glicko and Glicko-2 algorithms."
readme= "README.md"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Add the following to your `Cargo.toml` file:

```toml
[dependencies]
skillratings = "0.10.0"
skillratings = "0.10.1"
```

## Basic Usage
Expand Down
4 changes: 3 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
//! Contains structs to configure key variables used in the different rating algorithms.

/// 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 or 16.
/// In chess, k-values from 40 to 10 are used, with the most common being 32, 24, 16 or 10.
/// The higher the number, the more volatile the ranking.
/// Here the default is 32.
pub k: f64,
Expand Down
47 changes: 32 additions & 15 deletions src/dwz.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
//! The DWZ (Deutsche Wertungszahl) algorithm used in the german chess leagues alongside Elo.
//! DWZ continues to be enhanced over the years, while having similar scores to Elo.
//!
//! DWZ allows young players to rise and fall in the ranks more quickly, while more experienced players ratings are slower to change.
//! Overachieving players gain more rating while underperforming weak players do not lose rating points as quickly.
//!
//! These factors make DWZ more dynamic than Elo while producing accurate ratings more quickly.
//!
//! # More Information
//!
//! - [Wikipedia Article](https://en.wikipedia.org/wiki/Deutsche_Wertungszahl)
//! - [DWZ Calculator (German)](http://www.wertungszahl.de/)
//! - [DWZ Top 100 Ratings](https://www.schachbund.de/top-100.html)
//! - [Official DWZ scoring system rules (German)](https://www.schachbund.de/wertungsordnung.html)
//! - [Probability Table](https://www.schachbund.de/wertungsordnung-anhang-2-tabellen/articles/wertungsordnung-anhang-21-wahrscheinlichkeitstabelle.html)

use std::collections::HashMap;

use crate::{outcomes::Outcomes, rating::DWZRating};

#[must_use]
/// Calculates the DWZ (Deutsche Wertungszahl) ratings of two players based on their ratings, index, age and outcome of the game.
/// Calculates new [`DWZRating`] of two players based on their old rating, index, age and outcome of the game.
///
/// Takes in two players and the outcome of the game.
/// Takes in two players as [`DWZRating`]s and an [`Outcome`](Outcomes).
///
/// Instead of the traditional way of calculating the DWZ for only one player only using a list of results,
/// we are calculating the DWZ rating for two players at once, like in the Elo calculation,
Expand All @@ -15,9 +31,9 @@ use crate::{outcomes::Outcomes, rating::DWZRating};
/// To get a first DWZ rating, please see [`get_first_dwz`].
///
/// The outcome of the match is in the perspective of `player_one`.
/// This means `Outcomes::WIN` is a win for `player_one` and `Outcomes::LOSS` is a win for `player_two`.
/// This means [`Outcomes::WIN`] is a win for `player_one` and [`Outcomes::LOSS`] is a win for `player_two`.
///
/// # Example
/// # Examples
/// ```
/// use skillratings::{dwz::dwz, outcomes::Outcomes, rating::DWZRating};
///
Expand Down Expand Up @@ -105,12 +121,13 @@ pub fn dwz(
#[must_use]
/// The "traditional" way of calculating a DWZ Rating of a player in a rating period or tournament.
///
/// Takes in a player and their results as a Vec of tuples containing the opponent and the outcome.
/// Takes in a player as an [`DWZRating`] and their results as a Vec of tuples containing the opponent as an [`DWZRating`]
/// and the outcome of the game as an [`Outcome`](Outcomes).
///
/// All of the outcomes are from the perspective of `player_one`.
/// This means `Outcomes::WIN` is a win for `player_one` and `Outcomes::LOSS` is a win for `player_two`.
/// All of the outcomes are from the perspective of the player.
/// This means [`Outcomes::WIN`] is a win for the player and [`Outcomes::LOSS`] is a win for the opponent.
///
/// # Example
/// # Examples
/// ```
/// use skillratings::{dwz::dwz_rating_period, outcomes::Outcomes, rating::DWZRating};
///
Expand Down Expand Up @@ -175,11 +192,11 @@ pub fn dwz_rating_period(player: DWZRating, results: &Vec<(DWZRating, Outcomes)>
#[must_use]
/// Calculates the expected outcome of two players based on DWZ.
///
/// Takes in two players and returns the probability of victory for each player.
/// Takes in two players as [`DWZRating`]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.
/// Values near 0.5 mean a draw is likely to occur.
///
/// # Example
/// # Examples
/// ```
/// use skillratings::{dwz::expected_score, rating::DWZRating};
///
Expand Down Expand Up @@ -211,18 +228,18 @@ pub fn expected_score(player_one: DWZRating, player_two: DWZRating) -> (f64, f64

#[allow(clippy::as_conversions, clippy::cast_precision_loss)]
#[must_use]
/// Gets a proper first DWZ rating.
/// Gets a proper first [`DWZRating`].
///
/// If you do not have enough opponents, and have an [`crate::rating::EloRating`]
/// consider using `DWZRating::from(EloRating { ... })`.
/// If you do not have enough opponents, and have an [`EloRating`](crate::rating::EloRating)
/// consider using [`DWZRating::from()`](DWZRating#impl-From<EloRating>).
///
/// 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`.
///
/// This only returns a DWZ rating if the results include at least 5 matches,
/// and you don't have a 100% or a 0% win record. Otherwise it will return `None`.
/// and you don't have a 100% or a 0% win record. Otherwise it will return [`None`].
///
/// # Example
/// # Examples
/// ```
/// use skillratings::{dwz::get_first_dwz, outcomes::Outcomes, rating::DWZRating};
///
Expand Down
42 changes: 29 additions & 13 deletions src/elo.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
//! he Elo algorithm, the most widespread rating system and the gold-standard in chess and other games.
//! Used in the official FIDE chess ratings, FIFA World Rankings, and many online video games.
//!
//! The higher the Elo rating number, the stronger the player.
//! Compared to other rating algorithms, Elo ratings are relatively static, but very transparent and simple to calculate.
//!
//! # More Information
//!
//! - [Wikipedia Article](https://en.wikipedia.org/wiki/Elo_rating_system)
//! - [Elo Calculator](https://www.omnicalculator.com/sports/elo)
//! - [FIDE Ratings](https://ratings.fide.com/)
//! - [FIFA Ratings](https://www.fifa.com/fifa-world-ranking)

use crate::{config::EloConfig, outcomes::Outcomes, rating::EloRating};

/// Calculates the elo scores of two players based on their ratings and the outcome of the game.
/// Calculates the [`EloRating`]s of two players based on their old ratings and the outcome of the game.
///
/// Takes in two players, the outcome of the game and an [`EloConfig`].
/// Takes in two players as [`EloRating`]s, an [`Outcome`](Outcomes) and an [`EloConfig`].
///
/// The outcome of the match is in the perspective of `player_one`.
/// This means `Outcomes::WIN` is a win for `player_one` and `Outcomes::LOSS` is a win for `player_two`.
/// This means [`Outcomes::WIN`] is a win for `player_one` and [`Outcomes::LOSS`] is a win for `player_two`.
///
/// # Example
/// # Examples
/// ```
/// use skillratings::{elo::elo, outcomes::Outcomes, rating::EloRating, config::EloConfig};
///
Expand All @@ -25,7 +38,8 @@ use crate::{config::EloConfig, outcomes::Outcomes, rating::EloRating};
/// ```
///
/// # More
/// [Wikipedia Article on the Elo system](https://en.wikipedia.org/wiki/Elo_rating_system).
/// [Wikipedia Article on the Elo system](https://en.wikipedia.org/wiki/Elo_rating_system)
/// [Elo Calculator](https://www.omnicalculator.com/sports/elo)
#[must_use]
pub fn elo(
player_one: EloRating,
Expand Down Expand Up @@ -56,15 +70,16 @@ pub fn elo(
)
}

/// Calculates a Elo Rating in a non-traditional way using a rating period,
/// Calculates an [`EloRating`] in a non-traditional way using a rating period,
/// for compatibility with the other algorithms.
///
/// Takes in a player and their results as a Vec of tuples containing the opponent and the outcome.
/// Takes in a player as an [`EloRating`] and their results as a Vec of tuples containing the opponent as an [`EloRating`]
/// and the outcome of the game as an [`Outcome`](Outcomes).
///
/// All of the outcomes are from the perspective of `player_one`.
/// This means `Outcomes::WIN` is a win for `player_one` and `Outcomes::LOSS` is a win for `player_two`.
/// All of the outcomes are from the perspective of the player.
/// This means [`Outcomes::WIN`] is a win for the player and [`Outcomes::LOSS`] is a win for the opponent.
///
/// # Example
/// # Examples
/// ```
/// use skillratings::{elo::elo_rating_period, outcomes::Outcomes, rating::EloRating, config::EloConfig};
///
Expand Down Expand Up @@ -112,10 +127,11 @@ pub fn elo_rating_period(
/// Calculates the expected score of two players based on their elo rating.
/// Meant for usage in the elo function, but you can also use it to predict games yourself.
///
/// Takes in two elo scores and returns the expected score of each player.
/// A score of 1.0 means certain win, a score of 0.0 means certain loss, and a score of 0.5 is a draw.
/// Takes in two players as [`EloRating`]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.
/// Values near 0.5 mean a draw is likely to occur.
///
/// # Example
/// # Examples
/// ```
/// use skillratings::{elo::expected_score, rating::EloRating};
///
Expand Down
47 changes: 33 additions & 14 deletions src/glicko.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
//! The Glicko algorithm, developed by Mark Glickman as an improvement on Elo.
//! It is still being used in some games in favor Glicko-2, such as Pokémon Showdown and Quake Live.
//!
//! For Glicko-2, please see [`crate::glicko2`].
//!
//! The main improvement over Elo is the rating deviation introduced,
//! which decreases over time as the player plays more matches and the rating becomes more reliable.
//! This allows players to rise and fall through the ranks quickly at the beginning,
//! and not gain or lose as much rating points after completing more matches.
//!
//! # More Information
//!
//! - [Wikipedia Article](https://en.wikipedia.org/wiki/Glicko_rating_system)
//! - [Original Paper by Mark Glickman](http://www.glicko.net/glicko/glicko.pdf)
//! - [Glicko Calculator](http://www.bjcox.com/?page_id=2)

use crate::{config::GlickoConfig, outcomes::Outcomes, rating::GlickoRating};
use std::f64::consts::PI;

#[must_use]
/// Calculates the glicko scores of two players based on their ratings, deviations, and the outcome of the game.
/// Calculates the [`GlickoRating`]s of two players based on their old ratings, deviations, and the outcome of the game.
///
/// Please see [`crate::glicko2::glicko2`] for calculating with the improved version.
///
/// Takes in two players and the outcome of the game.
/// Takes in two players as [`GlickoRating`]s, and an [`Outcome`](Outcomes).
///
/// Instead of the traditional way of calculating the Glicko for only one player only using a list of results,
/// we are calculating the Glicko rating for two players at once, like in the Elo calculation,
Expand All @@ -15,9 +31,9 @@ use std::f64::consts::PI;
/// For the traditional way of calculating a Glicko rating please see [`glicko_rating_period`].
///
/// The outcome of the match is in the perspective of `player_one`.
/// This means `Outcomes::WIN` is a win for `player_one` and `Outcomes::LOSS` is a win for `player_two`.
/// This means [`Outcomes::WIN`] is a win for `player_one` and [`Outcomes::LOSS`] is a win for `player_two`.
///
/// # Example
/// # Examples
/// ```
/// use skillratings::{glicko::glicko, outcomes::Outcomes, rating::GlickoRating};
///
Expand Down Expand Up @@ -101,16 +117,17 @@ pub fn glicko(
)
}

/// The "traditional" way of calculating a Glicko Rating of a player in a rating period.
/// The "traditional" way of calculating a [`GlickoRating`] of a player in a rating period.
///
/// Takes in a player, their results as a Vec of tuples containing the opponent and the outcome, and a [`GlickoConfig`].
/// Takes in a player as an [`GlickoRating`] and their results as a Vec of tuples containing the opponent as an [`GlickoRating`],
/// the outcome of the game as an [`Outcome`](Outcomes) and a [`GlickoConfig`].
///
/// All of the outcomes are from the perspective of `player_one`.
/// This means `Outcomes::WIN` is a win for `player_one` and `Outcomes::LOSS` is a win for `player_two`.
/// The outcome of the match is in the perspective of the player.
/// This means [`Outcomes::WIN`] is a win for the player and [`Outcomes::LOSS`] is a win for the opponent.
///
/// If the player's results are empty, the player's rating deviation will automatically be decayed using [`decay_deviation`].
///
/// # Example
/// # Examples
/// ```
/// use skillratings::{glicko::glicko_rating_period, outcomes::Outcomes, rating::GlickoRating, config::GlickoConfig};
///
Expand Down Expand Up @@ -192,11 +209,11 @@ pub fn glicko_rating_period(
#[must_use]
/// Calculates the expected outcome of two players based on glicko.
///
/// Takes in two players and returns the probability of victory for each player.
/// Takes in two players as [`GlickoRating`]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.
/// Values near 0.5 mean a draw is likely to occur.
///
/// # Example
/// # Examples
/// ```
/// use skillratings::{glicko::expected_score, rating::GlickoRating};
///
Expand Down Expand Up @@ -227,9 +244,9 @@ pub fn expected_score(player_one: GlickoRating, player_two: GlickoRating) -> (f6
///
/// The length of the rating period and thus the number of missed periods per player is something to decide and track yourself.
///
/// Takes in a player and a [`GlickoConfig`], that describes how much the rating should change.
/// Takes in a player as a [`GlickoRating`] and a [`GlickoConfig`], that describes how much the rating should change, and returns the decayed [`GlickoRating`].
///
/// # Example
/// # Examples
/// ```
/// use skillratings::{glicko::decay_deviation, rating::GlickoRating, config::GlickoConfig};
///
Expand Down Expand Up @@ -258,7 +275,9 @@ pub fn decay_deviation(player: GlickoRating, config: &GlickoConfig) -> GlickoRat
///
/// The system is 95% sure that the "true skill" of the player is in-between these values.
///
/// # Example
/// Takes in a player as a [`GlickoRating`] and returns two [`f64`]s that describe the lowest and highest rating.
///
/// # Examples
/// ```rust
/// use skillratings::{rating::GlickoRating, glicko::confidence_interval};
///
Expand Down
Loading

0 comments on commit fed5bd3

Please sign in to comment.