Skip to content

Commit

Permalink
Add sticko calculations
Browse files Browse the repository at this point in the history
  • Loading branch information
atomflunder committed Oct 12, 2022
1 parent 9949992 commit 33d65c1
Show file tree
Hide file tree
Showing 10 changed files with 772 additions and 13 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.14.0 - 2022-10-13

- Add Sticko rating algorithm

## v0.13.4 - 2022-10-03

- Improve performance of some functions
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.13.4"
version = "0.14.0"
edition = "2021"
description = "Calculate a player's skill rating using algorithms like Elo, Glicko, Glicko-2, TrueSkill and many more."
readme = "README.md"
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Currently supported algorithms:
- [Glicko-2](https://docs.rs/skillratings/latest/skillratings/glicko2/index.html)
- [TrueSkill](https://docs.rs/skillratings/latest/skillratings/trueskill/index.html)
- [Weng-Lin (Bayesian Approxmation Method)](https://docs.rs/skillratings/latest/skillratings/weng_lin/index.html)
- [Sticko (Stephenson Rating System)](https://docs.rs/skillratings/latest/skillratings/sticko/index.html)
- [DWZ (Deutsche Wertungszahl)](https://docs.rs/skillratings/latest/skillratings/dwz/index.html)
- [Ingo](https://docs.rs/skillratings/latest/skillratings/ingo/index.html)

Expand All @@ -32,7 +33,7 @@ Alternatively, you can add the following to your `Cargo.toml` file manually:

```toml
[dependencies]
skillratings = "0.13"
skillratings = "0.14"
```

## Usage and Examples
Expand Down
67 changes: 63 additions & 4 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -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 calculations.
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.
Expand All @@ -23,7 +23,7 @@ impl Default for EloConfig {
}
}

/// Constants used in the Glicko calculation.
/// Constants used in the Glicko calculations.
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.
Expand All @@ -46,7 +46,7 @@ impl Default for GlickoConfig {
}
}

/// Constants used in the Glicko-2 calculation.
/// Constants used in the Glicko-2 calculations.
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".
Expand Down Expand Up @@ -76,7 +76,7 @@ impl Default for Glicko2Config {
}
}

/// Constants used in the TrueSkill calculation.
/// Constants used in the TrueSkill calculations.
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.
Expand Down Expand Up @@ -147,3 +147,62 @@ impl Default for WengLinConfig {
Self::new()
}
}

/// Constants used in the Sticko calculations.
/// If all of these are set to `0.0`, this will behave exactly like the [`Glicko`](crate::glicko::glicko) calculations.
pub struct StickoConfig {
/// Controls player deviations across time.
/// The higher this number, the higher the deviation is going to be.
/// By default set to `10.0`.
/// If you want to mimic the [`GlickoConfig`], set this to `0.0`.
/// Do not set this to a negative value.
pub h: f64,
/// A bonus parameter, which gives a rating boost for just participating.
/// Note that setting this to a positive number will create rating inflation over time.
/// By default set to `0.0`.
/// If you want to mimic the [`GlickoConfig`], set this to `0.0`.
/// Do not set this to a negative value.
pub beta: f64,
/// The neighborhood parameter, which shrinks player ratings towards their opponent.
/// By default set to `2.0`.
/// If you want to mimic the [`GlickoConfig`], set this to `0.0`.
/// Do not set this to a negative value.
pub lambda: f64,
/// The advantage parameter of the first player.
/// If your game is biased towards player one set this to a positive number,
/// or set this to a negative number if the second player has an advantage.
/// With this you could represent the advantage of playing white in chess,
/// or home-team advantage in sports like football and so on.
/// In chess, a value of `30.0` seems to be about correct.
/// By default set to `0.0`.
/// If you want to mimic the [`GlickoConfig`], set this to `0.0`.
pub gamma: f64,
/// 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.
/// This is similar to the c value in [`GlickoConfig`].
/// Keep in mind this needs to be set lower than the c in the [`GlickoConfig`] if the h value here is not equal to zero.
/// By default set to `10.0`.
/// If you want to mimic the [`GlickoConfig`] set this to `63.2`.
pub c: f64,
}

impl StickoConfig {
#[must_use]
/// Initialize a new `StickoConfig` with a h value of `10.0`, a beta value of `0.0`,
/// a lambda value of `2.0` and a gamma value of `0.0`.
pub const fn new() -> Self {
Self {
h: 10.0,
beta: 0.0,
lambda: 2.0,
gamma: 0.0,
c: 10.0,
}
}
}

impl Default for StickoConfig {
fn default() -> Self {
Self::new()
}
}
4 changes: 2 additions & 2 deletions src/glicko.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! 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.
//!
//! If you are looking for the updated Glicko-2 rating system, please see [`crate::glicko2`].
//! If you are looking for the updated Glicko-2 rating system, please see [`Glicko-2`](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.
Expand Down Expand Up @@ -48,7 +48,7 @@ use std::f64::consts::PI;
#[must_use]
/// 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.
/// Please see [`Glicko-2`](crate::glicko2) for calculating with the improved version.
///
/// Takes in two players as [`GlickoRating`]s, and an [`Outcome`](Outcomes).
///
Expand Down
4 changes: 2 additions & 2 deletions src/glicko2.rs
Original file line number Diff line number Diff line change
@@ -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.
//!
//! If you are looking for the regular Glicko rating system, please see [`crate::glicko`].
//! If you are looking for the regular Glicko rating system, please see [`Glicko`](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.
Expand Down Expand Up @@ -49,7 +49,7 @@ use std::f64::consts::PI;

/// Calculates the [`Glicko2Rating`]s of two players based on their old ratings, deviations, volatilities, and the outcome of the game.
///
/// For the original version, please see [`crate::glicko::glicko`].
/// For the original version, please see [`Glicko`](crate::glicko).
///
/// Takes in two players as [`Glicko2Rating`]s, an [`Outcome`](Outcomes), and a [`Glicko2Config`].
///
Expand Down
6 changes: 4 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
//! - **[`Glicko-2`](crate::glicko2)**
//! - **[`TrueSkill`](crate::trueskill)**
//! - **[`Weng-Lin`](crate::weng_lin)**
//! - **[`Sticko`](crate::sticko)**
//! - **[`DWZ (Deutsche Wertungszahl)`](crate::dwz)**
//! - **[`Ingo`](crate::ingo)**
//!
Expand All @@ -28,15 +29,15 @@
//!
//! If you are on Rust 1.62 or higher use `cargo add` to install the latest version:
//!
//! ```ignore
//! ```bash
//! cargo add skillratings
//! ```
//!
//! Alternatively, you can add the following to your `Cargo.toml` file manually:
//!
//! ```toml
//! [dependencies]
//! skillratings = "0.13"
//! skillratings = "0.14"
//! ```
//!
//! # Examples
Expand Down Expand Up @@ -200,5 +201,6 @@ pub mod glicko2;
pub mod ingo;
pub mod outcomes;
pub mod rating;
pub mod sticko;
pub mod trueskill;
pub mod weng_lin;
68 changes: 68 additions & 0 deletions src/rating.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ impl From<Glicko2Rating> for GlickoRating {
}
}

impl From<StickoRating> for GlickoRating {
fn from(s: StickoRating) -> Self {
Self {
rating: s.rating,
deviation: s.deviation,
}
}
}

/// The Glicko-2 rating of a player.
///
/// For the Glicko rating, please see [`GlickoRating`].
Expand Down Expand Up @@ -122,6 +131,16 @@ impl From<GlickoRating> for Glicko2Rating {
}
}

impl From<StickoRating> for Glicko2Rating {
fn from(s: StickoRating) -> Self {
Self {
rating: s.rating,
deviation: s.deviation,
..Default::default()
}
}
}

#[derive(Copy, Clone, Debug, PartialEq)]
/// The DWZ (Deutsche Wertungszahl) rating for a player.
///
Expand Down Expand Up @@ -287,3 +306,52 @@ impl From<TrueSkillRating> for WengLinRating {
}
}
}

#[derive(Copy, Clone, Debug, PartialEq)]
/// The Sticko rating of a player.
///
/// Similar to [`GlickoRating`].
///
/// The default rating is 1500.0.
/// The default deviation is 350.0.
pub struct StickoRating {
/// The player's Sticko rating number, by default 1500.0.
pub rating: f64,
/// The player's Sticko deviation number, by default 350.0.
pub deviation: f64,
}

impl StickoRating {
#[must_use]
/// Initialize a new `GlickoRating` with a rating of 1500.0 and a deviation of 350.0.
pub const fn new() -> Self {
Self {
rating: 1500.0,
deviation: 350.0,
}
}
}

impl Default for StickoRating {
fn default() -> Self {
Self::new()
}
}

impl From<GlickoRating> for StickoRating {
fn from(g: GlickoRating) -> Self {
Self {
rating: g.rating,
deviation: g.deviation,
}
}
}

impl From<Glicko2Rating> for StickoRating {
fn from(g: Glicko2Rating) -> Self {
Self {
rating: g.rating,
deviation: g.deviation,
}
}
}
Loading

0 comments on commit 33d65c1

Please sign in to comment.