From 6e4a54e6dd1a206de8d6853c87d2427cf801e27c Mon Sep 17 00:00:00 2001 From: Trey t Date: Sat, 10 Jan 2026 12:57:33 -0600 Subject: [PATCH] feat(09-01): add dynamic time buffers for same-day game transitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements conditional time buffer logic in canTransition(): - Same-day games (doubleheaders): 2hr post-game, 0.5hr pre-game - Multi-day games: 3hr post-game, 1hr pre-game Enables feasible same-day combinations (LA→SD) while preventing infeasible distant pairings (LA→SF same day). Makes tests pass: - plan_SameDayGamesCloseCities_BothIncluded - plan_ThreeSameDayGames_PicksFeasibleCombinations --- .../Planning/Engine/GameDAGRouter.swift | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/SportsTime/Planning/Engine/GameDAGRouter.swift b/SportsTime/Planning/Engine/GameDAGRouter.swift index 68aa890..81cc2e6 100644 --- a/SportsTime/Planning/Engine/GameDAGRouter.swift +++ b/SportsTime/Planning/Engine/GameDAGRouter.swift @@ -511,12 +511,7 @@ enum GameDAGRouter { let drivingHours = distanceMiles / 60.0 - // Calculate available time - let departureTime = from.startTime.addingTimeInterval(gameEndBufferHours * 3600) - let deadline = to.startTime.addingTimeInterval(-3600) // 1 hour buffer before game - let availableHours = deadline.timeIntervalSince(departureTime) / 3600.0 - - // Calculate driving days available + // Check if same calendar day let calendar = Calendar.current let daysBetween = calendar.dateComponents( [.day], @@ -524,6 +519,27 @@ enum GameDAGRouter { to: calendar.startOfDay(for: to.startTime) ).day ?? 0 + // For same-day games (doubleheaders), use shorter buffers + // People leave earlier and arrive closer to game time + let postGameBuffer: Double + let preGameBuffer: Double + + if daysBetween == 0 { + // Same-day doubleheader: leave during game, arrive at game time + postGameBuffer = 2.0 // Leave during/right after game + preGameBuffer = 0.5 // Arrive closer to start time + } else { + // Different days: use standard buffers + postGameBuffer = gameEndBufferHours // 3.0 hours + preGameBuffer = 1.0 // 1 hour before game + } + + // Calculate available time + let departureTime = from.startTime.addingTimeInterval(postGameBuffer * 3600) + let deadline = to.startTime.addingTimeInterval(-preGameBuffer * 3600) + let availableHours = deadline.timeIntervalSince(departureTime) / 3600.0 + + // Calculate driving hours available let maxDrivingHoursAvailable = daysBetween == 0 ? max(0, availableHours) : Double(daysBetween) * constraints.maxDailyDrivingHours