CS151 – Fall 2007: Programming Project 3

Due: Monday, October 8, 2007 28, 11:59:59:999 p.m. EST

 

In this project you will implement the PlayingCard class we have used in class for a number of examples.  You will also implement a BlackJackHand class to model a hand in the popular card game of Black Jack.  We will not concern ourselves with how to store the cards in a hand to simplify matters.  Later on if we actually implement the entire game we can deal with that detail.  Implementing these classes will give you more practice in class structure, implementation, and the conditional if statement we have started to discuss in class.  The project is based on Exercise P5.2 on p. 197 from your textbook (you can find a nice table of the card codes there).

 

To assist you in your task I will provide you with skeletons of both classes.  Additionally, I will give you tester classes that I found to be useful in my implementation.  Use them, modify them, or ignore them as you wish.  You can download the compressed file containing the project with these classes here.

 

NOTE: To see the entire output of the PlayingCardTester class' main method you may need to select "Unlimited buffering" from the Options menu when the Terminal window is active (love those context sensitive menus!).

 

PlayingCard Class

Please do not change the names of any public methods or instance variables (constants), or the order or type of any method parameters.  Doing so makes more work for the graders: bad for you and me.  You may change the name or type, or omit any private methods or instance variables.  You may also change the parameter names for any method to names more meaningful to you.  Add any additional private or public instance variables or methods you need to implement the methods specified in the skeleton.  Also add comments and @param and @return tags to support generation of web documentation for the methods and any public constants.

 

Additional Details:

1.        Both constructors should explicitly initialize all instance variables to an appropriate default value (you may wish to make these defaults class constants).  Note that the value of the cards is determined by the game played with them.  Consequently, the game itself will determine (assign them) their values, but you should initialize them to some default value.  Do not leave instance variables with null values, especially if you add additional instance variables.

a)        One constructor takes a single String parameter that denote a code for a card, e.g. the string "AH" should produce an Ace of Hearts card.  Note that "Ah", "ah", and "aH" should all create the same card, i.e. the codes need not be given in uppercase, but I recommend storing them as upper case.

b)        The other constructor takes two String parameters: the first is a code for the rank and the second is a code for the suit, e.g. PlayingCard("AH") and PlayingCard("A","H") both should produce an Ace of Hearts.

 

2.        The following get methods and set method should be self explanatory

a)    getRank(): return the rank code as an upper case String

b)    getSuit(): return the suit code as an upper case String

c)         getValue()

d)        setValue()

 

3.        Implement the following three methods by adding a (boolean) instance variable to your class and using it in them (don't forget to initialize it in your constructors).

a)    isFaceUp()

b)    isFaceDown()

c)         flipOver()

 

4.        The getDescription() method should return a nicely formatted string of the form "Ace of Clubs" if the card is created using the code "AC".  I have supplied class constants for each rank and suit code as well at their labels.  Please use these and don't change them or the syntax of the output of this method.  Again, if everyone's method outputs the same phrase, testing and grading is greatly simplified.  You may use the following two private methods if you wish to help implement your getDescription() method, but they aren't required. The method should return the contents of the constant UNKNOWN_CARD_PHRASE and nothing more if either the suit or rank code is invalid.

a)        getRankDescription()

b)    getSuitDescription()

 

5.        [Optional/extra credit choices]

a)    Expand/extend the suit and rank notation to allow for two Joker cards.  The two jokers should be distinguishable from one another by their description.  Add and document PlayingCard class constants for the Joker ranks and suit and descriptive labels for them.  Modify your getDescription() method to print out a nicely formatted string of the form "Red Joker"/"Black Joker" or "Big Joker"/"Little Joker" for example.  Also add a method called isJoker() that returns a boolean.  It should return true if the card is one of the two Jokers and false otherwise.  See http://www.usplayingcard.com/gamerules/glossary-index.html for a Joker terminology

b)        Create a drawing for your cards and add a display() method that shows the card in a graphical window.

c)         Your ideas.

 

 

BlackJackHand Class

Please do not change the names of any public methods or instance variables (constants), or the order or type of any method parameters for the reasons previously stated.  Again, you may change the name or type, or omit any private methods or instance variables.  You may also change the parameter names for any method to names more meaningful to you.  Add any additional private or public instance variables or methods you need to implement the methods specified in the skeleton.  Also add comments and @param and @return tags to support generation of web documentation for the methods and any public constants.

 

Additional Details:

1.        Both constructors should explicitly initialize all instance variables to an appropriate default value (you may wish to make these defaults class constants).  Do not leave instance variables with null values, especially if you add additional instance variables.

a.        One constructor takes no parameters and sets the instance variables (numberOfCards and value and whatever others you add) to some default values.

b.        The other constructor takes two int parameters: this first is the number of cards in the hand, and the second the total value of the hand.

 

2.        The following get methods should be self-explanatory and depend on the number and type of cards that have been added to the hand.

a.    getNumberOfCards()

b.        getValue() (note this is different from the method of the same name in the PlayingCard class)

                 

3.        The addCard() takes a single parameter, a PlayingCard and adjusts the value and number of cards in the hand accordingly.  More precisely, the number of cards should increase by one for every card added and the value of the hand should increase by the value of the card being added where the card values are class constants in the BlackJackHand class.  So for example if a card has two cards in it and a value of 7, then after adding the Ten of Diamonds to the hand using hand.addCard(),getNumberOfCards() and getValue() when called on that hand should return 3 and 17, respectively (see the BlackJackHandTester class for more details).

NOTE: You should not worry about hanging onto or managing the cards that have been added to the hand.  You only need to keep the number of cards and value of the hand.

NOTE: For simplicity treat all Ace cards as having a value of 11.  See the extra credit list below for treatment of Ace as 11 or 1.

 

4.        [Optional/extra credit choices]

a)        Add a method called isBust() that returns a boolean.  It should return true if the value of the hand exceeds the maximum allowable hand value of 21 (as public class constant?) and false otherwise.

 

b)        Add a method called isFiveCardCharlie() that returns a boolean.  It should return true if the number of the cards in the hand is 5 and the value of the hand is less than or equal to 21 (the maximum allowable hand), and false otherwise.

 

c)         Modify the class to value an Ace card as 11 unless this would cause the value of the hand to exceed the maximum allowable value, i.e. to cause the hand to be a bust.  In that case value the Ace as 1 (even if this still causes the hand to bust).  Again you should not keep in any way the cards that have been added, but you may keep additional information about the hand as a whole.

HINT: Track the value of the hand and number of cards excluding Aces.

 

d)        Create a method called split() that works only if the hand has two cards of the same rank.  The method should return a BlackJackHand with one card and half the value of the hand you are splitting.  It should also change the hand from which it is called in the same way.  You may also want to create a boolean method isSplitable() to decide if a hand can be split or not.

Strategy and Hints

First implement the get and set methods and constructors and make sure they work before moving on to the more challenging methods.  No additional class methods other than the String class methods are needed.  You may use a series of nested if else if ... statement or the switch statement (see the tester classes and Advanced Topic 5.2 Internet content for your book).  Before trying to write the code for any method, try to work out what it is supposed to do on paper with some simple examples.

 

Start early and try to make a little progress each day.  Test early and often.  Sections 2.8, 3.6, and 5.5 of your book discuss different aspects of testing.  You can use BlueJ to test constructors and simple methods interactively.  The tester classes I provide should also help you find problems.  Make use of the online documentation, the lab TAs, your fellow classmates (to the extent allowed by the Collaboration Policy) and me early and often.  Don't put it off until the last minute.

Style and Documentation

All constructors, methods, and public instance variables should be commented using @param and @return tags to facilitate the generation of .html documentation similar to the Java Class Libraries on the Web via the Javadoc utility.  BlueJ automatically generates this documentation for your class when you switch from "Implementation" to "Interface" in the class editor window.  We've discussed the use of these tags in class and additional information is in section 3.3 of your textbook. 

 

Your code should adhere to the stylistic guidelines we have been discussing and which are in Appendix A of your textbook as much as possible.  In particular group different constructors, instance variables, and similar methods together.  Use meaningful variable names and internally comment your code liberally (with // or /*   */ pairs).

 

The graders will be instructed to determine approximately 10-15% of your project grade based on style, readability, and documentation.  Please use indentation, white space, and other stylistic techniques to make your code easier to read (and grade).

Project Submission

You will again submit your projects electronically.  To do so

1.        Connect to the Academics volume of the server called fileserver1.  From a Mac choose "Connect to Server ..." from the "Go" menu in the Finder, type afp://fileserver1 in the dialog box, and select Academics from the volume list.  From Windows machine open Windows Explorer, select "Map Network Drive" from the tools menu, pick a free drive letter and type \\fileserver1\Academics or just type it directly into the address filed.  When prompted for your user name and password, type COLBY\username, where username is your Colby username and enter your password.  These instructions are adapted from http://www.colby.edu/administration_cs/its/support/fileserver1.cfm. 

2.        On the Academics volume inside of the COMP/CS151 folder/directory you will see a folder with your Colby e-mail/login name and within that a private folder.  Copy your PlayingCard.java and BlackJackHand.java files from your project directory to your private folder.  DO NOT submit a .zip file, a project directory or any other files. If you attempted some part of the extra credit please also include a brief readme.txt file explaining what additional functionality you have added and would like the graders to evaluate.  Just copy these files to the private directory right from your project directory.

 

Acknowledgement

As indicated in the preface, the card coding scheme is from Exercise P5.2 on p. 197 of Java Concepts for Java 5 and 6, 5th Edition by Cay S. Horstmann.