Deterministic race strategy simulation and crossover analysis in MoonBit.
Dependencies
pub(all) enum CliErrorCode {
MissingInputPath
MissingRequiredOption
MissingOptionValue
DuplicateOption
UnknownArgument
UnexpectedPositional
InvalidPlanFormat
InvalidPlanLap
InvalidPlanCompound
DuplicatePlanLap
} derive(Eq)pub struct CliOptions {
input_path : String
target_driver : String
opponent_driver : String
stops : Array[PlannedPitStop]
output_path : String?
} derive(Eq)pub(all) enum CliPipelineErrorCode {
CsvValidationFailed
StrategySimulationFailed
ExplanationFailed
} derive(Eq)pub(all) struct CrossoverPoint {
lap : Int
kind : CrossoverKind
direction : CrossoverDirection
previous_value_ms : Int
current_value_ms : Int
} derive(Eq, Debug)pub struct DriverLapState {
lap : Int
driver : String
lap_time_ms : Int
cumulative_time_ms : Int
position : Int
gap_to_leader_ms : Int
interval_to_ahead_ms : Int?
compound : Compound
tyre_age_laps : Int
pit : Bool
track_status : TrackStatus
weather : Weather
} derive(Eq, Debug)pub(all) struct ExplanationError {
code : ExplanationErrorCode
lap : Int?
message : String
} derive(Eq, Debug)pub struct LapRecord {
lap : Int
driver : String
lap_time_ms : Int
compound : Compound
tyre_age_laps : Int
pit : Bool
track_status : TrackStatus
weather : Weather
} derive(Eq, Debug)pub(all) struct PaceModelConfig {
tyre_profiles : Array[TyreProfile]
pit_loss_profile : PitLossProfile
} derive(Eq, Debug)pub struct RaceError {
code : RaceErrorCode
line : Int
field : String
message : String
} derive(Eq, Debug)pub(all) enum RaceEvent {
PitStop(PitStopEvent)
TrackStatusChange(TrackStatusChangeEvent)
WeatherChange(WeatherChangeEvent)
PositionChange(PositionChangeEvent)
} derive(Eq, Debug)pub(all) struct StrategyError {
code : StrategyErrorCode
lap : Int?
message : String
} derive(Eq, Debug)pub(all) struct StrategyExplanation {
verdict : StrategyVerdict
target_driver : String
opponent_driver : String
actual_stops : Array[StrategyPitStop]
simulated_stops : Array[StrategyPitStop]
performance_crossovers : Array[CrossoverPoint]
strategic_crossovers : Array[CrossoverPoint]
opponent_crossovers : Array[CrossoverPoint]
turning_points : Array[TurningPoint]
best_lap_gain : LapImpact?
worst_lap_loss : LapImpact?
summary : StrategySummary
laps : Array[StrategyLapComparison]
} derive(Eq, Debug)pub(all) struct StrategyLapComparison {
lap : Int
neutral_lap_time_ms : Int
weather : Weather
track_status : TrackStatus
actual_lap_time_ms : Int
actual_cumulative_time_ms : Int
actual_compound : Compound
actual_tyre_age_laps : Int
actual_pit : Bool
actual_position : Int
actual_signed_gap_to_opponent_ms : Int
simulated_lap_time_ms : Int
simulated_cumulative_time_ms : Int
simulated_compound : Compound
simulated_tyre_age_laps : Int
simulated_pit : Bool
simulated_position : Int
simulated_signed_gap_to_opponent_ms : Int
cumulative_time_gain_ms : Int
} derive(Eq, Debug)pub(all) struct StrategyRequest {
target_driver : String
opponent_driver : String
stops : Array[PlannedPitStop]
} derive(Eq, Debug)pub(all) struct StrategySimulation {
request : StrategyRequest
laps : Array[StrategyLapComparison]
summary : StrategySummary
} derive(Eq, Debug)pub(all) struct StrategySummary {
target_driver : String
opponent_driver : String
lap_count : Int
actual_stop_count : Int
simulated_stop_count : Int
actual_total_time_ms : Int
simulated_total_time_ms : Int
time_gain_ms : Int
actual_finish_position : Int
simulated_finish_position : Int
positions_gained : Int
actual_final_signed_gap_to_opponent_ms : Int
simulated_final_signed_gap_to_opponent_ms : Int
opponent_gap_gain_ms : Int
} derive(Eq, Debug)pub struct TrackStatusChangeEvent {
lap : Int
previous : TrackStatus
current : TrackStatus
} derive(Eq, Debug)fn TrackStatusChangeEvent::not_equal(x : TrackStatusChangeEvent, y : TrackStatusChangeEvent) -> Boolpub(all) struct TurningPoint {
lap : Int
kind : TurningPointKind
impact_ms : Int?
message : String
} derive(Eq, Debug)pub(all) struct TyreProfile {
compound : Compound
fresh_deltas : WeatherPaceDeltas
degradation_ms_per_lap : Int
cliff_age_laps : Int
cliff_extra_ms_per_lap : Int
} derive(Eq, Debug)fn cli_help() -> Stringfn derive_neutral_lap_time_ms(config : PaceModelConfig, observed_lap_time_ms : Int, compound : Compound, tyre_age_laps : Int, weather : Weather, track_status : TrackStatus, pit : Bool) -> Result[Int, ModelError]fn estimate_lap_time_ms(config : PaceModelConfig, neutral_lap_time_ms : Int, compound : Compound, tyre_age_laps : Int, weather : Weather, track_status : TrackStatus, pit : Bool) -> Result[Int, ModelError]fn explain_strategy(config : PaceModelConfig, simulation : StrategySimulation) -> Result[StrategyExplanation, ExplanationError]fn format_duration_ms(milliseconds : Int) -> Stringfn format_signed_ms(milliseconds : Int) -> Stringfn generate_strategy_report(csv : String, target_driver : String, opponent_driver : String, stops : Array[PlannedPitStop]) -> Result[String, CliPipelineError]fn simulate_strategy(data : RaceData, config : PaceModelConfig, request : StrategyRequest) -> Result[StrategySimulation, StrategyError]fn tyre_pace_delta_ms(config : PaceModelConfig, compound : Compound, tyre_age_laps : Int, weather : Weather) -> Result[Int, ModelError]Install
Download zipDeterministic race strategy simulation and crossover analysis in MoonBit.
Dependencies