skillratings 0.11.0

Calculate a player's skill rating using Elo, DWZ, Ingo, TrueSkill, Glicko and Glicko-2 algorithms.
Documentation

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.

Currently supported algorithms:

They are mainly known from their usage in chess and online games.

Installation

Add the following to your Cargo.toml file:

[dependencies]

skillratings = "0.11.0"

Basic Usage

Below is the most basic use case for each supported algorithm, in a 1-vs-1 format.
Each rating algorithm has many more associated functions, for example getting a rating using a list of outcomes or getting expected scores.

Head over to the documentation for more information.

Elo rating system

extern crate skillratings;

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

let player_one = EloRating { rating: 1000.0 };
let player_two = EloRating { rating: 1000.0 };

// The outcome is from the perspective of player one.
let outcome = Outcomes::WIN;

// The config allows you to change certain adjustable values in the algorithms.
let config = EloConfig::new();

let (player_one_new, player_two_new) = elo(player_one, player_two, outcome, &config);
assert!((player_one_new.rating - 1016.0).abs() < f64::EPSILON);
assert!((player_two_new.rating - 984.0).abs() < f64::EPSILON);

Glicko rating system

use skillratings::{
    config::Glicko2Config, glicko::glicko, outcomes::Outcomes, rating::GlickoRating,
};


let player_one = GlickoRating {
    rating: 1500.0,
    deviation: 350.0,
};
let player_two = GlickoRating {
    rating: 1500.0,
    deviation: 350.0,
};

// The outcome is from the perspective of player one.
let outcome = Outcomes::WIN;

// The config allows you to change certain adjustable values in the algorithms.
let config = GlickoConfig::new();

let (player_one_new, player_two_new) = glicko(player_one, player_two, outcome, &config);

assert!((player_one_new.rating.round() - 1662.0).abs() < f64::EPSILON);
assert!((player_one_new.deviation.round() - 290.0).abs() < f64::EPSILON);

assert!((player_two_new.rating.round() - 1338.0).abs() < f64::EPSILON);
assert!((player_two_new.deviation.round() - 290.0).abs() < f64::EPSILON);

Glicko-2 rating system

extern crate skillratings;

use skillratings::{
    glicko2::glicko2, outcomes::Outcomes, rating::Glicko2Rating, config::Glicko2Config
};

let player_one = Glicko2Rating { 
    rating: 1500.0, 
    deviation: 350.0, 
    volatility: 0.06 
};
let player_two = Glicko2Rating { 
    rating: 1500.0, 
    deviation: 350.0, 
    volatility: 0.06 
};

// The outcome is from the perspective of player one.
let outcome = Outcomes::WIN;

// The config allows you to change certain adjustable values in the algorithms.
let config = Glicko2Config::new();

let (player_one_new, player_two_new) = glicko2(player_one, player_two, outcome, &config);

assert!((player_one_new.rating.round() - 1662.0).abs() < f64::EPSILON);
assert!((player_one_new.deviation.round() - 290.0).abs() < f64::EPSILON);

assert!((player_two_new.rating.round() - 1338.0).abs() < f64::EPSILON);
assert!((player_two_new.deviation.round() - 290.0).abs() < f64::EPSILON);

TrueSkill rating system

Caution regarding usage of TrueSkill: Microsoft permits only Xbox Live games or non-commercial projects to use TrueSkill(TM). If your project is commercial, you should use another rating system included here.

use skillratings::{
    trueskill::trueskill, outcomes::Outcomes, rating::TrueSkillRating, config::TrueSkillConfig
};

let player_one = TrueSkillRating{
    rating: 25.0,
    uncertainty: 8.333,
};
let player_two = TrueSkillRating {
    rating: 30.0,
    uncertainty: 1.2,
};

// The config allows you to change certain adjustable values in the algorithms.
let config = TrueSkillConfig::new();

// The outcome is from the perspective of player one.
let outcome = Outcomes::WIN;

let (p1, p2) = trueskill(player_one, player_two, outcome, &config);

assert!(((p1.rating * 100.0).round() - 3300.0).abs() < f64::EPSILON);
assert!(((p1.uncertainty * 100.0).round() - 597.0).abs() < f64::EPSILON);

assert!(((p2.rating * 100.0).round() - 2983.0).abs() < f64::EPSILON);
assert!(((p2.uncertainty * 100.0).round() - 120.0).abs() < f64::EPSILON);

DWZ (Deutsche Wertungszahl) rating system

use skillratings::{dwz::dwz, outcomes::Outcomes, rating::DWZRating};

let player_one = DWZRating {
    rating: 1500.0,
    index: 42,
    // The actual age of the player, if unavailable set this to >25.
    // The lower the age, the more the rating will fluctuate.
    age: 42,
};
let player_two = DWZRating {
    rating: 1500.0,
    index: 12,
    age: 12,
};

// The outcome is from the perspective of player one.
let outcome = Outcomes::WIN;

let (player_one_new, player_two_new) = dwz(player_one, player_two, outcome);

assert!((player_one_new.rating.round() - 1519.0).abs() < f64::EPSILON);
assert_eq!(player_one_new.index, 43);

assert!((player_two_new.rating.round() - 1464.0).abs() < f64::EPSILON);
assert_eq!(player_two_new.index, 13);

Ingo rating system

use skillratings::{ingo::ingo, outcomes::Outcomes, rating::IngoRating};

let player_one = IngoRating {
    // Note that a lower rating is more desirable.
    rating: 130.0,
    // The actual age of the player, if unavailable set this to >25.
    // The lower the age, the more the rating will fluctuate.
    age: 40,
};
let player_two = IngoRating {
    rating: 160.0,
    age: 40,
};

// The outcome is from the perspective of player one.
let outcome = Outcomes::WIN;

let (p1, p2) = ingo(player_one, player_two, outcome);

assert!((p1.rating.round() - 129.0).abs() < f64::EPSILON);
assert!((p2.rating.round() - 161.0).abs() < f64::EPSILON);

License

This project is licensed under the MIT License.