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_OrderedListclass 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
Tournamentclass, it hasmainandrunTournamentmethods 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 toScoresReaderthat reads in scores but adds them to aBracketTree- 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