pickems/simulation/
mod.rs1use rayon::iter::{IntoParallelIterator, ParallelIterator};
2
3use crate::{datatypes::Teams, reporting::Report};
4
5mod matching;
6mod rng;
7mod swiss_system;
8
9use matching::Matchups;
10pub use swiss_system::SwissSystem;
11
12#[derive(Debug, Clone)]
14pub struct Simulation {
15 pub teams: Teams,
17 pub sigma: f32,
19 pub iterations: u64,
21}
22
23impl Simulation {
24 #[must_use]
26 pub const fn new(teams: Teams, sigma: f32, iterations: u64) -> Self {
27 Self {
28 teams,
29 sigma,
30 iterations,
31 }
32 }
33
34 #[must_use]
36 pub fn dummy(iterations: u64) -> Self {
37 Self {
38 teams: Teams::dummy(),
39 sigma: 800.0,
40 iterations,
41 }
42 }
43
44 pub fn bench_test<R: Report>(&self, mut report: R) -> R {
46 let mut ss = SwissSystem::new(self.teams.ratings, self.sigma);
47 let mut rng = rng::deterministic();
48
49 for _ in 0..self.iterations {
50 ss.reset();
51 ss.simulate_tournament(&mut rng);
52 report.update(&ss);
53 }
54
55 report
56 }
57
58 pub fn run<R: Report>(&self, fresh_report: R) -> R {
60 let fresh_ss = SwissSystem::new(self.teams.ratings, self.sigma);
61
62 (0..self.iterations)
63 .into_par_iter()
64 .map_init(
65 || (fresh_ss, rng::random()),
66 |(ss, rng), _| {
67 ss.reset();
70 ss.simulate_tournament(rng);
71 let mut report = fresh_report;
72 report.update(ss);
73 report
74 },
75 )
76 .sum()
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 use crate::reporting::BasicReport;
85
86 #[test]
88 fn sanity_test() {
89 let iterations = 1000;
90 let report = Simulation::dummy(iterations).bench_test(BasicReport::default());
91
92 assert_eq!(
94 (0..16)
95 .map(|index| report.stats[index].three_zero)
96 .sum::<u64>(),
97 iterations * 2
98 );
99
100 assert_eq!(
102 (0..16)
103 .map(|index| report.stats[index].advancing)
104 .sum::<u64>(),
105 iterations * 6
106 );
107
108 assert_eq!(
110 (0..16)
111 .map(|index| report.stats[index].zero_three)
112 .sum::<u64>(),
113 iterations * 2
114 );
115
116 assert!(report.stats[0].three_zero > report.stats[15].three_zero);
118
119 assert!(report.stats[0].zero_three < report.stats[15].zero_three);
121 }
122}