Historical NBA Simulator - Computing Methods II

———————————————————————————————————————————————-

This project is an interactive NBA Historical Simulator featuring a head-to-head matchup tool and a lineup optimizer. The simulator predicts outcomes between teams from any era, while the optimizer identifies the most effective player combinations using efficiency metrics and positional balance.
Authors

Sam Brogi

Toby Holland

Published

December 10, 2025

🏀 Project Summary & Skills Used

Project Overview

This project presents an interactive NBA Historical Simulator with a team matchup predictor and a lineup optimizer. Users can compare teams across eras and evaluate lineup effectiveness using efficiency metrics, player attributes, and positional balance.

Skills Practiced

  • Custom Java class design and inheritance
  • File input/output
  • Integration with external libraries (Vaadin UI, Tablesaw, OpenCSV, etc.)
  • GitHub workflow, version control, and collaborative coding
  • Developing an interactive web interface
  • Applying efficiency metrics and optimization concepts from Industrial Engineering

🛠️ Project Development Process

  • Initial concept:
    My partner and I wanted to create a simulator that could accurately predict scorelines between NBA teams from different eras. We decided to choose a subset of the winningest teams throughout the sport’s history. Initially, we envisioned a total of 30 teams. In addition to the matchup simulator, we wanted to implement a lineup optimizer into our project that could accurately create the best starting 5 based on a series of attributes.

  • Design evolution:
    In the early stages of the project, we were positive that creating a z-score of differentials between teams to train the RandomForest on would be the best way to then forecast any two given teams. However, it eventually proved unnecessary to the training process as the data was already formatted in a way that trained the teams simply, and creating differentials would mean losing the values of statistics in the name of relativity. As for the lineup optimizer, we originally meant for the problem to be solving using OR-Tools, but upon setting up the problem in Java, it became much simpler. Positional balance became the only constraint, and so the problem became more of an optimal search problem than a operations research topic. We also decided to add a worst lineup result as well, as it was a simple matter of replication and would provide completely new information to the user.

  • Roadblocks and solutions:
    We encountered several problems at nearly every point in our project. In the data construction phase, we could not avoid deleting excess games due to the game ID’s not being synced until we used joinOn/inner. We also had to transpose many of the tables manually to change z-score tables to match the formatting of the original dataset. In our first functionality, we discovered that the RandomForest could intake score columns or differential columns because that essentially “leaks” all the information to the model. In the second functionality, the player data allowed players to be considered for multiple positions, allowing players to be in our lineup more than once and violating our predetermined rules for an optimal lineup. Aside from the logic, we had plenty of software issues ranging from the exporting a csv from Excel, to GitHub version control.

  • Final outcome vs. expectations:
    We were very happy with the outcome of our project. While we ended up only having 28 out of the predicted 30 teams, the simulator and optimizer produce efficient, accurate, and consistent results. Though our Vaadin interface is a bit simpler than we may have initially envisioned, it covers everything we needed. We were able to add on to certain parts of our initial idea. In terms of the matchup simulator, we were able to incorporate an OT (overtime) feature, so that no games can end in a tie. In addition to the best lineup, we also implemented code that would find the worst possible lineup (based on the chosen attributes) within our lineup optimizer.

🔑 Key Features/Highlights

  • Below, I will showcase the components of our interface.

Matchup Simulator

  • Once opening the simulator, users will be presented with the option to select an era of choice. Each era has different types of play (scoring, possession, pace, etc.).

Matchup Simulator (upper half)
  • Below the era selection, users will be prompted to select their teams of choice. Clicking on the drop down boxes will present all 28 NBA teams.

Matchup Simulator (lower half)
  • Step 1: Select Era

Matchup Simulator (era selection)
  • Step 2: Select Teams and click ‘Simulate’ to run the model.

Matchup Simulator (team selection)
  • Step 3: Admire results

Matchup Simulator (results)

Lineup Optimizer

  • Once opening the optimizer, users will be presented with the following page:

Lineup Optimizer
  • All users must do is select one offensive attribute and one defensive attribute of choice. Clicking the ‘Show Lineups’ button will lead to the following:

Lineup Optimizer (results)

🧠 Reflection

  • What I learned:
    I strengthened my understanding of object-oriented design by structuring the project into clear classes such as Team, MatchupSimulator, and LineupOptimizer. I also became more confident working with data structures, file input/output, and converting real NBA data into usable program objects. Building the UI taught me how front-end Vaadin components interact with backend Java logic.

  • Contributions I’m proud of:
    I was primarily responsible for debugging the UI interface (Vaadin). In other words, my main job was to make look presentable.

  • Growth as a coder and teammate:
    Throughout this project, I became better at organizing modular code and separating logic from interface code. I improved my version control skills through consistent GitHub branching and merging. I also learned to approach debugging systematically by tracing data flow and isolating issues.

  • Increased confidence:
    I now feel much more comfortable building data-driven, multi-class Java applications. I gained confidence connecting UI frameworks like Vaadin to backend logic. I also feel more prepared to take on larger software projects involving analytics, optimization concepts, and user-facing interfaces.

Overall, our project blended Computing II concepts with industrial engineering principles. This was a fun way to tie what we have learned into a topic of interest for both me and Toby. It demonstrated how data, modeling, and interface design can work together to create an interactive tool like the Historical NBA Simulator.