The traffic project was never only about Q-learning. It was about fair comparison. Fixed Cycle, Longest Queue First, tabular Q-learning, and a genetic planner all had to run on the same four-way intersection, with the same wait-time and collision metrics.
One simulator, four policies
Sharing TrafficSimulator meant I could not cheat by giving the RL agent a nicer world. Every method saw the same roads, vehicles, and signal phases. That constraint was annoying during development and invaluable during evaluation.
Baselines keep you honest
Fixed Cycle is boring — and that is the point. If an adaptive method cannot beat a timed schedule on average wait time or collisions, the fancy algorithm is not ready. Longest Queue First was the second baseline: a simple heuristic that already adapts without learning.
Genetic search as a different bet
Instead of learning a Q-table over thousands of episodes, the search method evolves short action sequences (length 5) and scores them live. It felt closer to planning than to reinforcement learning — useful when you want a schedule quickly, less useful when you want a reusable policy.
The lesson
Research code gets better when evaluation is a first-class feature. The Tkinter runner that builds `python main.py -m … -e …` was not cosmetic — it made method comparison something I would actually do, instead of something I meant to do later.
