use crate::heads_up::HeadsUp;
use crate::util::Util;
use crate::win::Win;
use crate::{PlayerFlag, WinResult};
#[derive(Clone, Debug, Default)]
pub struct Wins(Vec<PlayerFlag>);
impl Wins {
pub fn add(&mut self, count: PlayerFlag) {
self.0.push(count);
}
pub fn add_x(&mut self, count: PlayerFlag, x: usize) {
for _ in 0..x {
self.0.push(count);
}
}
pub fn add_win_first(&mut self) {
self.0.push(Win::FIRST);
}
pub fn add_win_second(&mut self) {
self.0.push(Win::SECOND);
}
pub fn add_win_third(&mut self) {
self.0.push(Win::THIRD);
}
pub fn extend(&mut self, other: &Wins) {
self.0.extend(other.get());
}
#[must_use]
pub fn get(&self) -> &Vec<PlayerFlag> {
&self.0
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
#[must_use]
pub fn len(&self) -> usize {
self.0.len()
}
#[must_use]
pub fn wins_for(&self, result: PlayerFlag) -> (usize, usize) {
let wins: Vec<PlayerFlag> = self
.0
.clone()
.into_iter()
.filter(|r| r.win_for(result))
.collect();
(
wins.len(),
wins.into_iter().filter(WinResult::is_tie).count(),
)
}
#[must_use]
pub fn percentage_for_player(&self, index: usize) -> (f32, f32) {
let total = self.len();
let (wins, ties) = self.wins_for(Win::from_index(index));
let pure_wins = wins - ties;
(
Util::calculate_percentage(pure_wins, total),
Util::calculate_percentage(ties, total),
)
}
#[must_use]
pub fn results_heads_up(&self) -> HeadsUp {
let (first, ties) = self.wins_for(Win::FIRST);
let (second, _) = self.wins_for(Win::SECOND);
HeadsUp::new(first - ties, second - ties, ties)
}
}
impl From<Vec<PlayerFlag>> for Wins {
fn from(counts: Vec<PlayerFlag>) -> Self {
Wins(counts)
}
}
#[cfg(test)]
#[allow(non_snake_case)]
mod util__wincounter__wins__tests {
use super::*;
#[test]
fn extend() {
let mut wins = Wins::default();
let more_wins = Wins::from(vec![Win::FIRST, Win::FIRST, Win::SECOND]);
let even_more_wins = Wins::from(vec![Win::FIRST, Win::SECOND, Win::SECOND]);
wins.extend(&more_wins);
wins.extend(&even_more_wins);
assert!(!wins.is_empty());
assert_eq!(more_wins.len() + even_more_wins.len(), wins.len());
}
#[test]
fn get() {
let v = vec![Win::FIRST, Win::FIRST, Win::SECOND, Win::FIRST];
let wins = Wins::from(v.clone());
assert_eq!(&v, wins.get())
}
#[test]
fn add() {
let mut counter = Wins::default();
counter.add_win_first();
counter.add_win_second();
counter.add_win_first();
counter.add_win_third();
counter.add(Win::FIRST | Win::SECOND);
counter.add(Win::FIFTH);
assert_eq!(6, counter.len())
}
#[test]
fn add_x() {
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, 32116);
assert_eq!((1_365_284 + 32116, 32116), wins.wins_for(Win::FIRST));
assert_eq!((314_904 + 32116, 32116), wins.wins_for(Win::SECOND));
assert_eq!((32116, 32116), wins.wins_for(Win::FIRST | Win::SECOND));
}
#[test]
fn is_empty() {
let mut counter = Wins::default();
counter.add(Win::FIRST);
assert!(!counter.is_empty());
assert!(Wins::default().is_empty());
}
#[test]
fn len() {
let mut counter = Wins::default();
counter.add(Win::FIRST);
counter.add(Win::FIRST);
counter.add(Win::FIRST);
counter.add(Win::FIRST);
assert_eq!(4, counter.len());
assert_eq!(0, Wins::default().len());
}
#[test]
fn wins_for() {
let mut counter = Wins::default();
counter.add_win_first();
counter.add(Win::FIRST | Win::SECOND);
counter.add_win_third();
counter.add_win_third();
counter.add_win_third();
counter.add(Win::FORTH);
assert_eq!((2, 1), counter.wins_for(Win::FIRST));
assert_eq!((1, 1), counter.wins_for(Win::SECOND));
assert_eq!((3, 0), counter.wins_for(Win::THIRD));
assert_eq!((1, 0), counter.wins_for(Win::FORTH));
}
#[test]
fn percentage_for_player() {
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);
let (win_pct, tie_pct) = wins.percentage_for_player(0);
assert_eq!(79.73374_f32, win_pct);
assert_eq!(1.8756015_f32, tie_pct);
let (win_pct2, tie_pct2) = wins.percentage_for_player(1);
assert_eq!(18.39066_f32, win_pct2);
assert_eq!(1.8756015_f32, tie_pct2);
}
#[test]
fn results_heads_up() {
let mut counter = Wins::default();
counter.add_x(Win::FIRST, 1_365_284);
counter.add_x(Win::SECOND, 314_904);
counter.add_x(Win::FIRST | Win::SECOND, 32_116);
let hup = counter.results_heads_up();
assert_eq!(79.73374, hup.percentage_first());
assert_eq!(18.39066, hup.percentage_second());
assert_eq!(1.8756015, hup.percentage_ties());
assert_eq!(100.0, hup.percentage_total());
}
}