Starfish Card Games Simulator
In this project, you will utilize both
Java's ArrayList
This project will have you designing and implementing several related classes; a deck of cards and some game evaluation methods. The deck and games bear some similarities to a standard deck of cards and the games of Poker and Blackjack but there are differences; these are for the Starfish Casino, soon to open in Ocean City. You don't (and unless you hail from the vicinity of where SpongeBob lives, can't) have previous experience with this deck and these games. We'll explain everything! As always, you will have starter files provide and this document will specify the specifications for the methods. There is a GUI provided to allow you to "see" the deck to provide some help in debugging errors related to the deck, but JUnit testing will be your friend for much of this project!
You will design and implement one Java data structure class (the Deck which represents a deck of cards) using an ArrayList<Card> to store and manipulate the contents of the deck as well as HandEvaluatorSFCP, which contains several static methods that evaluate the contents of arrays of 5 cards to determine which "Starfish Poker" hand(s) are represented and HandEvaluatorPatrickjack, which contains two static methods that evaluate the contents of ArrayList objects connected to the game of Patrickjack. as well as a series of JUnit tests in another class.
If you are not familiar with the Starfish deck of 45 playing cards (which you aren't) and the terminology that goes along with it ("suit", "Ace", "clubs", etc.), then you'll need to take a look at the Playing Card Page.
Before you get started, you should read the JavaDoc for the Card class. You will use this class while writing your classes.
We provide a class called StarDeckException to create a new RuntimeException for use by the Deck.
The Deck class represents a deck of cards. It starts off with 45 cards, but as cards are dealt from the deck, the number of cards (and the ArrayList<Card> that holds them) becomes smaller.
The class has one private instance variable that stores the ArrayList<Card> of references to Cards that are currently in the Deck: You must use the ArrayList for this class. You may not add any arrays to this class except one place; the array that deal returns.
private ArrayList<Card> cards;
Important Note: The first Card in the ArrayList will be considered the card that is at the top of the deck. When cards are removed from the deck they will be removed from the front of the ArrayList.
You must implement the following methods for the Deck class:
public Deck() -- This constructor initializes the Deck with references to 45 card objects, representing the 45 cards that are in a standard Starfish deck. The cards must be ordered as in the diagram below:
Important: The FIRST card in your ArrayList<Card> must be the Ace of Spades, and the LAST card should be the Nine of Stars. Note that in the picture above, the Ace of Spades is at the TOP of the deck, which is to the left.
public Deck(Deck other) -- Standard copy constructor. Note that it is okay to make a shallow copy of the ArrayList<Card> of cards. (The Card class objects are immutable, so aliasing Card objects is not a problem.)
public Card getCardAt(int position) -- Returns a reference to the card that is at the specified position in the ArrayList<Card>. (Uses the usual 0-based indexing.) For this project you can assume only legal requests will be made.
public int getNumCards() -- Returns the size of the ArrayList<Card> of Card references. (It starts off equal to 45, but becomes smaller as cards are dealt from the deck.)
public void cut(int position)-- This method divides the deck into two logical subpackets: The part above the specified position, and the part that is at the specified position or below. The Starfish Casino has a rule that you can't cut a deck in a way that either the "top" or "bottom" packet has fewer than 3 cards in it. If the cut method is called with a value that would violate this rule, the method will need to throw a new StarDeckException with the message "Too few cards in one part of the cut." inside it. However, if it is a valid cut request, the two subpackets are reversed (the top packet is placed on the bottom and the bottom packet is placed on the top.) The position value uses 0-based indexing as usual, so the card at the top of the deck (to the left in the diagrams) is at position 0. Think about how you can take advantage of the ArrayList object's ability to add and remove individual cards to/from specific positions. While we will not be having a drawing/pseudocode element to this assignment, there are several places (like here) where drawing out a picture of a deck with (for example) only 8 or 9 cards and tracing on that before you start writing code will be very useful. Here is an example of a deck being cut:
Before cut
After cutting by clicking on position 4 (which is the 5th card if you count starting from 1). (So, we clicked on the 5 of spades, which was at position 4 in the diagram above.)
public Card[] deal(int numCards)-- This method will remove the specified number of cards from the top of the deck and return them as an array. For example, if the parameter is 4, then the first four cards in the deck will be returned as an array of size 4. This is the one place in this class where an array is used. Important: The cards will be removed from the front of the "cards" ArrayList, not the back. As with the cut method, drawing some pictures and thinking about the add/remove options the ArrayList object provides will help make this a smoother section of code to design and implement. For this project you can assume only legal requests will be made.
public void shuffle() -- If the deck at the time this method is called has fewer than 5 cards it does nothing. Otherwise, this method will re-arrange the cards that are in the deck. Since our Starfish dealers have 5 arms, the idea is that the deck will be divided into five "packets" of the same size, except the 5th packet which might have a few extra since the deck at the time of shuffling might not contain a number of cards evenly divisible by 5. Handling the shuffling of a deck size that is not evenly divisible by 5 is a CHALENGE PROBLEM. The new ArrayList of cards representing the deck will consist of: the first card from the 5th packet, followed by the first card from the 4th packet, followed by the first card from the 3rd packet, followed by the first card from the 2nd packet, followed by the first card from the 1st packet, followed by the second card from the 5th packet, followed by the second card from the 4th packet, followed by etc. Important: The top of the deck is considered to be the front of the array, and the 1st packet will be the topmost "fifth" of the deck and the 5th packet will be the bottom "fifth" of the deck, but could be larger than the other "fifths" of the deck if the number of cards in the deck isn't evenly divisible by five. For the challenge, if the deck is not evenly divisible by 5, the 5th packet has more cards (the decksize % 5 tells you how many extra it has). Just place these in reverse order at the end of the newly shuffled deck.
In the pictures below, remember that the top of the deck appears at the left side.Below are two examples of how the shuffle should work:
Example 1 (number of cards evenly divisible by 5):
Before Shuffling
After Shuffling
Example 2 (two cards short of being evenly divisible by 5):
Before Shuffling
After Shuffling
Read the Patrickjack Page. To successfully implement the Patrickjack evaluation part of this project you need to know the rules of how values are assigned to these hands very precisely so read this information carefully!
This class consists of two static methods that you will write. The prototypes for the methods are:
Read the Starfish Poker Hand Page. To successfully implement the Starfish Poker hand evaluation part of this project you need to know the definitions of these hands very precisely so read this information carefully!
This class consists of several static methods that you will write.
Each method can assume that the array passed into it has
exactly 5 elements.
The prototypes for the methods (in the order we think you should work on them)
are:
The parameter for each of these
methods will be an array of exactly 5 cards. Each method will return true
or false, based on whether or not the given set of cards satisfies the poker
hand being evaluated in the method. For example, the hasTwoPair method
will return true if the set of cards has two pairs of different values (e.g. a
pair of 4's and a pair of Nine). If you need to review the various "poker
hands" being tested in the methods, please take another look at the
Starfish Poker Hand Page. Important:
Each of these methods checks whether or not the set of cards satisfies the
given poker hand, but it does not care if it could also satisfy a better
hand.
<Ace of diamonds, Ace of spades,
Ace of hearts, Nine of Spades, Nine of Diamonds>
then the results of calling
each method should be as indicated below: hasPair -- true
(there is at least one pair) hasRainbow -- false
hasTwoPair -- true (there are
two pairs of distinct values) hasThreeOfAKind -- true (there are
three Aces) hasStraight -- false hasFlush -- false hasFullHouse -- true (there are
three Aces and two Nine -- that makes a "full house") hasFourOfAKind -- false hasStraightRainbow -- false hasStraightFlush -- false hasFiveOfAKind -- false Important: In order for a
hand to qualify as "Two Pair", it must have two pairs of distinct
values -- in particular, having four-of-a-kind or five-of-a-kind
do not also count as
two pair.
<2 of diamonds,
2 of stars,
2 of hearts, 2 of clubs,
9 of spades> then the results of calling
each method should be as indicated below:
For example, if the current hand is:
For example, if the current hand is:
hasPair -- true (there is at least one pair)
hasRainbow -- true (each suit is represented)
hasTwoPair -- false (there are not two pairs of distinct values)
hasThreeOfAKind -- true (there are three 2's)
hasStraight -- false
hasFlush -- false
hasFullHouse -- false
hasFourOfAKind -- true (there are four 2's)
hasStraightRainbow -- false
hasStraightFlush -- false
hasFiveOfAKind -- false
JUnit Tests
You are required to submit JUnit tests for all of the methods in the HandEvaluatorSFCP class and at least three eval scenarios for the HandEvaluatorPatrickjack class. Your tests should be as thorough as possible. Be sure that for each HandEvaluatorSFCP method you have written some tests where the method returns "true", and some tests where the method returns "false".
5% of your grade on this project will be determined by the thoroughness of the tests you write. Please note that in order to get any credit for a JUnit test, your project must pass the test AND it must be a proper test of what we have requested. You will place your JUnit test methods into the file provided called "StudentTests.java" in the p6Testing package. If the tests are not located in this file in this package, you will not get credit for them.
Requirements
Project Submissiong
Submit your project from Eclipse by right-clicking the project folder and selecting "submit project". You may incrementally submit as many times as you feel is useful since we will only grade the submission that scores the highest on the automated tests. Remember, after you have submitted your project, you should visit the submit server. As always, you will be able to obtain some feedback about how well your project is performing. Again, as usual on projects, the number of times you can run our release tests on your project (before the due date) is limited. The earlier you begin working on the project, the more opportunities you will have to see how your project performs on our release tests before the due date!
To run the simulation execute the main method in the Launcher.java class. This will allow you to do simple testing of building a deck, cutting the deck, and dealing a single card from the deck. You can cut the deck by clicking somewhere in the middle of the deck. Deal is accomplished by clicking the button. However, this is limited and most testing should be done via JUnit and the submit server.
Grading
Please note, there are public tests and release tests for both things related to the Deck and things related to hands. It is strongly suggested that you run the Release tests when you think you are done with your Deck (for example) rather than waiting until all of the Public tests (for both deck-related and hand-related things) are passing. The submit server for this assignment will allow you to run the Release tests even when some Public tests are still not passing.
Your grade will be computed as follows with the exception being that if any of the classes violate the rules given above, we will go in and remove submit server points connected to any class that was not written according to the restrictions stated about things like arrays and ArrayLists.