Thinking about each of you and how you should approach this project, first you really have to understand how to play the game of Yahtzee. I would suggest that you play the game online if you don't understand how it works. There is a version here: http://www.yahtzeeonline.org/ Click Roll each time you want to roll -- you get up to three rolls per round. Once you are out of rolls or have a combination that you can use, click on one of the boxes at the top that represent the scoring categories and hit Enter. To keep a die at its current value so that rerolling doesn't change it, click Hold by that die.
We won't be implementing a pretty GUI (graphical user interface) for the game, but anybody who knows how to do that can go right on and do it. If you watch this week's webinar you can see how a version I wrote in C++ a few years back runs in a console window. In C++ I could clear the screen before I printed the "board" so it appears that the stuff on screen isn't scrolling. We can't do that in Java so you can just let your output scroll.
I'm going to begin with the tray of dice. First I'll make a class called Die that represents just one die. I'm going to make a constructor for a Die that sets it to a random value between 1 and 6, a roll method that does the same thing, and a getValue method that returns the value of the die. Once I have this Die class, I'll make the DiceTray class. The field in that class will be an array of five Die. In the constructor of the DiceTray class, I'll create the array and then I'll walk through the array and create the Die objects. Like this:
public DiceTray()
{
tray = new Die[5];
for (int i = 0; i < 5; i++)
{
tray[i] = new Die();
}
}
So now I have a tray of dice. I need to be able to tell the tray that I want to roll only certain dice in the tray. I could make a roll method to which I would pass the index of the die to be rolled and that would work fine. But I think I'm going to handle this differently. I think I'm going to pass an array of five boolean values to the roll method so it can walk through the boolean array and use the values in that array to decide whether or not to roll the corresponding Die. This choice might make it a little harder to write the code that deals with playing the game because when the user says which dice need to be re-rolled, the code will have to create the array of booleans. But I'll worry about that later. For right now, here is my roll method in the DiceTray class:
public void roll(boolean[] rollMe)
{
for (int i = 0; i < 5; i++)
{
if (rollMe[i])
{
tray[i].roll();
}
}
}
I need to be able to get the values of the individual dice, so I'm going to pass an index to a getValue method and have that method call the getValue method in the Die class (on the die that corresponds to that index of the tray) and return the value of that die.
Finally, I need the DiceTray to be able to print itself so I need a toString method. I'm going to do what I did in my C++ program and not try to print the dots on the dice. Instead I'm going to print a number surrounded by lines. Like this:
_____ _____ _____ _____ _____
| 3 | | 1 | | 3 | | 4 | | 2 |
----- ----- ----- ----- -----
Finally I'll make a main in the DiceTray class that I'll use to test things with. Here is my idea for a main:
public static void main(String[] args)
{
DiceTray t = new DiceTray();
System.out.println(t);
boolean[] rollers = {true, true, false, false, true};
t.roll(rollers);
System.out.println(t);
}
That's the plan for right now. I'll do that and then come back to the blog.
For those of you reading this blog for help with CS1440, I definitely recommend learning how to play the game. Designing the program will make more sense once you understand the components.
ReplyDeleteA class for the dice is a great place to start. In general, it's best to approach an assignment like this by starting with the parts that are the easiest to design. You know that your game will have to use dice, a structure for holding scores, and players. You can begin with these classes that represent a "has-a" relationship with the game and work your way up the chain.
I didn't create a class for a single die, but it's definitely an option.
However you choose to implement the five dice, you will need some way to access the face value of an individual die.
You'll need to be able to randomize all of the dice for each turn of the game, and you'll need to be able to re-roll an individual die.
You may also find it helpful to put methods to sum and count the die faces in that class. For tallying the faces, you could create an array and return it. Each position in the array corresponds to the count of each die face, in order.
I also found it fun to implement selection sort to be called after all the dice are randomized. It makes it a little easier to spot straights, and much easier to choose which dice to re-roll. There are other ways to sort an array, provided in the Java API, but it never hurts to practice this algorithm.
Writing a toString is a great way to create a printable representation of your dice. It's much easier than writing a separate display method and you can just pass the reference variable to a print statement and you get the toString representation.
As you're writing a class and/or once you think you have it, be sure to test it. It's a lot easier to make classes collaborate when you know they work. Write a main method at the end of the class, create an instance of your class and call some methods on it. Put it some print statements to see if you're getting the result you expected. If not, fix it before moving on to the next class, especially if that class "has-a" DiceTray.