← back to the schedule


Tournament 2.0 — Bracket Simulation PROJECT
By Alyce Brady




PROBLEM DESCRIPTION

In the previous Tournament assignment (Tournament — Initial Matchups) you simulated the first round of a multi-round tournament, possibly with a bye round preceding it. In this assignment you will construct the full bracket and run the complete simulated tournament.

The primary data structure in this program is a bracket tree representing all the tournament matchups. A bracket tree represents the pairings for a tournament, with each level of the tree representing a different round in the tournament. The leaves of the tree represent the participants in the tournament, while each internal non-leaf node represents the winner of the matchup between the left and right nodes beneath it. The root node represents the overall winner of the tournament. The leaves are initialized from a list of participants (possibly also including the placeholder ParticipantInfo.BYE if there are byes), while the internal nodes are initialized to be ParticipantInfo.TBD until the relevant matches are played and they can be replaced by winners.

This project will reuse some of the classes from the initial Tournament project and introduce several others. The classes that you will be able to reuse include:

  • ParticipantInfo.java — Represents (name, value) information about participants, such as their name and ranking.
  • ParticipantReader.java — An object that knows how to read participant information from a file, one participant per line.
  • ValidatedInputReader.java — Class with static methods that can prompt users for numeric or string input.
  • 16rankings.txt and 18rankings.txt — files with sample rankings for 16 and 18 participants
  • round0Scores.txt and round1Scores.txt — sample score results for the bye round and full round 1, respectively.
  • You will also continue to use your K_OrderedList class and any other classes it requires.

In addition, you will be implementing or completing three new classes and using scores from additional rounds of play:

  • Tournament2_0.java — a variation on the original Tournament class that builds an entire tournament bracket and runs a simulation of the full tournament. Like the original Tournament class, it has main and runTournament methods to get things started.
  • BracketTree.java — a tree that contains the matchups for the tournament (an alternative to the Round class, which was an extended ArrayList).
  • BracketScoresReader.java — A class similar to ScoresReader that reads in scores but adds them to a BracketTree
  • round2Scores.txt, round3Scores.txt, and round4Scores.txt.
Tip: Since all of the new classes have new names and no existing classes will be modified, you can add the new classes to your existing project without needing to create a new folder and copy all of the reused classes over.

The instructions for this project follow the precepts and practices of Agile Development, making modifications in small blocks and testing them as soon as possible. As you work on the program, your output should slowly look more and more like that in the Sample Output below.


Getting Started

Download the two incomplete classes above (Tournament2_0 and BracketTree) and the files with scores from rounds 3 - 5 into your existing Tournament folder.

You will not be able to compile and run the Tournament2_0 program at this point because a number of methods called by the runTournament method are missing.


First Look: Reading Code for Understanding

In Tournament2_0.java, notice that the runTournament method is similar to the equivalent method in Tournament.java, although it uses a BracketTree to simulate a full tournament rather than using a Round (a list of Matchup objects) to simulate just the first round (and possibly a bye round before that).

getRankings and setRoundsAndByes: The getRankings and setRoundsAndByes methods for Tournament2_0 are unchanged from the initial Tournament class, so copy them from your initial Tournament class into Tournament2_0.java.

generateBracket: The generateBracket method in Tournament2_0 is similar to generateFirstRound in Tournament, except that it repeatedly generates a list of bracket trees representing the matchups for a given round rather than generating a single Round (a list of Matchup objects). It generates the bracket from the bottom up, so in the first round there will be as many trees as there are matchups in that round, with each tree representing that one Round-1 matchup. In the second round, the list will have only half as many bracket trees since the matchups in the second round will be pairing the winners from the first round, but the trees will represent the pairings for both the first and second rounds. In the third round, the list will again have only half as many bracket trees as the previous round, but each tree will represent the pairings for three rounds, and so on. For the final round, there will be only one bracket tree representing all the rounds of the tournament.

Another difference is that generateBracket stores the final, complete bracket as an instance variable rather than passing the matchups for a single round as a parameter and return value, as happens in the initial Tournament class.


Getting the Program to Compile

You have already made the first modification, copying in the getRankings and setRoundsAndByes methods from the initial Tournament class, since this behavior is unchanged in Tournament2_0.

The body of the determineMatchups method is also missing. Again, it will be very similar to the method in Tournament, but with the small differences that the type and name of the parameter are different, as is the method's return type. This means that the type of the matchups, match1, and match2 variables also need to be different.

At this point you should have implemented enough to try running the program, although it doesn't yet have its full functionality. Based on what code is active and what is commented out in runTournament and simulateRoundOfPlay, does the initial behavior of the program make sense to you? Note that the order of matchups in the Tournament2_0 output is different from the order in the initial Tournament program because the order represents a bracket tree rather than a list sorted by ranking. The "results" should be the same as the initial matchups since the program is not yet able to read in match scores.


Reading the BracketTree Class for Understanding

Notice that the BracketTree class has four constructors. Find where all four are used in generateBracket and determineMatchups.

leftBracket and rightBracket don't seem to be doing anything other than is already done by the inherited leftChild and rightChild methods, but the casting allows us to use the left and right child in code that requires the type to be a BracketTree rather than a generic K_RecBinaryTree, such as when we want to call the handleByes, hasBeenPlayed, or updateScore methods.


Modify the BracketTree Class to Handle Byes

Since the handleByes method calls the markWinner method, start by implementing markWinner. The markWinner method should change the value in the data field of the current node from ParticipantInfo.TBD to the participant identified as the winner. (There is no need to check that the data is currently ParticipantInfo.TBD, though.)

Implement the missing code in handleByes using the comments as a guide.

Run the program. Have the results changed at all? The program still is not printing actual results from the first round (Round 0 or Round 1, depending on which participant rankings file you use), because it cannot yet read in the scores.


Construct the BracketScoresReader Class

Create BracketScoresReader.java by copying ScoresReader.java, changing the name of the class and constructor, and changing the second parameter of both methods to be BracketTree bracket. The new javadoc comment could be

  *    @param bracket the tree representing matchups (past and future)

Note: In ScoresReader, the parseLine method calls the updateScore method in the Round class. The BracketTree class also has an updateScore method, so the same code will compile once the parameter name is updated.

Once you have created the BracketScoresReader class, you can un-comment the block of code in the simulateRoundOfPlay method in Tournament2_0 that creates the scores reader and reads in scores for the current round. You should be able to run the program at this point, although it will still not print the actual results for the first round (Round 0 or Round 1, depending on which participant rankings file you use) because the updateScore method in BracketTree is incomplete.


Modify the BracketTree Class to Document Winners

Implement the missing code in updateScore using the comments as a guide.

This time when you run the program you should see winners and scores for all non-bye matchups in the first round (Round 0 or Round 1, depending on which participant rankings file you use). Compare them to the partial results in the Sample Output section below.


Simulate the Full Tournament

In the runTournament method in Tournament2_0, uncomment the block of code that repeatedly calls the simulateRoundOfPlay method to run the next round of the simulation. Are the results what you expected? Do the matchups for each successive round correspond correctly to the scores being reported?

When you're satisfied with your results, remove the initial call to simulateRoundOfPlay in runTournament marked "TEMPORARY CODE".


Sample Output

(Display)


Clean and Refactor

Follow this link to clean and refactor your comments and code.


Submission

Submit your completed program through Kit, under Tournament 2.0 — Bracket Simulation Project.

Have fun! And if you have any questions remember I am available during office hours and the Collaboration Center folks are here for you as well!




← back to the schedule