


The Problem & Motivation
Typical fantasy draft aids rely on static “Value Over Replacement Player” (VORP) metrics, which fail to adapt to the dynamic state of a live draft or the adversarial nature of opponent picks. This project’s motivation was to train an agent that defines “success” not by the highest static point total, but by its ability to win a full, post-draft season simulation. The core challenge is teaching the agent to trade off immediate player value against long-term roster construction and positional scarcity.
Key Features
Custom RL Draft Environment: A full-featured OpenAI Gym environment (fantasy_draft_env.py) that models a multi-team snake draft, complete with configurable roster structures and a state representation that includes positional scarcity, opponent needs, and bye-week conflicts.
Robust Training Randomization: To prevent overfitting to a single strategy, the training loop (train.py) randomizes the agent’s starting draft position and assigns varied “personalities” (e.g., ADP-based, heuristic, or other AI models) to opponents in each episode (config.py).
End-to-End Season Simulation Reward: Instead of a simple per-pick reward, the agent receives its primary reward signal only after the draft is complete. A high-speed, NumPy-based simulator (utils/season_simulation_fast.py) plays out an entire fantasy season, and the agent’s reward is based on its final playoff placement and championship-win status.
Interactive “Draft Buddy” UI: A Flask and JavaScript frontend (app.py, index.html) to run mock drafts, manually draft, or get real-time positional suggestions from the trained agent.
Tech Stack & Implementation
Backend: Python, PyTorch, Flask, OpenAI Gym, Pandas, NumPy
Frontend: HTML, CSS, Vanilla JavaScript
Infrastructure: Docker
A PyTorch-based REINFORCE agent (reinforce_agent.py) is trained on data from the custom Gym environment. The agent’s reward signal is generated by a fast, NumPy-based optimal lineup simulator (season_simulation_fast.py) that plays out an entire fantasy season to determine the draft’s true winner. A Flask server (app.py) provides a RESTful API to manage the draft state and serve the frontend.