A smarter tournament system in which players are paired with those of similar skill level and everyone competes in every round. More fair than an elimination bracket and more efficient than a round-robin tournament.
A PostgreSQL database stores match results, and a Python module queries the database to rank and pair players. When two players have the same win record, ties are broken by summing the win record of each player's previous opponents.
Python >2.7 and <3.0.
To create the tournament database and tables:
>>> psql
initialize the interactive terminal for PostgreSQL
>>> \i tournament.sql
execute the contents of tournament.sql to create database, tables, and views
>>> \q
exit Psql interactive
Start the Python interpreter and import the tournament.py module.
python
>>> from tournament import *
The database will assign a unique id# to each player which you will use to refer to this player going forward. registerPlayer(name)
returns this id#, and you can capture it for future use like so:
>>> playerID = {}
>>> playerID['Rudy'] = registerPlayer('Rudy')
>>> playerID['Fido'] = registerPlayer('Fido')
Tournaments can be made up of multiple tours. Again, the database assigns a unique id# to each tour when you register it using registerTour(name)
. Capture it like this:
>>> tourID = {}
>>> tourID['agility'] = registerTour('agility')
>>> tourID['tug_of_war'] = registerTour('tug_of_war')
Players can participate in multiple tours. Register them using enrollPlayerInTour(player_id, tour_id)
. Note: The tournament module is currently configured to only work with an even number of players for each tour.
>>> enrollPlayerInTour(playerID['Rudy'], tourID['agility'])
>>> enrollPlayerInTour(playerID['Fido'], tourID['agility'])
Each player is paired with another player with an equal or nearly-equal win record using swissPairings(tour_id)
. Rematches are avoided, so all pairings are new. The function returns a list of tuples, each of which contains (id1, name1, id2, name2).
>>> swissPairings(tourID['agility'])
[(1, 'Rudy', 2, 'Fido'), ... ]
Record the results of matches by using reportMatch(tour_id, winner, loser, draw=False)
. If the match was a draw, you can supply the optional argument draw=True
.
>>> reportMatch(tourID['agility'], playerID['Rudy'], playerID['Fido'])
playerStandings(tour_id)
Returns a list of the players and their win, loss, draw records, sorted by total score. Currently wins are worth 1 point and draws are worth 0.5 points (configure these by changing the values of WIN_POINTS
and DRAW_POINTS
in the python file).
When two or more players have the same score, they are ranked according to the total score of players they have played against.
Returns a list of tuples, each of which contains (id, name, wins, losses, draws, matches, score).
>>> playerStandings(tourID['agility'])
[(1, 'Rudy', 3, 0, 1, 4, 3.5), ... ]