refactor(api): rename Player to Rating

The struct holds prior/beta/drift — a rating configuration, not a
person. The person-with-temporal-state is the Competitor (renamed in
the next task). Resolves Player/Agent ambiguity.

Part of T2 of docs/superpowers/specs/2026-04-23-trueskill-engine-redesign-design.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-24 10:43:19 +02:00
parent 52f5f76a34
commit 2f5aa98eac
7 changed files with 72 additions and 68 deletions

View File

@@ -1,7 +1,7 @@
use criterion::{Criterion, criterion_group, criterion_main}; use criterion::{Criterion, criterion_group, criterion_main};
use trueskill_tt::{ use trueskill_tt::{
BETA, GAMMA, KeyTable, MU, P_DRAW, SIGMA, agent::Agent, batch::Batch, drift::ConstantDrift, BETA, GAMMA, KeyTable, MU, P_DRAW, Rating, SIGMA, agent::Agent, batch::Batch,
gaussian::Gaussian, player::Player, storage::AgentStore, drift::ConstantDrift, gaussian::Gaussian, storage::AgentStore,
}; };
fn criterion_benchmark(criterion: &mut Criterion) { fn criterion_benchmark(criterion: &mut Criterion) {
@@ -17,7 +17,7 @@ fn criterion_benchmark(criterion: &mut Criterion) {
agents.insert( agents.insert(
agent, agent,
Agent { Agent {
player: Player::new(Gaussian::from_ms(MU, SIGMA), BETA, ConstantDrift(GAMMA)), player: Rating::new(Gaussian::from_ms(MU, SIGMA), BETA, ConstantDrift(GAMMA)),
..Default::default() ..Default::default()
}, },
); );

View File

@@ -2,12 +2,12 @@ use crate::{
N_INF, N_INF,
drift::{ConstantDrift, Drift}, drift::{ConstantDrift, Drift},
gaussian::Gaussian, gaussian::Gaussian,
player::Player, rating::Rating,
}; };
#[derive(Debug)] #[derive(Debug)]
pub struct Agent<D: Drift = ConstantDrift> { pub struct Agent<D: Drift = ConstantDrift> {
pub player: Player<D>, pub player: Rating<D>,
pub message: Gaussian, pub message: Gaussian,
pub last_time: i64, pub last_time: i64,
} }
@@ -26,7 +26,7 @@ impl<D: Drift> Agent<D> {
impl Default for Agent<ConstantDrift> { impl Default for Agent<ConstantDrift> {
fn default() -> Self { fn default() -> Self {
Self { Self {
player: Player::default(), player: Rating::default(),
message: N_INF, message: N_INF,
last_time: i64::MIN, last_time: i64::MIN,
} }

View File

@@ -6,7 +6,7 @@ use crate::{
drift::Drift, drift::Drift,
game::Game, game::Game,
gaussian::Gaussian, gaussian::Gaussian,
player::Player, rating::Rating,
storage::{AgentStore, SkillStore}, storage::{AgentStore, SkillStore},
tuple_gt, tuple_max, tuple_gt, tuple_max,
}; };
@@ -51,16 +51,16 @@ impl Item {
forward: bool, forward: bool,
skills: &SkillStore, skills: &SkillStore,
agents: &AgentStore<D>, agents: &AgentStore<D>,
) -> Player<D> { ) -> Rating<D> {
let r = &agents[self.agent].player; let r = &agents[self.agent].player;
let skill = skills.get(self.agent).unwrap(); let skill = skills.get(self.agent).unwrap();
if online { if online {
Player::new(skill.online, r.beta, r.drift) Rating::new(skill.online, r.beta, r.drift)
} else if forward { } else if forward {
Player::new(skill.forward, r.beta, r.drift) Rating::new(skill.forward, r.beta, r.drift)
} else { } else {
Player::new(skill.posterior() / self.likelihood, r.beta, r.drift) Rating::new(skill.posterior() / self.likelihood, r.beta, r.drift)
} }
} }
} }
@@ -92,7 +92,7 @@ impl Event {
forward: bool, forward: bool,
skills: &SkillStore, skills: &SkillStore,
agents: &AgentStore<D>, agents: &AgentStore<D>,
) -> Vec<Vec<Player<D>>> { ) -> Vec<Vec<Rating<D>>> {
self.teams self.teams
.iter() .iter()
.map(|team| { .map(|team| {
@@ -400,7 +400,7 @@ mod tests {
use super::*; use super::*;
use crate::{ use crate::{
KeyTable, agent::Agent, drift::ConstantDrift, player::Player, storage::AgentStore, KeyTable, agent::Agent, drift::ConstantDrift, rating::Rating, storage::AgentStore,
}; };
#[test] #[test]
@@ -420,7 +420,7 @@ mod tests {
agents.insert( agents.insert(
agent, agent,
Agent { Agent {
player: Player::new( player: Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
@@ -496,7 +496,7 @@ mod tests {
agents.insert( agents.insert(
agent, agent,
Agent { Agent {
player: Player::new( player: Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
@@ -575,7 +575,7 @@ mod tests {
agents.insert( agents.insert(
agent, agent,
Agent { Agent {
player: Player::new( player: Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),

View File

@@ -7,13 +7,13 @@ use crate::{
drift::Drift, drift::Drift,
factor::{Factor, trunc::TruncFactor}, factor::{Factor, trunc::TruncFactor},
gaussian::Gaussian, gaussian::Gaussian,
player::Player, rating::Rating,
tuple_gt, tuple_max, tuple_gt, tuple_max,
}; };
#[derive(Debug)] #[derive(Debug)]
pub struct Game<'a, D: Drift> { pub struct Game<'a, D: Drift> {
teams: Vec<Vec<Player<D>>>, teams: Vec<Vec<Rating<D>>>,
result: &'a [f64], result: &'a [f64],
weights: &'a [Vec<f64>], weights: &'a [Vec<f64>],
p_draw: f64, p_draw: f64,
@@ -23,7 +23,7 @@ pub struct Game<'a, D: Drift> {
impl<'a, D: Drift> Game<'a, D> { impl<'a, D: Drift> Game<'a, D> {
pub fn new( pub fn new(
teams: Vec<Vec<Player<D>>>, teams: Vec<Vec<Rating<D>>>,
result: &'a [f64], result: &'a [f64],
weights: &'a [Vec<f64>], weights: &'a [Vec<f64>],
p_draw: f64, p_draw: f64,
@@ -225,16 +225,16 @@ mod tests {
use ::approx::assert_ulps_eq; use ::approx::assert_ulps_eq;
use super::*; use super::*;
use crate::{ConstantDrift, GAMMA, Gaussian, N_INF, Player, arena::ScratchArena}; use crate::{ConstantDrift, GAMMA, Gaussian, N_INF, Rating, arena::ScratchArena};
#[test] #[test]
fn test_1vs1() { fn test_1vs1() {
let t_a = Player::new( let t_a = Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
); );
let t_b = Player::new( let t_b = Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
@@ -256,12 +256,12 @@ mod tests {
assert_ulps_eq!(a, Gaussian::from_ms(20.794779, 7.194481), epsilon = 1e-6); assert_ulps_eq!(a, Gaussian::from_ms(20.794779, 7.194481), epsilon = 1e-6);
assert_ulps_eq!(b, Gaussian::from_ms(29.205220, 7.194481), epsilon = 1e-6); assert_ulps_eq!(b, Gaussian::from_ms(29.205220, 7.194481), epsilon = 1e-6);
let t_a = Player::new( let t_a = Rating::new(
Gaussian::from_ms(29.0, 1.0), Gaussian::from_ms(29.0, 1.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(GAMMA), ConstantDrift(GAMMA),
); );
let t_b = Player::new( let t_b = Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(GAMMA), ConstantDrift(GAMMA),
@@ -283,8 +283,8 @@ mod tests {
assert_ulps_eq!(a, Gaussian::from_ms(28.896475, 0.996604), epsilon = 1e-6); assert_ulps_eq!(a, Gaussian::from_ms(28.896475, 0.996604), epsilon = 1e-6);
assert_ulps_eq!(b, Gaussian::from_ms(32.189211, 6.062063), epsilon = 1e-6); assert_ulps_eq!(b, Gaussian::from_ms(32.189211, 6.062063), epsilon = 1e-6);
let t_a = Player::new(Gaussian::from_ms(1.139, 0.531), 1.0, ConstantDrift(0.2125)); let t_a = Rating::new(Gaussian::from_ms(1.139, 0.531), 1.0, ConstantDrift(0.2125));
let t_b = Player::new(Gaussian::from_ms(15.568, 0.51), 1.0, ConstantDrift(0.2125)); let t_b = Rating::new(Gaussian::from_ms(15.568, 0.51), 1.0, ConstantDrift(0.2125));
let w = [vec![1.0], vec![1.0]]; let w = [vec![1.0], vec![1.0]];
let g = Game::new( let g = Game::new(
@@ -302,17 +302,17 @@ mod tests {
#[test] #[test]
fn test_1vs1vs1() { fn test_1vs1vs1() {
let teams = vec![ let teams = vec![
vec![Player::new( vec![Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
)], )],
vec![Player::new( vec![Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
)], )],
vec![Player::new( vec![Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
@@ -367,12 +367,12 @@ mod tests {
#[test] #[test]
fn test_1vs1_draw() { fn test_1vs1_draw() {
let t_a = Player::new( let t_a = Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
); );
let t_b = Player::new( let t_b = Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
@@ -394,12 +394,12 @@ mod tests {
assert_ulps_eq!(a, Gaussian::from_ms(24.999999, 6.469480), epsilon = 1e-6); assert_ulps_eq!(a, Gaussian::from_ms(24.999999, 6.469480), epsilon = 1e-6);
assert_ulps_eq!(b, Gaussian::from_ms(24.999999, 6.469480), epsilon = 1e-6); assert_ulps_eq!(b, Gaussian::from_ms(24.999999, 6.469480), epsilon = 1e-6);
let t_a = Player::new( let t_a = Rating::new(
Gaussian::from_ms(25.0, 3.0), Gaussian::from_ms(25.0, 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
); );
let t_b = Player::new( let t_b = Rating::new(
Gaussian::from_ms(29.0, 2.0), Gaussian::from_ms(29.0, 2.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
@@ -424,17 +424,17 @@ mod tests {
#[test] #[test]
fn test_1vs1vs1_draw() { fn test_1vs1vs1_draw() {
let t_a = Player::new( let t_a = Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
); );
let t_b = Player::new( let t_b = Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
); );
let t_c = Player::new( let t_c = Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
@@ -460,17 +460,17 @@ mod tests {
assert_ulps_eq!(b, Gaussian::from_ms(25.0, 5.707424), epsilon = 1e-6); assert_ulps_eq!(b, Gaussian::from_ms(25.0, 5.707424), epsilon = 1e-6);
assert_ulps_eq!(c, Gaussian::from_ms(25.0, 5.729069), epsilon = 1e-6); assert_ulps_eq!(c, Gaussian::from_ms(25.0, 5.729069), epsilon = 1e-6);
let t_a = Player::new( let t_a = Rating::new(
Gaussian::from_ms(25.0, 3.0), Gaussian::from_ms(25.0, 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
); );
let t_b = Player::new( let t_b = Rating::new(
Gaussian::from_ms(25.0, 3.0), Gaussian::from_ms(25.0, 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
); );
let t_c = Player::new( let t_c = Rating::new(
Gaussian::from_ms(29.0, 2.0), Gaussian::from_ms(29.0, 2.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
@@ -498,29 +498,29 @@ mod tests {
#[test] #[test]
fn test_2vs1vs2_mixed() { fn test_2vs1vs2_mixed() {
let t_a = vec![ let t_a = vec![
Player::new( Rating::new(
Gaussian::from_ms(12.0, 3.0), Gaussian::from_ms(12.0, 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
), ),
Player::new( Rating::new(
Gaussian::from_ms(18.0, 3.0), Gaussian::from_ms(18.0, 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
), ),
]; ];
let t_b = vec![Player::new( let t_b = vec![Rating::new(
Gaussian::from_ms(30.0, 3.0), Gaussian::from_ms(30.0, 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
)]; )];
let t_c = vec![ let t_c = vec![
Player::new( Rating::new(
Gaussian::from_ms(14.0, 3.0), Gaussian::from_ms(14.0, 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
), ),
Player::new( Rating::new(
Gaussian::from_ms(16., 3.0), Gaussian::from_ms(16., 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
@@ -549,12 +549,12 @@ mod tests {
let w_a = vec![1.0]; let w_a = vec![1.0];
let w_b = vec![2.0]; let w_b = vec![2.0];
let t_a = vec![Player::new( let t_a = vec![Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(0.0), ConstantDrift(0.0),
)]; )];
let t_b = vec![Player::new( let t_b = vec![Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(0.0), ConstantDrift(0.0),
@@ -632,12 +632,12 @@ mod tests {
let w_a = vec![1.0]; let w_a = vec![1.0];
let w_b = vec![0.0]; let w_b = vec![0.0];
let t_a = vec![Player::new( let t_a = vec![Rating::new(
Gaussian::from_ms(2.0, 6.0), Gaussian::from_ms(2.0, 6.0),
1.0, 1.0,
ConstantDrift(0.0), ConstantDrift(0.0),
)]; )];
let t_b = vec![Player::new( let t_b = vec![Rating::new(
Gaussian::from_ms(2.0, 6.0), Gaussian::from_ms(2.0, 6.0),
1.0, 1.0,
ConstantDrift(0.0), ConstantDrift(0.0),
@@ -667,12 +667,12 @@ mod tests {
let w_a = vec![1.0]; let w_a = vec![1.0];
let w_b = vec![-1.0]; let w_b = vec![-1.0];
let t_a = vec![Player::new( let t_a = vec![Rating::new(
Gaussian::from_ms(2.0, 6.0), Gaussian::from_ms(2.0, 6.0),
1.0, 1.0,
ConstantDrift(0.0), ConstantDrift(0.0),
)]; )];
let t_b = vec![Player::new( let t_b = vec![Rating::new(
Gaussian::from_ms(2.0, 6.0), Gaussian::from_ms(2.0, 6.0),
1.0, 1.0,
ConstantDrift(0.0), ConstantDrift(0.0),
@@ -694,12 +694,12 @@ mod tests {
#[test] #[test]
fn test_2vs2_weighted() { fn test_2vs2_weighted() {
let t_a = vec![ let t_a = vec![
Player::new( Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(0.0), ConstantDrift(0.0),
), ),
Player::new( Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(0.0), ConstantDrift(0.0),
@@ -708,12 +708,12 @@ mod tests {
let w_a = vec![0.4, 0.8]; let w_a = vec![0.4, 0.8];
let t_b = vec![ let t_b = vec![
Player::new( Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(0.0), ConstantDrift(0.0),
), ),
Player::new( Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(0.0), ConstantDrift(0.0),
@@ -824,7 +824,7 @@ mod tests {
let g = Game::new( let g = Game::new(
vec![ vec![
t_a.clone(), t_a.clone(),
vec![Player::new( vec![Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(0.0), ConstantDrift(0.0),

View File

@@ -6,7 +6,7 @@ use crate::{
batch::{self, Batch}, batch::{self, Batch},
drift::{ConstantDrift, Drift}, drift::{ConstantDrift, Drift},
gaussian::Gaussian, gaussian::Gaussian,
player::Player, rating::Rating,
sort_time, sort_time,
storage::AgentStore, storage::AgentStore,
tuple_gt, tuple_max, tuple_gt, tuple_max,
@@ -267,7 +267,7 @@ impl<D: Drift> History<D> {
results: Vec<Vec<f64>>, results: Vec<Vec<f64>>,
times: Vec<i64>, times: Vec<i64>,
weights: Vec<Vec<Vec<f64>>>, weights: Vec<Vec<Vec<f64>>>,
mut priors: HashMap<Index, Player<D>>, mut priors: HashMap<Index, Rating<D>>,
) { ) {
assert!(times.is_empty() || self.time, "length(times)>0 but !h.time"); assert!(times.is_empty() || self.time, "length(times)>0 but !h.time");
assert!( assert!(
@@ -303,7 +303,7 @@ impl<D: Drift> History<D> {
*agent, *agent,
Agent { Agent {
player: priors.remove(agent).unwrap_or_else(|| { player: priors.remove(agent).unwrap_or_else(|| {
Player::new( Rating::new(
Gaussian::from_ms(self.mu, self.sigma), Gaussian::from_ms(self.mu, self.sigma),
self.beta, self.beta,
self.drift, self.drift,
@@ -437,7 +437,7 @@ mod tests {
use super::*; use super::*;
use crate::{ use crate::{
ConstantDrift, EPSILON, Game, Gaussian, ITERATIONS, KeyTable, P_DRAW, Player, ConstantDrift, EPSILON, Game, Gaussian, ITERATIONS, KeyTable, P_DRAW, Rating,
arena::ScratchArena, arena::ScratchArena,
}; };
@@ -461,7 +461,7 @@ mod tests {
for agent in [a, b, c] { for agent in [a, b, c] {
priors.insert( priors.insert(
agent, agent,
Player::new( Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(0.15 * 25.0 / 3.0), ConstantDrift(0.15 * 25.0 / 3.0),
@@ -532,7 +532,7 @@ mod tests {
for agent in [a, b, c] { for agent in [a, b, c] {
priors.insert( priors.insert(
agent, agent,
Player::new( Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(0.15 * 25.0 / 3.0), ConstantDrift(0.15 * 25.0 / 3.0),
@@ -581,7 +581,7 @@ mod tests {
for agent in [a, b, c] { for agent in [a, b, c] {
priors.insert( priors.insert(
agent, agent,
Player::new( Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),
@@ -639,7 +639,7 @@ mod tests {
for agent in [a, b, c] { for agent in [a, b, c] {
priors.insert( priors.insert(
agent, agent,
Player::new( Rating::new(
Gaussian::from_ms(25.0, 25.0 / 3.0), Gaussian::from_ms(25.0, 25.0 / 3.0),
25.0 / 6.0, 25.0 / 6.0,
ConstantDrift(25.0 / 300.0), ConstantDrift(25.0 / 300.0),

View File

@@ -16,7 +16,7 @@ pub mod gaussian;
mod history; mod history;
mod key_table; mod key_table;
mod matrix; mod matrix;
pub mod player; mod rating;
pub(crate) mod schedule; pub(crate) mod schedule;
pub mod storage; pub mod storage;
@@ -27,7 +27,7 @@ pub use gaussian::Gaussian;
pub use history::History; pub use history::History;
pub use key_table::KeyTable; pub use key_table::KeyTable;
use matrix::Matrix; use matrix::Matrix;
pub use player::Player; pub use rating::Rating;
pub use schedule::ScheduleReport; pub use schedule::ScheduleReport;
pub const BETA: f64 = 1.0; pub const BETA: f64 = 1.0;

View File

@@ -4,14 +4,18 @@ use crate::{
gaussian::Gaussian, gaussian::Gaussian,
}; };
/// Static rating configuration: prior skill, performance noise `beta`, drift.
///
/// Renamed from `Player` in T2; `Rating` better describes the data
/// (a configuration) vs. a person (who's a `Competitor` with state).
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct Player<D: Drift = ConstantDrift> { pub struct Rating<D: Drift = ConstantDrift> {
pub(crate) prior: Gaussian, pub(crate) prior: Gaussian,
pub(crate) beta: f64, pub(crate) beta: f64,
pub(crate) drift: D, pub(crate) drift: D,
} }
impl<D: Drift> Player<D> { impl<D: Drift> Rating<D> {
pub fn new(prior: Gaussian, beta: f64, drift: D) -> Self { pub fn new(prior: Gaussian, beta: f64, drift: D) -> Self {
Self { prior, beta, drift } Self { prior, beta, drift }
} }
@@ -21,7 +25,7 @@ impl<D: Drift> Player<D> {
} }
} }
impl Default for Player<ConstantDrift> { impl Default for Rating<ConstantDrift> {
fn default() -> Self { fn default() -> Self {
Self { Self {
prior: Gaussian::default(), prior: Gaussian::default(),