Crate bbt

Crate bbt 

Source
Expand description

BBT is an implementation of a skill-rating system similar to Elo, Glicko or TrueSkill. It follows Algorithm 1 from the paper A Bayesian Approximation Method for Online Ranking.

§Usage

As a first step, you need to instantiate a Rater:

let rater = bbt::Rater::new(25.0/6.0);

The new() function takes one parameter, β. This parameter describes how much randomness (variance in outcomes) your game has. For example, a game like Hearthstone is much more luck-based than chess and should have a higher variance; you may need to experiment to see which value has the highest predictive power.

§Two-player games (e.g. Chess)

BBT has a convenience function for two-player games that updates the ratings for the two players in place after a game. In the example, p1 wins against p2:

let rater = bbt::Rater::default();

let mut p1 = bbt::Rating::default();
let mut p2 = bbt::Rating::default();

rater.duel(&mut p1, &mut p2, bbt::Outcome::Win);

The bbt::Outcome enum can take on the values Win, Loss and Draw.

§Multiplayer games

Games with more than two players will have to use the general update_ratings method. It takes mutable slices of teams and a container of ranks, with each team being a mutable slice of (mutable) player ratings. The ratings are updated in place.

§Example 1: Racing Game

In a racing game without teams, each player is represented as a “team” of one, and since there are usually no ties in a racing game, the list of ranks contains no duplicates:

let rater = bbt::Rater::default();

let mut p1 = bbt::Rating::default();
let mut p2 = bbt::Rating::default();
let mut p3 = bbt::Rating::default();
let mut p4 = bbt::Rating::default();
let mut p5 = bbt::Rating::default();
let mut p6 = bbt::Rating::default();

let mut team1 = [&mut p1]; let mut team2 = [&mut p2]; let mut team3 = [&mut p3];
let mut team4 = [&mut p4]; let mut team5 = [&mut p5]; let mut team6 = [&mut p6];
let mut teams = [&mut team1[..], &mut team2[..], &mut team3[..], &mut team4[..], &mut team5[..], &mut team6[..]];

rater.update_ratings(&mut teams, [1, 2, 3, 4, 5, 6]).unwrap();

In the example, the first player places first, the second player second, and so on.

§Example 2: Tied Teams

Let’s say you have a hypothetical game with four teams and two players per team.

Team 1Team 2Team 3Team 4
AliceCharlieEveGabe
BobDaveFredHenry

If Team 1 wins, and Team 2 and 3 draw for second place and Team 4 loses, you can call the update_ratings function as follows:

let rater = bbt::Rater::default();

let mut alice   = bbt::Rating::default();
let mut bob     = bbt::Rating::default();
let mut charlie = bbt::Rating::default();
let mut dave    = bbt::Rating::default();
let mut eve     = bbt::Rating::default();
let mut fred    = bbt::Rating::default();
let mut gabe    = bbt::Rating::default();
let mut henry   = bbt::Rating::default();

let mut team1 = [&mut alice, &mut bob]; let mut team2 = [&mut charlie, &mut dave];
let mut team3 = [&mut eve, &mut fred]; let mut team4 = [&mut gabe, &mut henry];
let mut teams = [&mut team1[..], &mut team2[..], &mut team3[..], &mut team4[..]];

rater.update_ratings(&mut teams, [1, 2, 2, 4]).unwrap();

The second argument assigns a rank to the teams given in the first argument. Team 1 placed first, teams 2 and 3 tie for second place and team 4 comes in fourth.

§Rating scale

The default rating scale follows TrueSkill’s convention of ranks from 0 to 50. You should be able to use a different scale by specifying the middle of that scale in Rating::new(). For example, to use a more traditional scale of 0 to 3000, you can initialize ratings with Rating::new(1500.0, 1500.0/3.0). You’ll also need to adjust the β-value of the Rater instance accordingly: Rater::new(1500.0/6.0).

Structs§

Rater
Rater is used to calculate rating updates given the β-parameter.
Rating
Rating represents the skill of a player.

Enums§

BBTError
Error type for BBT rating calculation
Outcome
Outcome represents the outcome of a head-to-head duel between two players.