This repository has been archived on 2025-07-12. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
miller/gamelog/src/event.rs
Cutieguwu 89f97101af Various patches and Delta implementations.
Cheap summaries in main.rs
2025-04-05 19:17:37 -04:00

259 lines
8.9 KiB
Rust

use crate::{Down, Play, Team, TerrainState, error};
use serde::Deserialize;
type Offence = Team;
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub enum Event {
Kickoff(Offence),
Play(Play),
Turnover(Offence),
Penalty(TerrainState),
Score(ScorePoints),
}
impl Event {
pub fn delta(&self, following: &Self) -> Option<i8> {
// Clean this trash spaghetti code up.
fn make_play(event: &Event) -> Option<Play> {
match event {
Event::Kickoff(_) | Event::Turnover(_) => Some(Play::default()),
Event::Play(play) => {
let p = play.to_owned();
if p.down.is_none()
|| p.terrain.is_none()
|| p.terrain.as_ref()? == &TerrainState::Unknown
{
None
} else {
Some(p)
}
}
_ => None,
}
}
let preceeding = make_play(self)?;
let following = if let Event::Turnover(_) = following {
// I should really just early return
// but this is too funny to look at.
None?
} else {
make_play(following)?
};
if following.down? == Down::First {
if let TerrainState::Yards(yrds) = preceeding.terrain? {
Some(yrds as i8)
} else {
None
}
} else {
let a = if let TerrainState::Yards(yrds) = preceeding.terrain? {
yrds
} else {
0_u8
};
let b = if let TerrainState::Yards(yrds) = following.terrain? {
yrds
} else {
0_u8
};
Some(a as i8 - b as i8)
}
}
pub fn team(&self) -> Result<Team, error::NoTeamAttribute> {
match self {
Self::Kickoff(team) => Ok(team.to_owned()),
Self::Turnover(team) => Ok(team.to_owned()),
_ => Err(error::NoTeamAttribute),
}
}
}
#[derive(Debug, Deserialize, Clone, PartialEq, Default)]
pub enum ScorePoints {
#[default]
Touchdown,
FieldGoal,
Safety,
PatFail,
PatTouchdown,
PatFieldGoal,
PatSafety,
}
impl ScorePoints {
pub fn to_points(&self) -> u8 {
match &self {
Self::Touchdown => 6,
Self::FieldGoal => 3,
Self::Safety => 2,
Self::PatFail => 0,
Self::PatTouchdown => 2,
Self::PatFieldGoal => 1,
Self::PatSafety => 1,
}
}
}
#[cfg(test)]
mod tests {
use crate::*;
#[test]
fn delta() {
let kickoff = Event::Kickoff(Team::Nebraska);
let first_down = Event::Play(Play {
action: Action::Unknown,
down: Some(Down::First),
terrain: Some(TerrainState::Yards(10)),
});
let second_down = Event::Play(Play {
action: Action::Unknown,
down: Some(Down::Second),
terrain: Some(TerrainState::Yards(10)),
});
let third_down = Event::Play(Play {
action: Action::Unknown,
down: Some(Down::Third),
terrain: Some(TerrainState::Yards(13)),
});
let fourth_down = Event::Play(Play {
action: Action::Unknown,
down: Some(Down::Fourth),
terrain: Some(TerrainState::Yards(5)),
});
let penalty = Event::Penalty(TerrainState::Yards(15));
let turnover = Event::Turnover(Team::Nebraska);
let noned_down = Event::Play(Play {
action: Action::Unknown,
down: None,
terrain: None,
});
let score = Event::Score(ScorePoints::default());
let goal_line = Event::Play(Play {
action: Action::Unknown,
down: Some(Down::First),
terrain: Some(TerrainState::GoalLine),
});
let inches = Event::Play(Play {
action: Action::Unknown,
down: Some(Down::First),
terrain: Some(TerrainState::Inches),
});
assert!(10_i8 == kickoff.delta(&first_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 == 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!(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));
}
}