homework代写 | java代做 | 代写project | assignment – Com S 227

Com S 227

homework代写 | java代做 | 代写project | assignment – 这道题目是利用java进行的编程代写任务, 是有一定代表意义的java等代写方向, 这个项目是assignment代写的代写题目

homework代写 代写homework hw代做

assignment 4

300 points

General information

This assignment is to be done on your own. See the Academic Dishonesty policy in the syllabus, http://www.cs.iastate.edu/~cs227/syllabus.html , for details.

You will not be able to submit your work unless you have completed the Academic Dishonesty policy questionnaire on the Assignments page on Canvas. Please do this right away.

If you need help, see your instructor or one of the TAs. Lots of help is also available through the Piazza discussions.

Note: The due date is the last day of classes. This is to give everyone as much time as possible. If you don’t want to have an assignment due on the last day of classes, please speak with one of staff. We will be happy to provide a special, earlier due date just for you.

Please start the assignment as soon as possible and get your questions answered right away!


For this assignment you will implement a number of classes for an implementation of a dice game based on the game Yahtzee. The purposes of this assignment are:

  • To use interfaces and inheritance in a realistic way
  • To give you a chance to make some design decisions related to inheritance
  • To give you more practice using arrays and ArrayLists

A portion of your grade on this assignment (roughly 15% to 20%) will be determined by how effectively you have been able to use inheritance to minimize duplicated code in the ScoringCategory hierarchy.

Summary of tasks

You will implement the following classes:


plus, at a minimum , the following nine classes, all of which directly or indirectly implement the ScoringCategory interface:


All of your code goes in package hw 4. In addition to the classes listed above , you will implement whatever additional classes you decide are necessary in order to exploit inheritance to facilitate code reuse. See the discussion of scoring categories below for more information.

The exact definition of each of the nine category classes listed above can be found by reading its javadoc.

Yahtzee is normally played with five, six-sided dice and a scorecard. One round consists of rolling the dice up to three times, and then filling one of the categories on the scorecard with a score. The score depends on both the criteria for the category and the actual dice values, and the player will normally choose an unfilled category so as to maximize the resulting score.

In our version of the game, the number of dice, the maximum value on the dice (i.e., the number of sides), the max number of rolls per round, and the types of categories on the scorecard, will all be configurable.

If you are not at all familiar with the game, dont worry, it is not too complicated. Take a look at the Wikipedia page for an overview, http://en.wikipedia.org/wiki/Yahtzee

Note that our version of the game does not include several features described on Wikipedia or in the
traditional versions of the game. In particular, we do not distinguish the "upper section" and "lower
section" categories, there is no bonus for the "upper section", there is no special bonus for a second
Yahtzee, and there are no jokers.

The two key abstractions in the design are hands and scoring categories.


A hand, represented by the Hand class that you will implement, is a basically a list of Die objects representing the current states of all the dice (in the traditional game there would be 5 dice with possible values 1 through 6). However, the dice are marked as available dice and fixed dice. Initially, all dice are available. When the hand is “rolled”, only the available dice are rolled (receive new randomly generated values); the fixed values are not modified. If the maximum number of rolls has not yet been reached, the player can choose to “keep” some of the current available die values, which means their status is changed to be fixed so they won’t be modified by the next roll. Likewise, the player can choose to “free” any of the fixed values, so they will be re-rolled. All methods that return arrays containing dice must return the values in ascending order, according to the DieComparator.

After the maximum number of rolls is reached, all dice are automatically fixed and the hand can no longer be modified. A new hand must be created for the next round.

See the javadoc for details. Also note that the client normally obtains a new Hand using the method createNewHand in the DiceGame class, not by calling the Hand constructor directly. (You can see how this works by reading at the doOneTurn() method of the sample UI.)

Hand example. Suppose we display a hand as a string, listing first the available dice and then the fixed dice in parentheses. For example, in a game with 5 dice, after the first roll we might see the values such as this:

2 3 3 4 6 ()

Depending on which scoring categories you need to fill, you might decide to keep 2, 3, and 4 (perhaps in the hope of completing a straight). Then you have

3 6 (2 3 4)

On the next roll, the 6 and the other 3 are then replaced by random values, but the 2, 3, and 4 you selected remain fixed. If (for example) you now roll a 2 and a 5, you would have

2 5 (2 3 4)

At this point you might choose to keep the 5 (to make a small straight, maybe hoping the next roll will give you a large straight). Then you would have

2 (2 3 4 5)

Suppose that, as in the traditional game, you get a maximum of three rolls; in that case (for example) if you now rolled a 4, youd end up with

(2 3 4 4 5)

That is, when you reach the maximum number of rolls, all dice are automatically fixed. Once all dice are fixed, we say the hand is complete. At this point in the game, the player chooses one of the scoring categories and uses the completed hand to fill that category.

Scoring categories

A scoring category represents one row of the score sheet. A ScoringCategory object stores the actual score for that category along with the hand that was used to fill the category. A given category object also contains the algorithms needed to a) determine whether a given hand satisfies the criteria defined for the category (e.g., is it a straight, or three-of-a-kind, or whatever), and b) determine what the potential score would be for a given hand, if it were used to fill that category.

There are many different possible categories, each with its own particular algorithms. For example, the traditional game has a three-of-a-kind category: a hand satisfies the category if it contains any three numbers that are the same, and it is scored by summing the values of all the dice. The traditional game also has a large straight category: a hand satisfies the category if it has 5 consecutive values, and it always receives a fixed score of 40.

This is where polymorphism becomes useful. The client using this code (e.g., think of the “client” as the text-based UI provided in the sample code) does not care about the details of what the categories are or how each category calculates its score. The client just needs to be able to invoke methods on a category to find out whether a given dice group satisfies it, what the score would be, and to inform the category when it has been selected to be filled by a given hand.

Therefore, a scoring category is defined by an interface, called ScoringCategory. This interface is already written and you should not modify it. See the javadoc for detailed descriptions of the methods. See the text-based UI to see how it is used from the clients point of

view. In particular, you can see in the printCategories method where the UI just iterates over the categories and displays the potential score or actual score from each one.

There are nine concrete subtypes of the ScoringCategory interface that you are required to implement in package hw 4 , as listed above. However, a class need not implement the interface directly : it could instead extend some other class that implements ScoringCategory. If you just add the declaration implements ScoringCategory to each of these classes and then write all the required methods, you would find yourself writing much of the same code over and over again. Even though there are several different algorithms involved in the different classes (e.g. three-of- a-kind vs. a large straight), there is also a lot in common between the classes. You should carefully think about how to design an inheritance hierarchy so that you can minimize duplicated code between the classes. You might think about starting with an abstract class containing features that are common to all category types, such as isFilled() or getHand(). There are additional opportunities for sharing code to think about too. Are there code similarities between large straight and small straight that you can exploit? How about between “all the same kind” and “all but one of the same kind”? How about between categories that always have a fixed score, or categories where the score is always the sum of the die values?

A portion of your grade on this assignment (roughly 15% to 20%) will be determined by the logical organization of classes in this hierarchy and by how effectively you have been able to use inheritance to minimize duplicated code. As part of this effort you must include a brief statement, as part of the javadoc at the top of your DiceGame class, explaining your design decisions. See the documentation and style section.


A DiceGame instance is pretty simple: it encapsulates some configuration information (the number of dice, the maximum value (number of die faces), and the number of rolls allowed in a round) along with a list of categories. There is no other state information required, since each category object keeps track of the score for that category. The method for returning the total game score just needs to iterate over the scoring categories to add things up.

One feature that may not be obvious is the method createNewHand(). This method constructs and returns a new Hand object that is based on the attributes of that particular game instance. This way, a client does not have to separately keep track of the number of dice, maximum value, or number of rolls in order to correctly create new hands; that information is only stored in the

game object. See the UI method doOneTurn for sample usage.


The getAllDice , getAvailableDice , and getFixedDice methods of Hand are required to return arrays that are sorted in a particular order, defined by the DieComparator class. See the javadoc for details. DieComparator implements the Comparator interface. Using a Comparator is similar to using a class that implements Comparable. That is, there is a comparison function

public int compare(Die left, Die right)

that returns a negative number if left comes before right , a positive number if left comes after right , and zero if they are the same. The difference is that instead of the comparison function being built into the class as with Comparable , it is a separate object that is passed in to the sorting algorithm. If dice was an array of Die objects, you could sort it using the following:

DieComparator comp = new DieComparator(); Arrays.sort(dice, comp);


(Note that the class GameFactory is already implemented and is in the default package. However, you can add to it as you wish for testing and experimentation.)

This class has some static methods for creating various games. You can take a look to see how the game constructor is used and how the categories are added to a DiceGame object. This class is used in the sample UI.

Note that in the sample code, all the calls to the constructors of the ScoringCategory implementations are commented out. Thats because this code wont compile until you actually have implementations of the classes that are named there that are subtypes of ScoringCategory. As you complete the implementations, you can start uncommenting the constructor calls to try them out (and uncomment the import statements too).

The sample code

The sample code is an Eclipse project that you can import. See the instructions given for homework 3 (page 15) if you dont remember how to import a project. There are skeletons present for the Hand , DiceGame and DieComparator classes in package hw 4. The TextUI and GameFactory classes are in the default package, and the ScoringCategory interface and Die class are in the api package. Do not modify the code in the api package.

About the UI

There is a sample user interface TextUI provided in the default (top-level) package of the sample code. This code will not run until you have implemented the DiceGame and Hand classes, and you will not be able to play a game until you have started implementing the necessary scoring categories for the game you want to play. As you implement and test the categories, you can uncomment the corresponding constructors (and add appropriate import statements) in the GameFactory.

This is a text-based UI using clunky console I/O. It is not as slick as a graphical UI, but has the advantage that the code is entirely comprehensible, so you can read it to see how the other classes in the application are used.

A typical screenshot of a game in progress is shown below. The dashed lines in the second column indicate the categories called “Sixes” and “Three of a kind” are already filled, and the rightmost columns show the score and the hand (list of die values) that was used to fill the category.

**Potential scores for this roll:

  1. 1 Aces
  2. 2 Twos
  3. 3 Threes
  4. 4 Fours
  5. 0 Fives
  6. — Sixes 12 (1 2 3 6 6)
  7. — 3 of a kind 15 (2 2 2 4 5)
  8. 0 4 of a kind
  9. 0 Full House
  10. 30 Small Straight
  11. 0 Large Straight
  12. 0 Yahtzee
  13. 16 Chance

SCORE: 27**

You rolled 1 6 (2 3 4)

Press ENTER to roll available dice, or: a) keep all b) select dice to keep c) select dice to free Your choice:

The You rolled… shows the state of our current hand. Since the parentheses are nonempty, we must have previously chosen to keep the 2, 3, and 4 from the previous roll, and we just rolled a 1 and a 6. The second column in the list above shows us what potential score we would get in each category for this roll as it stands (e.g. 30 points if we use it to fill the “Small Straight”

category, or 16 points if we use it for the “Chance” category). One of our options might be to keep the 1 and reroll the 6 in the hope of getting a 5 (that would be a large straight).

You can edit the UI main method to 1) choose a seed for the random number generator, in case you want the dice results to be reproducible while you are developing the code, and 2) to get a different game from the GameFactory. To set up a different game from those constructed in the GameFactory , add another static method to GameFactory. (The “factory” keeps the UI from having any direct dependence on any of the specific ScoringCategory classes, so it will continue to work correctly even if you add new or different categories.)

Testing and the SpecChecker

As always, you should try to work incrementally and write tests for your code as you develop it. Please do not put your test code in the hw 4 package.

Do not rely on the UI code for testing! Trying to test your code using a UI is generally slow and unreliable_. In particular, when we grade your work we are NOT going to run the UI, we are going to test that each method works according to its specification._

We will provide a basic SpecChecker, but it will not perform any functional tests of your code. At this point in the course, you are expected to be able to read the specifications, ask questions when things require clarification, and write your own unit tests.

Since the test code is not a required part of this assignment and does not need to be turned in, you are welcome to post your test code on Piazza for others to check, use and discuss.

The SpecChecker will verify the class names and packages, the public method names and return types, and the types of the parameters. If your class structure conforms to the spec, you should see a message similar to this in the console output:

x out of x tests pass.

Note that spec conformance can only be checked for the ten required classes listed at the beginning of this document that are known to the specchecker. Remember that your instance variables should always be declared private , and if you want to add any additional helper methods that are not specified, they must be declared private as well.

This SpecChecker will also offer to create a zip file for you. Note that it will look for the 10 required classes, but it will also zip up all other java files in your hw 4 directory. Thus the archive should include any additional classes you added to your inheritance hierarchy, and should NOT include extraneous or unnecessary files such as your unit tests.

See the document SpecChecker HOWTO, which can be found in the Piazza pinned messages under
Syllabus, office hours, useful links if you don't remember how to import and run a SpecChecker.

Suggestions for getting started

General advice about using inheritance: It may not be obvious how to go about defining an inheritance hierarchy for the required subtypes of ScoringCategory. A really good way to get started is to forget about inheritance at first. That is, pick one of the required concrete types, such as CountOccurrences , add the clause implements ScoringCategory to its declaration, and just write the code for all the specified methods. Then, choose another required type and write all the code for that one. At this point you’ll notice that you had to write some of the same code twice. Move the duplicated code into an abstract superclass that can be extended by all types of categories.

That’s a good start, and you can use a similar strategy as you implement the other category types: Write the code first, then look for places where you’ve got similar code in multiple classes. Does it make sense to define one of them as a subclass of the other? Or, should the duplicated code be in a common superclass?

There is not necessarily any one, perfect way to make these decisions. All “good” solutions will involve some tradeoffs. Part of the assignment (see “Special Documentation Requirement”, below) is for you to provide a brief statement at the top of DiceGame.java that explains your design decisions.

  1. The DiceGame class is very straightforward and doesnt really depend on anything else you’re implementing other than the first Hand constructor, so you can work on it independently. It should depend only on the interface ScoringCategory , not on any of the concrete category implementations. (In order to test it, however, you’ll need at least one concrete category that you can put into it. See the GameFactory for sample usage.)
  2. Hand can also be developed and tested independently. You might start with the three- argument constructor, in which all dice initially have value 1. Try something like this:

Hand hand = new Hand(5, 6, 3); System. out .println(hand.getNumDice()); // expected 5 System. out .println(hand.getMaxValue()); // expected 6 Die[] dice = hand.getAllDice(); System. out .println(Arrays. toString (dice)); // [1, 1, 1, 1, 1] int[] values = hand.getAllValues(); System. out .println(Arrays. toString (values)); // [1, 1, 1, 1, 1]

You'll need to take a look at the Die class to see how to construct Die objects. It is
completely up to you how you want to implement the Hand class, but you can see you'll need
to be able to return an array of the Die objects in the hand, or to return an int array of their
values. (Notice that the toString method of Die is overridden to return the current die value
as a string, so the two outputs above actually look the same. The distinction will be more
clear once you implement a bit more of Hand .)
  1. For testing your categories, you will want to use the Hand constructor that takes an int array, so you can specify starting values. Try getting this to work:

int[] test = {4, 3, 3, 1, 3}; Hand hand = new Hand(5, 6, 3, test); Die[] dice = hand.getAllDice(); System. out .println(Arrays.toString(dice); // [1, 3, 3, 3, 4] int[] values = hand.getAllValues(); System. out .println(Arrays. toString (values)); // [1, 3, 3, 3, 4]

The API requires that the getAllValues method of Hand return int array that is sorted
in ascending order. You do not need to implement your own sorting algorithm, just use
Arrays.sort or Collections.sort.
(The API also requires that getAllDice (as well as getAvailableDice and
getFixedDice ) return a Die array that is sorted using the rules of DieComparator , which
you will be implementing. This does not need to be done right away, since you can
develop the category types just using getAllValues , but your output from printing
the Die array may be different from that shown above until you implement the
comparator and sort the array. See the earlier section on DieComparator for more
4. Although the scoring categories depend on Hand , they can be individually developed and
tested with just a simplified, partial implementation of Hand. Within a given scoring
category implementation, the only method of Hand you really need is either getAllDice() or
getAllValues(). (The distinction between fixed and available dice is not relevant for the
scoring category implementations, nor is the ability to roll the dice.).
5. For the scoring categories, you might start with something like CountOccurrences.
Create the class and include the clause implements ScoringCategory and create stubs for
the required methods. Write a couple of simple test cases and start to implement the
methods. (You may later move some of this code into an abstract superclass shared by
multiple scoring categories, but this is a good place to begin.) For example, here is a simple

int[] test = {4, 3, 3, 1, 3}; Hand hand = new Hand(5, 6, 3, test);

ScoringCategory cat = new CountOccurrences(“Count threes”, 3); System. out .println(cat.isSatisfiedBy(hand)); // should be true System. out .println(cat.getPotentialScore(hand)); // should be 9 System. out .println(cat.getScore()); // should be zero cat.fill(hand); System. out .println(cat.getScore()); // should be nine

(For the moment, ignore the business in the fill() documentation about
IllegalStateException .) You can start on the other categories in a similar way.
Remember that a hand does not always have five dice and the numbers on the dice may
not always be 1 through 6.
6. As noted above, you can develop and test all the categories with just that minimal
implementation of Hand. Of, course, at some point you'll need to finish the rest of the Hand
methods. As usual, start with some test cases and think about the expected behavior. Start
with getAvailableDice(), getFixedDice() , and keep(). Here is an example of the
behavior we need to start with:

int[] test = {4, 3, 3, 1, 3}; Hand hand = new Hand(5, 6, 3, test); Die[] avail = hand.getAvailableDice(); System. out .println(Arrays. toString (avail)); // [1, 3, 3, 3, 4] Die[] fixed = hand.getFixedDice(); System. out .println(Arrays. toString (fixed)); // [] hand.keep(3); hand.keep(1); avail = hand.getAvailableDice(); System. out .println(Arrays. toString (avail)); // [3, 3, 4] fixed = hand.getFixedDice(); System. out .println(Arrays. toString (fixed)); // [1, 3]**

The toString method of Die will also append a "*" if the die is set to be unavailable, so
once you have also implemented the keep method you could try:

Die[] all = hand.getAllDice(); System. out .println(Arrays. toString (all)); // [1, 3, 3, 3, 4]**

Another useful way to display a hand is with the utility method handToString in the UI (this
requires you to have implemented getAvailableDice and getFixedDice ):
System. out .println(TextUI. handToString (hand)); // 3 3 4 (1 3)
7. Note that the roll method of Hand takes a Random as an argument. Likewise, the Die
class has a roll method that takes a Random as an argument. It is a requirement that the
roll method of Hand calls the roll method of each available die using the same Random
object as its argument. For testing, you can specify a Random with a known seed to make
your test results reproducible. Here's a simple example,

// try rolling the hand above Random rand = new Random(99); hand.roll(rand); all = hand.getAllDice(); System. out .println(Arrays. toString (all)); // [1, 2, 3, 3, 4] System.** out .println(TextUI. handToString (hand)); // 2 3 4 (1 3)

Notice that the two fixed dice are not changed. Since the Hand was constructed with 3 as the
max number of rolls, if we roll the hand two more times then all dice should be fixed.

hand.roll(rand); hand.roll(rand); all = hand.getAllDice(); System. out .println(Arrays. toString (all)); // [1, 3, 3, 3, 5] System.* out .println(TextUI. handToString (hand)); // (1 3 3 3 5) System. out .println(hand.isComplete()); // true

8. Once you have DiceGame , Hand , and CountOccurrences , you can uncomment the
constructor in the createReallyTinyGame() method of the GameFactory. Then, you can
run the UI and play the Really Tiny Game! Likewise, as you complete and test each of the
scoring categories, uncomment the relevant constructor from one of the games in
GameFactory and try it out.

Other implementation notes

1. The API for the fill() method specifies that it throws an IllegalStateException
under certain conditions. Java Exceptions will be covered in detail during the last week of
classes, but for this problem all you need to do is this: at the beginning of the method, write

if (isFilled() || !hand.isComplete()) { throw new IllegalStateException(); }

Special documentation requirement

You must add a comment to the top of the DiceGame class with a couple of sentences explaining how you decided to organize the class hierarchy for the scoring categories.

Special style requirement

You may not use public , protected or package-private variables. Normally, instance variables in a superclass should be initialized by an appropriately defined superclass constructor.

You can create additional protected getter/setter methods if you really, really need them.

Style and documentation

Roughly 15% of the points will be for documentation and code style, including the Special documentation requirement described above. Please refer to the Style and documentation section of homework 1 for general guidelines about documentation. Note the following for this assignment in particular:

  • Add @author tags to each file that you create or modify
  • You do not need to rewrite existing javadoc in the skeleton code. You do need to javadoc instance variables and helper methods that you add, as usual.
  • You should provide class javadoc with @author tag for all classes you add to the hw 4 package (including the nine required types)
  • Methods that are documented in an interface or superclass normally do not need to be documented again when you implement the interface or extend the class (unless you have substantially modified the behavior to the point that the original documentation is incorrect).
  • Some of the loops you write may be tricky. You are expected to provide internal, //-style comments to explain what you are doing. If you had to think for a few minutes to figure out how to write the code, it probably needs a comment to make it clear to the reader! Internal comments always come BEFORE the code they describe and are indented to the same level.

What to turn in

Note: You will need to complete the “Academic Dishonesty policy questionnaire,” found on the Assignments page on Canvas, before the submission link will be visible to you.

Please submit, on Canvas, the zip file that is created by the SpecChecker. The file will be named SUBMIT_THIS_hw 4 .zip. and it will be located in whatever directory you selected when you ran the SpecChecker. It should contain one directory, hw 4 , which in turn contains a minimum of twelve files described in the “Summary of Tasks” section (plus any other classes you’ve added to the hierarchy).

Please LOOK at the file you upload and make sure it is the right one!

Submit the zip file to Canvas using the Assignment 4 submission link and verify that your submission was successful. If you are not sure how to do this, see the document “Assignment Submission HOWTO”, which can be found in the Piazza pinned messages under Syllabus, office hours, useful links.

We recommend that you submit the zip file as created by the specchecker. If necessary for some reason,
you can create a zip file yourself. The zip file must contain the directory hw 4 , which in turn should contain
the the required .java files. You can accomplish this by zipping up the src directory within your project.
Do not zip up the entire project. The file must be a zip file, so be sure you are using the Windows or
Mac zip utility, and NOT a third-party installation of WinRAR, 7-zip, or Winzip.