Various patches and Delta implementations.

Cheap summaries in main.rs
This commit is contained in:
Cutieguwu
2025-04-05 19:17:37 -04:00
parent 594d53e080
commit 89f97101af
3 changed files with 232 additions and 49 deletions

View File

@@ -5,8 +5,8 @@ type Offence = Team;
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub enum Event {
Play(Play),
Kickoff(Offence),
Play(Play),
Turnover(Offence),
Penalty(TerrainState),
Score(ScorePoints),
@@ -54,13 +54,13 @@ impl Event {
let a = if let TerrainState::Yards(yrds) = preceeding.terrain? {
yrds
} else {
unreachable!()
0_u8
};
let b = if let TerrainState::Yards(yrds) = following.terrain? {
yrds
} else {
unreachable!()
0_u8
};
Some(a as i8 - b as i8)
@@ -159,27 +159,100 @@ mod tests {
});
assert!(10_i8 == kickoff.delta(&first_down).unwrap());
assert!(0_i8 == first_down.delta(&second_down).unwrap());
assert!(-3_i8 == second_down.delta(&third_down).unwrap());
assert!(0_i8 == kickoff.delta(&second_down).unwrap());
assert!(None == kickoff.delta(&penalty));
assert!(None == kickoff.delta(&score));
assert!(10_i8 == first_down.delta(&kickoff).unwrap());
assert!(10_i8 == first_down.delta(&first_down).unwrap());
assert!(0_i8 == first_down.delta(&second_down).unwrap());
assert!(None == first_down.delta(&turnover));
assert!(None == first_down.delta(&penalty));
assert!(None == first_down.delta(&score));
assert!(10_i8 == first_down.delta(&goal_line).unwrap());
assert!(10_i8 == first_down.delta(&inches).unwrap());
assert!(None == first_down.delta(&noned_down));
assert!(10_i8 == second_down.delta(&kickoff).unwrap());
assert!(10_i8 == second_down.delta(&first_down).unwrap());
assert!(-3_i8 == second_down.delta(&third_down).unwrap());
assert!(None == second_down.delta(&turnover));
assert!(None == second_down.delta(&penalty));
assert!(None == second_down.delta(&score));
assert!(10_i8 == second_down.delta(&goal_line).unwrap());
assert!(10_i8 == second_down.delta(&inches).unwrap());
assert!(None == second_down.delta(&noned_down));
assert!(13_i8 == third_down.delta(&kickoff).unwrap());
assert!(13_i8 == third_down.delta(&first_down).unwrap());
assert!(8_i8 == third_down.delta(&fourth_down).unwrap());
assert!(None == third_down.delta(&turnover));
assert!(None == third_down.delta(&penalty));
assert!(None == third_down.delta(&score));
assert!(13_i8 == third_down.delta(&goal_line).unwrap());
assert!(13_i8 == third_down.delta(&inches).unwrap());
assert!(None == third_down.delta(&noned_down));
assert!(5_i8 == fourth_down.delta(&kickoff).unwrap());
assert!(5_i8 == fourth_down.delta(&first_down).unwrap());
assert!(None == fourth_down.delta(&turnover));
assert!(None == kickoff.delta(&penalty));
assert!(None == first_down.delta(&penalty));
assert!(None == noned_down.delta(&kickoff));
assert!(None == noned_down.delta(&turnover));
assert!(None == kickoff.delta(&score));
assert!(None == first_down.delta(&score));
assert!(None == turnover.delta(&score));
assert!(None == goal_line.delta(&first_down));
assert!(None == inches.delta(&first_down));
assert!(None == goal_line.delta(&inches));
assert!(None == fourth_down.delta(&penalty));
assert!(None == fourth_down.delta(&score));
assert!(5_i8 == fourth_down.delta(&goal_line).unwrap());
assert!(5_i8 == fourth_down.delta(&inches).unwrap());
assert!(None == fourth_down.delta(&noned_down));
assert!(10_i8 == turnover.delta(&first_down).unwrap());
assert!(0_i8 == turnover.delta(&second_down).unwrap());
assert!(-3_i8 == turnover.delta(&third_down).unwrap());
assert!(None == turnover.delta(&turnover));
assert!(None == turnover.delta(&penalty));
assert!(None == turnover.delta(&score));
assert!(10_i8 == turnover.delta(&goal_line).unwrap());
assert!(10_i8 == turnover.delta(&inches).unwrap());
assert!(None == turnover.delta(&noned_down));
assert!(None == score.delta(&kickoff));
assert!(None == score.delta(&first_down));
assert!(None == score.delta(&second_down));
assert!(None == score.delta(&third_down));
assert!(None == score.delta(&fourth_down));
assert!(None == score.delta(&turnover));
assert!(None == score.delta(&penalty));
assert!(None == score.delta(&goal_line));
assert!(None == score.delta(&inches));
assert!(None == score.delta(&score));
assert!(None == goal_line.delta(&kickoff));
assert!(None == goal_line.delta(&first_down));
assert!(-10_i8 == goal_line.delta(&second_down).unwrap());
assert!(-13_i8 == goal_line.delta(&third_down).unwrap());
assert!(-5_i8 == goal_line.delta(&fourth_down).unwrap());
assert!(None == goal_line.delta(&turnover));
assert!(None == goal_line.delta(&penalty));
assert!(None == goal_line.delta(&goal_line));
assert!(None == goal_line.delta(&inches));
assert!(None == goal_line.delta(&score));
assert!(None == inches.delta(&kickoff));
assert!(None == inches.delta(&first_down));
assert!(-10_i8 == goal_line.delta(&second_down).unwrap());
assert!(-13_i8 == goal_line.delta(&third_down).unwrap());
assert!(-5_i8 == goal_line.delta(&fourth_down).unwrap());
assert!(None == inches.delta(&turnover));
assert!(None == inches.delta(&penalty));
assert!(None == inches.delta(&goal_line));
assert!(None == inches.delta(&inches));
assert!(None == inches.delta(&score));
assert!(None == noned_down.delta(&kickoff));
assert!(None == noned_down.delta(&first_down));
assert!(None == noned_down.delta(&second_down));
assert!(None == noned_down.delta(&third_down));
assert!(None == noned_down.delta(&fourth_down));
assert!(None == noned_down.delta(&turnover));
assert!(None == noned_down.delta(&penalty));
assert!(None == noned_down.delta(&goal_line));
assert!(None == noned_down.delta(&inches));
assert!(None == noned_down.delta(&score));
}
}

View File

@@ -53,8 +53,6 @@ impl Game {
let mut idx: usize = 0;
let mut deltas: Vec<i8> = vec![];
dbg!(&events);
while idx < len {
if let Some(value) = events[idx].delta(&events[idx + 1]) {
deltas.push(value);
@@ -66,31 +64,6 @@ impl Game {
deltas
}
/// The average number of plays in a quarter.
/// Does not include OT plays or quarters where team indeterminate.
pub fn avg_plays_per_quarter(&self, team: Team) -> f32 {
// Handle if teams known at start or not override via index calculation of all game events.
let quarterly_avgs: Vec<f32> = self
.periods
.iter()
.filter_map(|period| {
if !period.is_overtime() {
let plays = period.team_plays(team.to_owned(), None);
Some(plays.unwrap().len() as f32 / period.quarters().len() as f32)
} else {
None
}
})
.collect::<Vec<f32>>();
let mut summation = 0_f32;
quarterly_avgs.iter().for_each(|float| summation += float);
summation / quarterly_avgs.len() as f32
}
pub fn team_plays(&self, team: Team) -> usize {
let quarterly_plays: Vec<usize> = self
.periods
@@ -111,6 +84,67 @@ impl Game {
summation
}
/// The average number of plays in a quarter.
/// Does not include OT plays or quarters where team indeterminate.
pub fn avg_plays_per_quarter(&self, team: Team) -> f32 {
// Handle if teams known at start or not override via index calculation of all game events.
let quarterly_avgs: Vec<f32> = self
.periods
.iter()
.filter_map(|period| {
if !period.is_overtime() {
let plays = period.team_plays(team.to_owned(), None);
Some(plays.unwrap().len() as f32 / period.quarters().len() as f32)
} else {
None
}
})
.collect::<Vec<f32>>();
quarterly_avgs.iter().sum::<f32>() / quarterly_avgs.len() as f32
}
pub fn avg_delta(&self, team: Team) -> f32 {
let deltas = self.deltas(team);
// Summation doesn't like directly returning f32 from i8.
deltas.iter().sum::<i8>() as f32 / deltas.len() as f32
}
pub fn avg_gain(&self, team: Team) -> f32 {
let deltas: Vec<u8> = self
.deltas(team)
.iter()
.filter_map(|value| {
if value.is_positive() {
Some(value.to_owned() as u8)
} else {
None
}
})
.collect();
// Summation doesn't like directly returning f32 from u8.
deltas.iter().sum::<u8>() as f32 / deltas.len() as f32
}
pub fn avg_loss(&self, team: Team) -> f32 {
let deltas: Vec<i8> = self
.deltas(team)
.iter()
.filter_map(|value| {
if value.is_negative() {
Some(value.to_owned())
} else {
None
}
})
.collect();
deltas.iter().sum::<i8>() as f32 / deltas.len() as f32
}
}
#[derive(Debug, Deserialize, Clone, PartialEq)]