diff --git a/README.md b/README.md index a46f319..7ddea97 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,15 @@ Rust port of [TrueSkillThroughTime.py](https://github.com/glandfried/TrueSkillThroughTime.py). +## Other implementations + +- [ttt-scala](https://github.com/ankurdave/ttt-scala) +- [ChessAnalysis #F](https://github.com/lucasmaystre/ChessAnalysis) +- [TrueSkillThroughTime.jl](https://github.com/glandfried/TrueSkillThroughTime.jl) +- [TrueSkillThroughTime.R](https://github.com/glandfried/TrueSkillThroughTime.R) + ## Todo - [ ] Add examples (use same TrueSkillThroughTime.py) -- [ ] Change `time` to always be a u64 (or usize?) +- [x] Change `time` to always be f64 +- [ ] Add Observer (see [argmin](https://docs.rs/argmin/latest/argmin/core/trait.Observe.html) for inspiration) diff --git a/examples/atp.rs b/examples/atp.rs index a88bf8c..d54ddd3 100644 --- a/examples/atp.rs +++ b/examples/atp.rs @@ -2,7 +2,27 @@ use std::collections::HashMap; use time::Date; -use trueskill_tt::{History, BETA, MU, P_DRAW}; +use trueskill_tt::{History, PlayerIndex, BETA, MU, P_DRAW}; + +struct Players(HashMap); + +impl Players { + fn new() -> Self { + Self(HashMap::new()) + } + + fn get(&mut self, name: &str) -> PlayerIndex { + if let Some(idx) = self.0.get(name) { + *idx + } else { + let idx = PlayerIndex::new(self.0.len()); + + self.0.insert(name.to_string(), idx); + + idx + } + } +} fn main() { let mut csv = csv::Reader::open("examples/atp.csv").unwrap(); @@ -13,17 +33,23 @@ fn main() { let time_format = time::format_description::parse("[year]-[month]-[day]").unwrap(); + let mut players = Players::new(); + for row in csv.records() { if &row["double"] == "t" { - composition.push(vec![ - vec![row["w1_id"].to_string(), row["w2_id"].to_string()], - vec![row["l1_id"].to_string(), row["l2_id"].to_string()], - ]); + let w1_id = players.get(&row["w1_id"]); + let w2_id = players.get(&row["w2_id"]); + + let l1_id = players.get(&row["l1_id"]); + let l2_id = players.get(&row["l2_id"]); + + composition.push(vec![vec![w1_id, w2_id], vec![l1_id, l2_id]]); } else { - composition.push(vec![ - vec![row["w1_id"].to_string()], - vec![row["l1_id"].to_string()], - ]); + let w1_id = players.get(&row["w1_id"]); + + let l1_id = players.get(&row["l1_id"]); + + composition.push(vec![vec![w1_id], vec![l1_id]]); } results.push(vec![1, 0]); @@ -37,6 +63,49 @@ fn main() { times.push(time as f64 / (60 * 60 * 24) as f64); } + /* + let mut history = History::builder() + .sigma(1.6) + .gamma(0.036) + .priors(priors) + .build::