Tire strategy is crucial in Formula 1. The system models tire degradation rates, optimal pit windows, and compound performance to help predict race outcomes and strategy decisions.
The system models five tire compounds with distinct characteristics:
Soft (Red)
Medium (Yellow)
Hard (White)
Intermediate
Wet
Performance: Fastest lap timesDegradation: High (0.085 sec/lap)Optimal Window: Laps 1-18Cliff Point: Lap 18
TIRE_PACE['SOFT'] = 0.0 # No time penalty (baseline)TIRE_DEG['SOFT'] = 0.085 # Fast degradationTIRE_CLIFF['SOFT'] = 18 # Performance drops after lap 18
Performance: BalancedDegradation: Moderate (0.050 sec/lap)Optimal Window: Laps 1-28Cliff Point: Lap 28
TIRE_PACE['MEDIUM'] = 0.4 # +0.4s slower than softTIRE_DEG['MEDIUM'] = 0.050 # Moderate degradationTIRE_CLIFF['MEDIUM'] = 28 # Performance drops after lap 28
Performance: Slowest but most durableDegradation: Low (0.028 sec/lap)Optimal Window: Laps 1-40Cliff Point: Lap 40
TIRE_PACE['HARD'] = 0.8 # +0.8s slower than softTIRE_DEG['HARD'] = 0.028 # Slow degradationTIRE_CLIFF['HARD'] = 40 # Performance drops after lap 40
The race engine calculates lap times with tire degradation:
race_engine.py
def base_lap_time(self, lap, weather, sc_active): """Calculate lap time for this lap""" base = 90.0 # base lap time in seconds # Car performance base -= (self.car - 0.85) * 12.0 # Driver skill (adjusted for weather) eff_skill = self.wet_skill if weather in ["LIGHT_RAIN","HEAVY_RAIN"] else self.skill base -= (eff_skill - 0.85) * 8.0 # Tire compound offset base += TIRE_PACE.get(self.tire, 0.8) # Tire degradation deg = TIRE_DEG.get(self.tire, 0.05) cliff = TIRE_CLIFF.get(self.tire, 25) # Degradation accelerates after cliff point age_factor = self.tire_age if self.tire_age < cliff else \ cliff + (self.tire_age - cliff) * 2.2 base += deg * age_factor # Safety car effect if sc_active: base = max(base, 115.0) # slow down behind SC # Random variation (±0.4s) base += random.gauss(0, 0.4) return max(base, 82.0)
# Start on softs, pit lap 18 for mediumsstrategy = STRATEGIES["S-M"]# Lap 1-18: Fast pace on softs# Lap 19-50: Consistent pace on mediums# Total pit stops: 1# Time cost: 22 seconds# Best for: Top teams starting from front
Strategies are assigned based on grid position and team performance:
race_engine.py
def assign_strategies(weather): """Assign strategies to all 20 drivers""" assignments = {} grid = list(DRIVERS.keys()) random.shuffle(grid) for i, code in enumerate(grid): if weather == "HEAVY_RAIN": # All on wet tires s = WET_STRATEGY.copy() elif weather == "LIGHT_RAIN": # Start on intermediates s = STRATEGIES["M-H"].copy() s["start"] = "INTER" s["compounds"] = ["INTER", "MEDIUM"] else: # Vary strategies realistically if i < 6: # top teams key = random.choice(["S-M", "M-H", "S-M-H"]) elif i < 12: # midfield key = random.choice(["M-H", "H-M", "M-M"]) else: # backmarkers key = random.choice(["H-M", "M-H"]) s = {k: list(v) if isinstance(v, list) else v for k, v in STRATEGIES[key].items()} assignments[code] = s return assignments
Pit earlier than your opponent to gain track position:
# Example: Undercut attempt# Driver A: Pits lap 16 (early)# Driver B: Pits lap 18 (planned)# Lap 16: A pits (loses 22s)# Lap 17: A on fresh tires (3s faster), B on old tires# Lap 18: A still faster, B pits# Lap 19: A ahead of B despite pitting first!
# Example: Overcut defense# Driver A: Pits lap 18# Driver B: Stays out until lap 22# Laps 19-22: B builds gap despite slower tires# Lap 22: B pits with 8+ second gap# Outcome: B retains position after pit stop
# Weather change detectionif current_weather == "DRY" and roll < 0.03: current_weather = "LIGHT_RAIN" weather_history.append((lap, current_weather)) for c in cars.values(): c.events.append(f"L{lap}: Rain starts!")# Tire transitions during wet weatherif current_weather in ["LIGHT_RAIN","HEAVY_RAIN"] and \ next_cpd in ["SOFT","MEDIUM","HARD"]: next_cpd = "INTER" # Switch to intermediates
Rain Strategy Rules:
Dry → Light Rain: Switch to Intermediates immediately
Light Rain → Heavy Rain: Switch to Full Wets
Drying Track: Gamble on slicks early for advantage
P1: Max Verstappen Lap 1-18: SOFT (18 laps) → PIT Lap 19-50: MEDIUM (32 laps) → FINISH Total: 1 stop, 22s lostP2: Lando Norris Lap 1-26: MEDIUM (26 laps) → PIT Lap 27-50: HARD (24 laps) → FINISH Total: 1 stop, 22s lost
The web dashboard displays tire strategy recommendations:
app.py
# Tire strategy datafd['Tire_Degradation_Rate'] = 0.08 if tire=='SOFT' else \ 0.05 if tire=='MEDIUM' else 0.03fd['Optimal_Pit_Lap'] = 25 if tire=='SOFT' else \ 35 if tire=='MEDIUM' else 45fd['Tire_Advantage'] = 1.0 if tire=='SOFT' else \ 0.8 if tire=='MEDIUM' else 0.6
Safety Car Impact: A safety car deployment can completely change optimal strategy. Teams often pit under safety car to minimize time loss (only ~10s vs 22s).