round_robin
The problem statement
My mom is an avid pickleball player, and when I say avid, I don't just mean that she likes to play a lot of pickleball, I mean that she won the US nationals tournament this year and she coaches pickleball classes in her free time.
She talked to me once and was frustrated with the state of round robin scheduling apps. She claimed that they didn't offer enough flexibility in terms of ability to schedule a tournament where one could easily input the amount of games to be played, the amount of courts that are available, and the amount of players. I took a quick look around the app store and at some websites and generally agreed with her assessment. Since those configuration options sounded like function parameters that could be baked into a script, I figured that I could write a simple algorithm to schedule a round robin tournament.
My approach
I opened up Matlab to write the script. I used Matlab because it's the language I code in every day for work, and it would be the easiest one for me to prototype the algorithm in. I wanted to start simple: just create an algorithm which would randomly assign players using the three parameters: number of games (nGames), number of courts (nCourts), and number of players (nPlayers), and print the matchups to stdout. This turned out to be relatively straightforward to write, and it was a good way to get the skeleton of the algorithm written. However, during the testing, it looked like some players would have multiple byes, and others would play every round. This led to a desire to improve upon the algorithm to solve this problem.
I created a player matchup matrix (an nPlayer by nPlayer size matrix) to count the amount of times each player has played with each other player, as well as an extra column in order to keep track of the amount of byes each player has had, since we would want to minimize those. After adding this and printing the output to console after all the match ups had been made, my suspicions were confirmed: some players had multiple byes, whereas others had none. Additionally it could be seen that some players were paired up with others multiple times, and did not play with some others at all. Therefore, I decided to modify the algorithm in order to minimize the number of byes each player has, and also maximize the amount of times a player gets paired with another player.
To do this, I wrote the function make_team(). To pick the first player on the team, I utilized the player matchup matrix to check which player has had the most byes, and pick them first. To pick their partner, I picked the player with the next least amount of byes, and also has played the least amount of times with player one. This yielded better results, ensuring that everyone had the same number of byes, and had played with all other players an equal amount.
Beta testing
I sent the above algorithm to my mom and her friends to test, and they all said it was great, but I also got some feedback from the users:
- Make it easier to use by making it an app or website.
- Make it so that each player not only gets paired up with everyone, but also plays against everyone too.
- Add an extra parameter so that the tournament creator can enter skill levels for each player. Then beginner players can be paired against beginners, and advanced can play against advanced.
Making a website version
I hadn't made an app or website before, so I did some research on both. It turns out in order to make an iPhone app, you must create a developer account, which costs $100 per year. And in order to make a website, it is free. Thus, I decided a web app version would be the best first approach. This required me to learn a bit of Javascript, so I studied some documentation and began translating the algorithm into Javascript. After translating, I had a few bugs (Matlab has 1-based arrays and Javascript uses 0-based arrays, so there were a few indexing errors). Once those were all fixed though, the Javascript version seemed to be giving good results that were equivalent to the Matlab version. All I needed to do now was to deploy it onto a website! I deployed it to my site on Netlify, and the Javascript wasn't working! After some debugging, I found that it was due to my Content Security Policy (CSP). In order to fix this, I needed to embed a unique hash into my script, and then update the CSP to only allow script with that hash to run. After updating and re-deploying, it worked again! I sent this version to my mom again, and it was successful in it's first field test!
Conclusion
This was a great project to learn some Javascript. Now if I ever need to make another web app in the future, it won't be so daunting. Next, I will need to add the other two features that were requested. The source code and project demo are below:
The source code
The project demo