use crate::util::Util;
use crate::win::Win;
use crate::wins::Wins;
use std::fmt::{Display, Formatter};
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct WinResults {
pub case_count: usize,
pub player_count: usize,
pub v: Vec<(usize, usize)>,
}
impl WinResults {
#[must_use]
pub fn from_wins(wins: &Wins, player_count: usize) -> WinResults {
let mut results = Self {
case_count: wins.len(),
player_count,
..Default::default()
};
for i in 0..player_count {
let (total_wins, ties) = wins.wins_for(Win::from_index(i));
results.v.push((total_wins - ties, ties));
}
results
}
#[must_use]
pub fn player_to_string(&self, player_index: usize) -> String {
let (wins, ties) = self.wins_and_ties(player_index);
let (win_percentage, tie_percentage) = self.wins_and_ties_percentages(player_index);
let percentage = win_percentage + tie_percentage;
if percentage == 0.00 {
"0.00%".to_string()
} else {
format!("{percentage:.1}% ({win_percentage:.2}%/{tie_percentage:.2}%) [{wins}/{ties}]")
}
}
#[must_use]
pub fn wins_and_ties(&self, player_index: usize) -> (usize, usize) {
match self.v.get(player_index) {
None => (0, 0),
Some((wins, ties)) => (*wins, *ties),
}
}
#[must_use]
pub fn wins_and_ties_percentages(&self, player_index: usize) -> (f32, f32) {
let (wins, ties) = self.wins_and_ties(player_index);
(
Util::calculate_percentage(wins, self.case_count),
Util::calculate_percentage(ties, self.case_count),
)
}
#[must_use]
pub fn wins_total(&self, player_index: usize) -> usize {
let (wins, ties) = self.wins_and_ties(player_index);
wins + ties
}
#[must_use]
pub fn wins_total_percentage(&self, player_index: usize) -> f32 {
let (wins, ties) = self.wins_and_ties(player_index);
Util::calculate_percentage(wins + ties, self.case_count)
}
}
impl Display for WinResults {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
for i in 0..self.v.len() {
writeln!(f, "Player #{} {}", i + 1, self.player_to_string(i))?;
}
Ok(())
}
}
#[cfg(test)]
#[allow(non_snake_case)]
mod util__wincounter__results__tests {
use super::*;
fn the_hand_as_wins() -> Wins {
let mut wins = Wins::default();
wins.add_x(Win::FIRST, 1_365_284); wins.add_x(Win::SECOND, 314_904); wins.add_x(Win::FIRST | Win::SECOND, 32_116);
wins
}
#[test]
fn from_wins() {
let results = WinResults::from_wins(&the_hand_as_wins(), 2);
assert_eq!(1_712_304, results.case_count);
assert_eq!(2, results.player_count);
assert_eq!(&(1_365_284, 32_116), results.v.get(0).unwrap());
assert_eq!(&(314_904, 32_116), results.v.get(1).unwrap());
}
#[test]
fn player_to_string() {
let results = WinResults::from_wins(&the_hand_as_wins(), 2);
assert_eq!(
"81.6% (79.73%/1.88%) [1365284/32116]",
results.player_to_string(0)
);
assert_eq!(
"20.3% (18.39%/1.88%) [314904/32116]",
results.player_to_string(1)
);
assert_eq!("0.00%", results.player_to_string(2));
}
#[test]
fn wins_and_ties() {
let results = WinResults::from_wins(&the_hand_as_wins(), 2);
assert_eq!((1_365_284, 32_116), results.wins_and_ties(0));
assert_eq!((314_904, 32_116), results.wins_and_ties(1));
assert_eq!((0, 0), results.wins_and_ties(2));
assert_eq!((0, 0), results.wins_and_ties(3));
}
#[test]
fn wins_and_ties_percentages() {
let results = WinResults::from_wins(&the_hand_as_wins(), 2);
assert_eq!((79.73374, 1.8756015), results.wins_and_ties_percentages(0));
assert_eq!((18.39066, 1.8756015), results.wins_and_ties_percentages(1));
assert_eq!((0.0, 0.0), results.wins_and_ties_percentages(2));
assert_eq!((0.0, 0.0), results.wins_and_ties_percentages(3));
}
#[test]
fn wins_total() {
let results = WinResults::from_wins(&the_hand_as_wins(), 2);
assert_eq!(1_397_400, results.wins_total(0));
assert_eq!(347_020, results.wins_total(1));
assert_eq!(0, results.wins_total(2));
assert_eq!(0, results.wins_total(3));
}
#[test]
fn wins_total_percentage() {
let results = WinResults::from_wins(&the_hand_as_wins(), 2);
assert_eq!(81.60934, results.wins_total_percentage(0));
assert_eq!(20.266262, results.wins_total_percentage(1));
assert_eq!(0.0, results.wins_total_percentage(2));
assert_eq!(0.0, results.wins_total_percentage(3));
}
#[test]
fn display() {
let results = WinResults::from_wins(&the_hand_as_wins(), 2);
assert_eq!(
"Player #1 81.6% (79.73%/1.88%) [1365284/32116]\nPlayer #2 20.3% (18.39%/1.88%) [314904/32116]\n",
results.to_string()
);
}
}