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

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