Assignment 8 – Backgammon: the tournament
Due Friday 5/21 11:59pm for the code deliverables
For this assignment you must implement a tournament manager for backgammon that is capable of running round-robin tournaments and single-elimination tournaments.
1 Round-Robin Tournaments
In a round-robin tournament, each player plays each other player once and the tournament manager tallies the results of each match, ideally reporting the winner as the player with the best record.
For example, if you have three players named and "a", "b", and "c", you’d match up "a" against "b", "a" against "c", and "b" against "c". If the first player in each of those matches wins, then "a"’s record would be 2-0, "b"’s would be 1-1 and "c"’s would be 0-2 and thus "a" is the winner of the tournament.
There are situations, however, where no player has the best record. For example, in a three-player tournament with players named "a", "b", and "c", it may be that "a" beats "b", "b" beats "c", and "c" beats "a", and thus the final result of the tournament is that every player has a 1-1 record.
Another concern for the tournament is working out a schedule. It is possible (but your code is not required) to run games in parallel. Wikipedia describes an algorithm for determining the matches in a schedule.
2 Single Elimination Tournaments
A single-elimination tournament proceeds in a number of rounds. Each round splits the number of players in half, matching one half against the other half and those games are then played. Any player that loses is out of the tournament and the tournament continues with half of the players until there is only a single player left, which is the winner of the tournament.
For example, if you have four players named and "a", "b", "c", and "d", then you might first ask "a" to play "c" and "b" to play "d". If "a" and "b" win, then "c" and "d" are out of the tournament and we then play "a" against "b" to determine who wins the tournament.
When the number of players is not a power of two, then there will be some rounds where some players do not have an opponent and some tournament organizations would just give those players a “bye” into the next round. We will instead use the non-cheating random player from assignment 5 as filler so everyone plays the same number of games and the tournament (internally) has a player count that’s a power of two. Any filler player that your tournament manager generates must have a unique name that starts with "Filler".
3 Cheating
When a player cheats (using the same definition of cheating from assignment 7), the tournament server must account for that as part of the final result it delivers for the tournament.
In a round-robin tournament, when a player is discovered to cheat, all of its wins should be awarded to the non-cheating players that it has played up to that point while the cheater should accumulate losses for all its games so far. After a player cheats, there should be no more network communication with the player and their final tally should have 0 wins. If a player cheats in some round that isn’t the last round, they are still matched up (as they would have been if they had not cheated) but the match is considered a forfeit and the win is directly awarded to the opposing player.
Note that that the final sum of wins might be less than the number of games played. For example, if "a" and "b" play and "a" wins but subsequently cheats, then its win is awarded to "b". It may be the case that on a yet later game, however, "b" cheats. In that situation there is no one to award the win for the original game between "a" and "b". Instead, for that first game where "a" played "b", the tournament manager should count it as if there were two losers and no winners.
In contrast, when a player is discovered to cheat in the single-elimination tournament, simply eliminate it from the tournament as soon as it cheats, giving a win to the opposing player.
This means that the result of the entire tournament might be that there is no winner if, for example, both players cheat in the final game.
Also, unlike assignment 7, if a player cheats during a game, the game should end immediately and it shouldn’t not play out with a replacement local player. Otherwise, the CI may timeout (as it maybe too long before it sees some network communication). Similarly, if two filler players end up playing each other, simply decide on a winner and declare the winner; do not play the game out as it may cause your administrator to be silent for long enough to trigger a timeout from the CI.
4 Design, Build and Test
Your tournament manager should be capable of running either a round-robin tournament or a single-elimination tournament, depending on its initial input.
The tournament manager receives the tournament type, the number of players to expect on stdin, according to config, below.
The tournament manager starts a networking server on the port and then prints networking-started to stdout
Once the server is up and running, the tournament manager waits for the specified number of players to connect via TCP/IP on the given port.
If the tournament is single elimination, the tournament manager creates some number of players to bring the total a number of players to a power of two. For example, if 5 players participate, the tournament manager creates 3 more players. These players should make random moves.
The tournament manager runs the tournament, closes all of the network connections to players, and reports the result to stdout.
If the tournament is a single elimination one, the winner must be reported via the se-result non-terminal, giving the name of the winning player or false if one of the filler players wins.
If the tournament is a round-robin tournament, the records of all players, sorted by the number of games won, should be reported according to the format of the rr-result non-terminal.
config | ::= | { "players" : number, "port" : number, "type" : type } |
type | ::= | "round robin" |
| | "single elimination" | |
networking-started | ::= | "started" |
se-result | ::= | player |
| | false | |
rr-result | ::= | [ [ player, wins, losses ], ... ] |
player | ::= | string |
wins | ::= | number |
losses | ::= | number |
To achieve the above you may have to adjust the interface of the components you designed in previous assignments. As before, note any changes you make to existing parts of your code base so that we can discuss them during code walks.
Also as before, you may not modify the communication protocol for player components from assignment 6. Note that you must inform each player if they won or lost, unless they cheated, in which case simply terminating their connection is fine.
Deliverables: In your team’s GitHub dev repository, create a directory "Deliverables/8/8.1/" and deposit there a Makefile for the tournament manager. We will use it to run a number of tournaments both in single-elimination and round robin mode with our own remote players. You can assume our players will send valid JSON to the admin but you may not make any further assumptions about the shape or order of these messages. Of course, out of sequence or invalid messages count as cheating, just as illegal moves would.
There are no test deliverables for this assignment.
You will receive up to sixty points for your tournament manager depending on how many tournaments it handles appropriately.