Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

We endeavor to set up some classes that involve playing card games with a human or simulating card games entirely by a computer. There are

We endeavor to set up some classes that involve playing card games with a human or simulating card games entirely by a computer. There are two basic classes we'll need :

Card: A class like the one presented in the modules, but with a few changes.

Hand: A class that represents the cards held by a single player.

The codes for Card & Hand classes are given(See the bottom part)

Here are eight cards, each of which contains both a value ('A', '2', '3', ... 'T', 'J', 'Q',' K') and a suit (spades , hearts , diamonds , clubs ) image text in transcribed

Notice that I am using the char 'T' to describe the value 10. (Ignore the Joker, which we will not need.)

The dealer uses a Deck object to deal Hand objects to the players. The dealer may or may not be a player who gets a hand of his own (poker dealers in casinos don't receive a hand, but most other games involve the dealer getting a hand).

We continue to work on the card game effort, now adding the source of all cards for the various players, the Deck.

Deck: A class that represents the source of the cards for dealing and, as the game progresses, the place from which players can receive new cards (say, as they pick cards "from the deck" or when future hands are to be dealt from the same deck). Recall this picture, which relates the Deck to the various Hands that it creates through the process called "dealing":

image text in transcribed

Let's deconstruct the meaning of this important class.

Deck: A Deck object is the source of all cards. It's where the dealer gets cards to deal, and if a player takes an individual card after the deal, he takes it from the Deck object. Naturally, the primary member here is an array of Card objects, much like Hand. We'll call this member cards[]. A deck normally consists of a single pack of cards: 52 cards (four suits of 13 values each). However, some games use two, three or more packs. If a card game requires two packs, then the deck will consist of two full 52-card packs: 104 cards. (Many games throw away some cards before beginning. For example Pinochle wants all cards with values 8-and-below to be taken out of the deck, but we will not trouble ourselves with this complexity.) A newly instantiated deck will have a multiple of 52 cards and will contain all the standard cards, so the number of cards in a newly instantiated deck will be 52, 104, 156, ..., i.e., numPacks 52.

Clearly, we need an int like Hand's numCards, to keep track of how many cards are actually in the cards[] array. To this end, we'll use topCard (not numCards), since a deck typically removes and delivers cards to players from the top-of-the-deck, and this is a convenient variable to use for the number of cards as well as the position of the top of the deck.

There are a few other useful members (numPacks, for example). In addition to the the usual constructors and accessors, we'll want a dealCard() to return and remove the card at the top of the deck (which may be received by a client and added to some player's hand), and a shuffle() to re-order the cards in a random fashion. Also, we'll need to restock the deck (init()) to the original full condition in preparation for a fresh deal (we would certainly not want to re-instantiate a new deck when we have a perfectly good one available: garbage collection, done by us or by the operating system, is a resource we do not abuse).

Phase 1: The Deck Class

Private Static Class Constants

Define a private final int value like MAX_PACKS = 6 , NUM_CARDS_PER_PACK = 52 , and MAX_CARDS_PER_DECK = MAX_PACKS * NUM_CARDS_PER_PACK. Use them to their full benefit in the class code.

Private Static Member Data

Card[] masterPack

This is a private static Card array, masterPack[], containing exactly 52 card references, which point to all the standard cards. It will enable us to avoid capriciously and repeatedly declaring the same 52 cards which are needed as the game proceeds. In other words, once we have, say, a ('6', spades) Card constructed and stored (inside this masterPack[]), we use that same instance whenever we need it as a source to copy in various places, notably during a re-initialization of the Deck object; it will always be in the masterPack[] array for us to copy.

Private Member Data

Card[] cards;

int topCard;

int numPacks;

Public Methods

Deck(int numPacks) - a constructor that populates the arrays and assigns initial values to members. Overload so that if no parameters are passed, one pack is assumed. This constructor can call a helper, allocateMasterPack() (see below), but that helper would only do something the very first time it gets called per program (no need to allocate a static array more than once per program, right?). It would then use another helper, init(), to assign the master pack Cards to the various cards[] elements.

boolean init(int numPacks) - re-populate cards[] with the standard 52 numPackscards. (This also gives the client a chance to change the number of packs in the deck in preparation for a new game.) We should not repopulate the static array, masterPack[], since that was done once, in the (first-invoked) constructor and never changes. The elements of the cards[] array can reference the masterPack[] objects -- that's safe since we will never give the client any of those objects to modify (see dealCard() on this issue). If numPacks is out-of-range, return false without changing the object; else return true and make the change.

void shuffle() - mixes up the cards with the help of the standard random number generator.

Card dealCard() - returns and removes (effectively, not physically) the card in the top occupied position of cards[]. Here we have to return a copy of the card, not the actual reference to the object in the cards[] array, since that object is also the object in the masterPack[] array, which the client must not be allowed to change.

An accessor for the int, topCard (no mutator.)

Card inspectCard(int k) - Accessor for an individual card. Returns a card with errorFlag = true if k is bad. Otherwise returns a copy of the card (see admonition for dealCard()).

Private Methods

static void allocateMasterPack() - this is a method that will be called by the constructor. However, it has to be done with a very simple twist: even if many Deck objects are constructed in a given program, this static method will not allow itself to be executed more than once. Since masterPack[] is a static, unchanging, entity, it need not be built every time a new Deck is instantiated. So this method needs to be able to ask itself, "Have I been here before?", and if the answer is "yes", it will immediately return without doing anything; it has already built masterPack[] in a previous invocation.

Recommended test of Class Deck

Declare a deck containing a single pack of cards. Do not shuffle. Deal all the cards in a loop until the deck is empty (dealt directly to the display/screen, not to any Hand objects just yet). Display each card as it comes off the deck. Next, reset the deck by initializing it again (to the same single pack). Shuffle the deck this time, and re-deal to the screen in a loop again. Notice that the cards are now coming off in a random order.

Repeat this double deal, unshuffled, then shuffled, but this time using a deck containing twopacks of cards.

Example Test Run of Card Class

/* ---------------------------------------------------------

A of spades / K of spades / Q of spades / J of spades / T of spades / 9 of spades / 8 of spades / 7 of spades / 6 of spades / 5 of spades / 4 of spade s / 3 of spades / 2 of spades / A of hearts / K of hearts / Q of hearts / J of hearts / T of hearts / 9 of hearts / 8 of hearts / 7 of hearts / 6 of hearts / 5 of hearts / 4 of hearts / 3 of hearts / 2 of hearts / A of diamo nds / K of diamonds / Q of diamonds / J of diamonds / T of diamonds / 9 of diamonds / 8 of diamonds / 7 of diamonds / 6 of diamonds / 5 of diamonds / 4 of diamonds / 3 of diamonds / 2 of diamonds / A of clubs / K of clubs / Q of clubs / J of clubs / T of clubs / 9 of clubs / 8 of clubs / 7 of clubs / 6 of clubs / 5 of clubs / 4 of clubs / 3 of clubs / 2 of clubs / K of spades / 9 of clubs / Q of hearts / T of diamonds / 9 of spades / 5 of hear ts / 2 of clubs / A of hearts / J of hearts / K of clubs / T of hearts / 4 of sp ades / 7 of hearts / 3 of spades / Q of spades / A of clubs / 8 of spades / 5 of clubs / T of clubs / J of spades / 2 of spades / 6 of diamonds / 2 of diamonds / 8 of diamonds / 4 of hearts / 2 of hearts / 6 of hearts / 5 of spades / 8 of h earts / 7 of diamonds / 7 of spades / Q of diamonds / K of hearts / J of diamond s / T of spades / 8 of clubs / 3 of diamonds / J of clubs / 6 of spades / 4 of c lubs / K of diamonds / 4 of diamonds / 3 of clubs / A of spades / 9 of hearts / Q of clubs / A of diamonds / 6 of clubs / 5 of diamonds / 7 of clubs / 3 of hear ts / 9 of diamonds / A of spades / K of spades / Q of spades / J of spades / T of spades / 9 of spades / 8 of spades / 7 of spades / 6 of spades / 5 of spades / 4 of spade s / 3 of spades / 2 of spades / A of hearts / K of hearts / Q of hearts / J of hearts / T of hearts / 9 of hearts / 8 of hearts / 7 of hearts / 6 of hearts / 5 of hearts / 4 of hearts / 3 of hearts / 2 of hearts / A of diamo nds / K of diamonds / Q of diamonds / J of diamonds / T of diamonds / 9 of diamonds / 8 of diamonds / 7 of diamonds / 6 of diamonds / 5 of diamonds / 4 of diamonds / 3 of diamonds / 2 of diamonds / A of clubs / K of clubs / Q of clubs / J of clubs / T of clubs / 9 of clubs / 8 of clubs / 7 of clubs / 6 of clubs / 5 of clubs / 4 of clubs / 3 of clubs / 2 of clubs / A of sp ades / K of spades / Q of spades / J of spades / T of spades / 9 of spades / 8 of spades / 7 of spades / 6 of spades / 5 of spades / 4 of spades / 3 of spades / 2 of spades / A of hearts / K of hearts / Q of hearts / J of he arts / T of hearts / 9 of hearts / 8 of hearts / 7 of hearts / 6 of hearts / 5 of hearts / 4 of hearts / 3 of hearts / 2 of hearts / A of diamonds / K of diamonds / Q of diamonds / J of diamonds / T of diamonds / 9 of diamond s / 8 of diamonds / 7 of diamonds / 6 of diamonds / 5 of diamonds / 4 of di amonds / 3 of diamonds / 2 of diamonds / A of clubs / K of clubs / Q of clu bs / J of clubs / T of clubs / 9 of clubs / 8 of clubs / 7 of clubs / 6 of clubs / 5 of clubs / 4 of clubs / 3 of clubs / 2 of clubs / 6 of diamonds / 7 of clubs / 9 of hearts / 4 of diamonds / 9 of diamonds / J of hearts / 3 of spades / 2 of clubs / J of clubs / A of hearts / J of cl ubs / Q of hearts / Q of diamonds / 7 of clubs / 2 of diamonds / 5 of clubs / K of spades / 5 of clubs / 5 of diamonds / 8 of hearts / 3 of clubs / 6 of hearts / A of spades / A of hearts / 4 of hearts / J of diamonds / A of clubs / 3 of diamonds / A of diamonds / K of diamonds / 6 of clubs / 4 of spades / 6 of hearts / 7 of spades / K of clubs / 3 of hearts / 3 of hearts / K of spades / Q of spades / J of spades / 7 of hearts / J of hearts / K of hearts / T of spades / K of clubs / 8 of hearts / 2 of spades / A of di amonds / 4 of diamonds / Q of clubs / T of diamonds / 7 of hearts / 9 of cl ubs / T of clubs / 7 of spades / 6 of spades / 6 of spades / K of diamonds / Q of spades / 7 of diamonds / Q of hearts / J of spades / 3 of clubs / 5 of hearts / K of hearts / 9 of spades / 9 of clubs / 2 of clubs / 7 of dia monds / 8 of diamonds / T of spades / 8 of clubs / 8 of diamonds / 8 of clu bs / T of diamonds / 4 of spades / 9 of hearts / A of spades / 8 of spades / 4 of hearts / T of hearts / 5 of diamonds / T of hearts / 5 of spades / 9 of diamonds / 5 of hearts / T of clubs / Q of diamonds / 6 of diamonds / 3 of spades / J of diamonds / 8 of spades / Q of clubs / 2 of diamonds / 2 of hearts / 6 of clubs / 2 of hearts / 9 of spades / 4 of clubs / 2 of spad es / 3 of diamonds / 5 of spades / 4 of clubs / A of clubs / --------------------------------------------------------- */

Phase 2: The Deck and Hand Classes

For your second test client, allow your Deck class to interact with your Hand class. Don't add anything to the two classes, but do everything in this phase from within your main() client.

Ask the user (interactively) to select the number of players (a number from 1 to 10). That's one question, one numeric answer, and no further user-interaction. Once you have a legal value, instantiate a single-pack Deck object without shuffling, deal a deck into that many Hand objects, dealing all cards until the deck is empty. Since the number of players chosen by the user may not divide evenly into 52, the number of cards dealt into the various hands might differ, but only by, at most, one. Display all the hands after the deal.

Reset the objects to their initial state, but this time shuffle the deck before a second deal (same # of players).

To be clear, dealing to hands means dealing a single card to each hand, until all hands have one card, then repeating to give all hands a second card, etc., until the cards are gone, and each hand has (nearly) the same number of cards. It does not mean dealing x cards to one hand, then x to the next hand, etc. This is very important.

You don't need any more classes than the ones we've already created, since there should not be that much to do in main().

Example of One of Possibly Many Test Runs of Deck + Card Classes

--------------- run #2 ----------------------------------

How many hands? (1 - 10, please): 6

Here are our hands, from unshuffled deck:

Hand = ( A of spades, 8 of spades, 2 of spades, 9 of hearts, 3 of hearts, T of

diamonds, 4 of diamonds, J of clubs, 5 of clubs )

Hand = ( K of spades, 7 of spades, A of hearts, 8 of hearts, 2 of hearts, 9 of

diamonds, 3 of diamonds, T of clubs, 4 of clubs )

Hand = ( Q of spades, 6 of spades, K of hearts, 7 of hearts, A of diamonds, 8 o

f diamonds, 2 of diamonds, 9 of clubs, 3 of clubs )

Hand = ( J of spades, 5 of spades, Q of hearts, 6 of hearts, K of diamonds, 7 o

f diamonds, A of clubs, 8 of clubs, 2 of clubs )

Hand = ( T of spades, 4 of spades, J of hearts, 5 of hearts, Q of diamonds, 6 o

f diamonds, K of clubs, 7 of clubs )

Hand = ( 9 of spades, 3 of spades, T of hearts, 4 of hearts, J of diamonds, 5 o

f diamonds, Q of clubs, 6 of clubs )

Here are our hands, from SHUFFLED deck:

Hand = ( J of diamonds, 9 of hearts, Q of spades, 5 of clubs, 8 of spades, 4 of

spades, T of diamonds, Q of clubs, K of clubs )

Hand = ( 4 of diamonds, 3 of clubs, T of spades, 5 of diamonds, 7 of diamonds,

8 of hearts, A of diamonds, 6 of diamonds, 3 of diamonds )

Hand = ( 7 of clubs, 6 of spades, K of diamonds, 6 of clubs, 8 of clubs, 5 of s

pades, 8 of diamonds, 4 of hearts, 4 of clubs )

Hand = ( T of clubs, 2 of diamonds, 6 of hearts, 2 of hearts, 9 of clubs, A of

clubs, K of hearts, A of spades, A of hearts )

Hand = ( 7 of spades, J of clubs, 9 of spades, 3 of spades, J of hearts, 5 of h

earts, K of spades, 3 of hearts )

Hand = ( 9 of diamonds, J of spades, 2 of spades, 2 of clubs, Q of hearts, T of

hearts, Q of diamonds, 7 of hearts )

--------------------------------------------------------- */

You will be graded, in part, on how efficiently you put together these two classes. Use what you know about arrays, loops, the methods available in the Deck and Hand classes -- even testing user input for valid in-range response -- to give a clean, short and completely tested client that proves that your Deck can feed the number of Hands requested by the user. There is some amount of creativity and variability allowed in this part, and any two correct solutions will look very different. You can implement this in any way that interprets the instructions. Yet, I can and will deduct when I see basic programming concepts misused, deduction amounts commensurate with the type of infraction.

Attention Please:

Always include both a source and (for console apps) a run.

Do not add or change any characters on the console output lines.

All mutators return boolean. Set methods or functions should return a boolean value, whether your client uses the return value or not.

Filter input. Any mutator, constructor, or other member method (function) that uses a passed parameter as a basis for setting private data, should test for the validity of that passed parameter - that means range checking, string length testing, or any other test that makes sense for the class and private member.

Use symbolic names, not literals. Never use a numeric literal like 1000, 3 or 52 for the size of an array, or the maximum value of some data member in your code. Instead create a symbolic constant and use the constant. In other words, use ARRAY_SIZE or MAX_CARDS, not 1000 or 52.

Avoid costly methods when simple operations can acheive the same result more efficiently. Examples: (i) Methods like Math.pow() should not be used for small integer powers (e.g. powers less than 4). (ii) recursion should be avoided if a simple loop can do the same thing.

Never use labels in loops . Although continue and break statements are usually fine, using them with labels to create spaghetti looping creates bad form and code maintenance issues.

//Card class --------------------------------------------------------------------

class Card

{

// type and constants

public enum Suit { clubs, diamonds, hearts, spades }

static char DEFAULT_VAL = 'A';

static Suit DEFAULT_SUIT = Suit.spades;

// private data

private char value;

private Suit suit;

private boolean errorFlag;

// 4 overloaded constructors

public Card(char value, Suit suit)

{ // because mutator sets errorFlag, we don't have to test

set(value, suit);

}

public Card(char value)

{

this(value, DEFAULT_SUIT);

}

public Card()

{

this(DEFAULT_VAL, DEFAULT_SUIT);

}

// copy constructor

public Card(Card card)

{

this(card.value, card.suit);

}

// mutators

public boolean set(char value, Suit suit)

{

char upVal; // for upcasing char

// convert to uppercase to simplify

upVal = Character.toUpperCase(value);

if ( !isValid(upVal, suit))

{

errorFlag = true;

return false;

}

// else implied

errorFlag = false;

this.value = upVal;

this.suit = suit;

return true;

}

// accessors

public char getVal()

{

return value;

}

public Suit getSuit()

{

return suit;

}

public boolean getErrorFlag()

{

return errorFlag;

}

// stringizer

public String toString()

{

String retVal;

if (errorFlag)

return "** illegal **";

// else implied

retVal = String.valueOf(value);

retVal += " of ";

retVal += String.valueOf(suit);

return retVal;

}

// helper

private static boolean isValid(char value, Suit suit)

{

// don't need to test suit (enum), but leave in for clarity

char upVal; // string to hold the 1-char value

String legalVals = "23456789TJQKA";

// convert to uppercase to simplify (need #include )

upVal = Character.toUpperCase(value);

// check for validity

if ( legalVals.indexOf(upVal) >= 0 )

return true;

else

return false;

}

public boolean equals(Card card)

{

if (this.value != card.value)

return false;

if (this.suit != card.suit)

return false;

if (this.errorFlag != card.errorFlag)

return false;

return true;

}

}

// class Hand ----------------------------------------------------------------

class Hand

{

public static final int MAX_CARDS_PER_HAND = 50; // should cover any game

private Card[] myCards;

private int numCards;

// constructor

public Hand()

{

// careful - we are only allocating the references

myCards = new Card[MAX_CARDS_PER_HAND];

resetHand();

}

// mutators

public void resetHand()

{

numCards = 0;

}

public boolean takeCard(Card card)

{

if (numCards >= MAX_CARDS_PER_HAND)

return false;

if (!card.getErrorFlag())

{

// be frugal - only allocate when needed

if (myCards[numCards] == null)

myCards[numCards] = new Card();

// don't assign - that would be a grave error (could clone(), instead)

myCards[numCards++].set(card.getVal(), card.getSuit());

}

return true;

}

public Card playCard()

{

// always play highest card in array. client will prepare this position.

// in rare case that client tries to play from a spent hand, return error

if (numCards == 0)

return new Card('E', Card.Suit.spades); // error card, in rare cases;

else

return myCards[--numCards];

}

public Card inspectCard(int k)

{

// return copy of card at position k.

// if client tries to access out-of-bounds card, return error

if (k = numCards)

return new Card('E', Card.Suit.spades); // error card, in rare cases;

else

return myCards[k];

}

// accessors

public String toString()

{

int k;

String retVal = "Hand = ( ";

for (k = 0; k

{

retVal += myCards[k].toString();

if (k

retVal += ", ";

}

retVal += " )";

return retVal;

}

public int getNumCards()

{

return numCards;

}

}

car ds---- USAnaoCaoCa z! 18. TOKER yA/ULS t ----Su, SwiK a luLS .4 C- 3 3 A car ds---- USAnaoCaoCa z! 18. TOKER yA/ULS t ----Su, SwiK a luLS .4 C- 3 3 A

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Data Management Databases And Organizations

Authors: Richard T. Watson

6th Edition

1943153035, 978-1943153039

More Books

Students also viewed these Databases questions

Question

In an Excel Pivot Table, how is a Fact/Measure Column repeated?

Answered: 1 week ago