When submitting your hardcopies, turn in only one package of
materials. Your package should include a hardcopy of your
Game.java file and your Tournament.java file.
Please staple your files
together with a cover page, and submit your
hardcopy at the start of class on the due date.
Drop off an electronic copy of your code files by connecting
to your Euro directory and executing the following command:
submit cs230 Euro *.*
Since we have just learned about binary trees in CS230, you will be writing a program that uses trees to simultate the European Football Championship. A binary tree is a natural data structure to represent the results of a single-elimination sports tournament. Your program will begin with 16 teams that participate in the European Football Championship competition. Your program will then simulate the outcome of the games played at each level of the divisional tournament. (If you would rather use another tournament as an example (basketball, tennis, ping-pong, etc.), feel free to do so, as long as you have the names of 16 teams/players with their rankings.)
The pairings for the first eight games of the tournament are listed below. The number in parentheses next to each team name represents the seed number for the team. In advance of the tournament, the 16 teams are ranked from 1 (the host, considered the best) to 16 (Greece), based on qualifying records. In each game, the team with the lower seed number is expected to win, but upsets are not uncommon, especially in this tournament.
Portugal (1) vs. Greece (16)
Spain (8) vs. Russia (9)
France (5) vs. England (12)
Croatia (4) vs. Switzerland (13)
Sweeden (6) vs. Denmark (11)
Italy (3) vs. Bulgaria (14)
Czech Republic (7) vs. Holland (10)
Germany (2) vs. Latvia (15)
For each game that is played as the tournament progresses, your program should generate random, but realistic, scores for the two teams and display the outcome of the game on a GUI. Most (though not all) soccer games have no more than 5 goals, and you will use this fact when you generate random scores.
Below is a picture of a sample GUI that was created in
the solutions for this program.
The GUI consists mostly of JLabels,
and has three JButtons in the bottom right
corner that control the progress of the tournament. You can run this simulation
program yourself by connecting to the
/home/cs230/download/Euro/solution directory and
executing the command java
RunTournament_Solutions. Initially, the GUI contains only the
original 16 teams and their seed numbers along the leftmost column of the
display, as shown in the Figure below.
If at any point, you click the "start new tournament" button, the program
will start a new tournament and again display this initial state of the
tournament.
To progress one level of the tournament, click the "play
next level" button.
From the initial state, the result of this action will be that the first
8 games of the tournament will be played, the labels of
the initial 16 teams will be changed to include the simulated scores in
these games, and the winners of the 8 games will appear in the second column of the display.
If you click the
"play next level" button again, the next 4 games of the tournament
will be played and the winners will be placed in the third column of the display.
Clicking the "play next level" button two more times will complete
the tournament.
When an upset occurs (a team with a higher seed number beats
a team with a lower seed number), the label displayed on the GUI includes
a string of "*" characters. In the results of the complete tournament
shown below, for example, Greece (the No. 16 seed) upset Portugal (the No. 1 seed)
in the first game, then Greece upset Spain, but Greece lost to the favored Croatia,
who then beat Latvia to win the Championship.
At any time during execution of the program, you can click the "end tournament"
button to terminate the program.
Before starting your programming, you should play with this executable version to get a feel for
what your program should eventually do.
Initial code for this program is contained in the /home/cs230/download/Euro directory, which has six code files: Tree.java, Team.java, Game.java, Tournament.java, TreeInterface.java and RunTournament.java. The Tree.java, TreeInterface.java, Team.java and RunTournament.java code files are complete and do not need to be modified. Carefully examine these four code files to see what methods are provided for each class. Your task is to complete the Game.java and Tournament.java code files, as described below.
This file defines a Game class that is used to store information about a single game in the tournament. There are four instance variables to store the two teams competing in the game and the two scores. There is only one method that you need to complete in this class:
(1) the instance method playGame() should simulate the outcome of a single game. This method should generate a random score for each input team that is drawn from a realistic range of soccer scores. You should take into account the fact that the team with the lower seed number is likely to obtain a higher score, but upsets should be possible. If the two scores that are initially generated are equal (a tie), alter one of the scores so that there is a clear winner.
This file defines a Tournament class that stores information about all of the games being played in a tournament, simulates the outcome of these games, and displays the status of the tournament on a GUI. Take a close look at the drawing with the data structures below. The state of the tournament can be represented in a full binary tree of five levels, with the successive levels containing 1, 2, 4, 8 and 16 teams. In the Tournament class, this tree is stored in the gameTree instance variable. At the start of the tournament, an initial game tree can be created with Team objects for the original 16 teams stored in the nodes at the fifth level of the tree, and "empty" Team objects (with no real names and seeds specified) at the other levels, as shown for the root node of the tree in the drawing. The instance variable nextLevel keeps track of the next level at which games must be played in the tournament, and is initialized to 4, as shown in the drawing. The instance variable teams is an array of Team objects that store information about the initial 16 teams. This array is created in the RunTournament.java code file and passed as an input to the Tournament constructor. Your first task for the Tournament class is to complete a method that creates and returns an initial game tree:
(2) complete the definition of the makeInitTree() method whose skeleton appears in the Tournament.java code file. This method is invoked inside the Tournament constructor and inside the startNewTournament() method, and has a single integer input. Recall that every node in a binary tree can be associated with a unique integer label that indicates its position in the tree. In the game tree shown in the drawing, these integer labels are shown below each node. When constructing the initial game tree, the label of the current node can be helpful for determining what Team object to store in the node (either a Team object taken from the teams array or an empty Team object). The integer input to the makeInitTree() method represents the integer node label for the root node of the subtree being constructed by the current call to this method. You should implement makeInitTree() using recursion.
The method playNextLevel() simulates the outcome of playing all of the games on the next level of the game tree. It accomplishes this by calling a recursive helper method named playLevel() whose skeleton appears in the Tournament.java code file.
(3) complete the definition of the method playLevel(). Recall that the nextLevel instance variable stores the level of the game tree whose games should be played next. For each node of the game tree at this level, the playLevel() method should retrieve the Team objects for the two competing teams and determine the outcome of the game played between these two teams (using your playGame() method defined earlier). The Team object for the winning team should then be placed in this node. After you complete the GUI code described below, you can then expand playLevel() to update the GUI with the two scores for this game and the winning team. There is a skeleton for the playLevel() method in the Tournament.java code file that has three inputs: an input Tree t and two integers corresponding to the level and label of the root node of the input tree. The level is helpful to determine when to play a game, and the label input will be helpful when updating the GUI.
Your final task is to complete the GUI for this program, which involves the following subtasks:
(4) complete code to create the three buttons on the GUI display. Instance variables for three Button objects have already been added to the Tournament class, named startButton, nextButton and stopButton. You may consider writing a separate method to create the three buttons and place them in a JPanel, to be added later to the Applet display. This method can then be called by the Tournament constructor. The actionPerformed() method, which is already complete, indicates what actions are performed in response to clicking these three buttons.
(5) Create panels to display all of the labels and buttons that appear on the GUI, in an appropriate arrangement. There are 31 JLabels on the GUI that display information about the teams in the game tree. These JLabels are stored in an array named labelArray that is constructed in the method makeLabels(), which is already complete. The correspondence between the JLabels in this array and the corresponding nodes in the game tree is also pictured in the drawing. In particular, the GUI JLabel corresponding to the node in the game tree with integer node label n is stored in the labelArray at index n (the index 0 of this array is not used). There is a final JLabel created in the makeLabels() method that just displays the overall status of the tournament (this JLabel appears above the buttons in the GUI display created in the solutions). You should add code to the Tournament class to create JPanels for different regions of the GUI display, add the various JLabels and JButtons to these JPanels using appropriate layout managers, and then add the JPanels to the Applet display. You will need to declare an instance variable for each JPanel (or array of JPanels) and should consider writing a separate method to create the JPanels. This method can then be called inside the Tournament constructor.
(6) Complete the init() method to add the JPanels to the Applet using an appropriate layout manager. Your final GUI display does not have to exactly match the display provided in the sample solution version of the program, but you should at least try to copy the general appearance of the game tree.
Note: the Tournament class contains abbreviations for the class methods defined in the Tree class, so that you can invoke these methods without having to write the Tree class name.