Your task is to implement a dice game GUI program based on Java Swing and according to the game rules and the implementation details below. You are allowed to use any classes found in the standard Java API libraries (the classes found in http://docs.oracle.com/javase/8/docs/api/)
but you are NOT allowed to use any other third party libraries or Netbeans libraries (or other IDE specific libraries).
Also you are NOT allowed to use drag and drop tools (such as those found in Netbeans, etc.) to create the graphical user interface for any part of this coursework! All code should be manually written and no tool which generates code automatically should be used. Any submission which uses for any part of this assignment drag and drop tools will not receive more than 30%. Similarly, any work which does not follow the specifications below (which interfaces, classes, methods to implement and use in the rest of the subquestions) will not receive more than 30%.
Your program will be displaying images of the dice thrown by the two players: the human and the computer. You can use the images found in the following URL: http://www.wpclipart.com/recreation/games/dice/ or any other dice images that you prefer. The URL mentioned allows you to edit the images, in case you would like to change the size of the images before saving them in your hard drive for the usage of your Java program (Click on Edit image following by typing the dimensions you prefer before update and saving).
The rules of the game
A human player competes against the computer. Both players throw 5 dice at the same time. The score of each throw for each player is the sum of the numbers shown on the faces of the dice. The objective of the game is to reach a score of 101 or more (instead of 101 another target can be set by the human before play starts) by throwing 5 dice as many times as necessary. After a roll, each player may either score it or take up to two optional rerolls. For each reroll, he may reroll all of the dice or select any of the dice to keep and only reroll the remainder. He may score at any time, thus ending his current throw; after the second reroll (three rolls total) he must score it.
After both players score their rolls, the procedure is repeated until one of the players reach 101 or more points by summing all of their scores. If both players reach 101 or more with the same number of attempts (a single attempt is considered as one roll followed by 2 optional rerolls) the player with the highest score wins.
As an example, assume that the human player scores 30 points in the first attempt (a roll followed by 2 optional rerolls), 25 in the second, 11 in the third, 28 in the fourth and 15 in the fifth achieving a total score of 109 in five attempts. If the computer did not score 101 in four attempts or more than 109 in five attempts, the human wins. In the case that both the computer and the human achieved the same score in the five attempts (i.e. 109 in the example), each player throws for a last time all five dice and the player with the highest sum in that roll wins (no optional rerolls are allowed in this case). In the case of a tie again, both players keep rethrowing all five dice until one of them wins.
Specification
Any graphical components in your GUI application should use relative positioning and NOT absolute positioning. I.e. when you resize the application (the window or frame of your application) each component will still be in the same relative position to other graphical components. You should NOT use coordinates x, y to specify that a component will be located at that specific point x, y in a container (absolute positioning). You should NOT disable the resizing of the main frame of the application.
The details for the implementation of the system are given in the steps below:
- Create a Java interface DieIntf which contains four methods: getDieImage() (returning an ImageIcon), setImage (which sets the image associated with the face of a die for a die class implementing the interface), setValue(int v) which sets the value of the face of a die (which number is displayed on the top of a die) and getValue() (which returns the value of the face of a die, i.e. which number is displayed on the top of a die).
- Create a class Die which represents a die and implements the DieIntf and the Comparable (found in the standard API package java.lang) interfaces. For the implementation of the latter, a die with a higher face value is considered as greater than a die with a smaller face value. In terms of natural ordering, a die with higher value is coming after a die with a lower value.
- Design and implement a class Dice which contains 6 instances of Die objects each one of them having a different face (i.e. each one of them represents a die which displays on the top 1, 2, 3, 4, 5 and 6 respectively). The class should include a method roll() which returns an array of 5 objects (different ones every time the method is called), representing the roll of 5 dice. Each of these 5 returned objects should be selected from one of the 6 instances of Die objects created above, inside the class Dice. However, not all of them should be unique, as one roll of 5 dice may result in 6, 1, 4, 4, 2, i.e. the same object representing 4 on the face of a die must be included twice in the array. The class may contain any additional methods that you choose as appropriate and necessary for the rest of your game application. For the remaining subquestions, you should be using the classes Die and Dice that you implemented above.
- The implementation of your graphical application should include a button Throw. Each time it is pressed a simulation of throwing 5 dice by both the human player and the computer is performed simultaneously: The images of the five dice rolled by the human player and the five dice rolled by the computer are displayed.
- The human player may choose to score by pressing a button Score or take up to two optional rerolls (see below). As soon as the player clicks on Score the total score for the current game should be updated for both the human player and the computer player. If the user performs the maximum of 3 rolls for that turn, the score is updated automatically without the need to press the Score button (see the rules of the games described above).
- For each of the 2 optional rerolls, the human player should be able to select (it is left up to you to design the appropriate user interface for this) which dice (if any) he would like to keep for that roll. After selecting this, he should press the Throw button again and the dice which have not been selected for keeping should be rerolled.
- The computer player follows a random strategy. I.e. first it decides randomly whether it would like to reroll (up to a maximum of 3 rolls per time) and if this is the case it decides randomly which dice to keep. A single reroll for the computer player occurs and it is displayed only after the human player clicks on the Throw button. If the human player clicks on the Score button, the computer player uses all of its remaining rolls for that turn according to the random strategy, i.e. the final result of the five dice is displayed after the computer has used (optionally based on the random strategy) the 2 rerolls (for a total maximum of 3 rolls).
- Modify your implementation above so that when the user presses the Throw button, the rolls of the human player and the computer player are performed by 2 separate threads (different than the main thread and the event dispatch thread) and the results are displayed as above in the main graphical area of your application.
- When a player (human or computer) reaches 101 or more points a pop up window with the message You win! is displayed (if the human wins) or You lose (if the computer wins). You should implement the exact rules of the game described in the Section The rules of the game above.
- Implement what happens in the case of a tie according to the exact rules of the game described in the Section The rules of the game above (the 2 players keep rolling until the tie is broken - no rerolls in this case).
- Implement a button New Game which reinitialises the application and starts a new game.
- Extend your implementation by allowing the human player to set the number of points which is the target to reach for the winning player (default value is 101).
- The number of wins and losses should be saved in a file every time the application exits.
- When the application starts, the number of wins and losses for the human player and the computer should be read from the file above and displayed in the main graphical area of the application for the whole duration of a game.
- Design and implement an efficient (as optimum as possible) strategy for the computer player strategy. The strategy you design should determine whether the computer player should reroll some of its dice and which ones (up to a maximum of 2 rerolls - total maximum of rolls is 3).
- You should assume that the computer player cannot see the current dice of the human player displayed in the application, but it is aware of (i.e. it can see) the current total of the current game for both itself and the human player, i.e. the computer player knows that the score of the current game is, e.g. 79 93.
If you implement this subquestion, you should make sure that you describe in detail the strategy that you come up with, its justification and why do you think that it will perform well, advantages and disadvantages. The documentation of this should be done inside comments in the very beginning, or the very end of your implementation of this part.