Card
The first thing to do is to implement a class to represent a playing card. Use the following UML diagram to guide you on what this class will need:
UML for Card
Card |
---|
- value : char* - suit : char* - playerId : unsigned* - discard : bool* |
+ Card(v : char, s : char)
+ ~Card()
+ getValue() const : char + getSuit() const : char + getPlayerId() const : unsigned + isDiscard() const : bool
+ setPlayerId(p : unsigned) : void + flipDiscard() : void
|
The following are implementation notes for the class:
- You must separate the class into two files (specification and implementation)
- All attributes are dynamic
- Make sure to release their memory to avoid memory leaks
- The value of the card is represented asa
char
so that it can be digits (2 through 9), as well as the (J)ack, (Q)ueen, (K)ing, and (A)ce; the 0 character represents the value 10
- The suit of the card must take on the values (D)iamond, (H)eart, (C)lub, and (S)pade
- Use 0 as the initial value for the
playerId
attribute; this will allow you to check if a player owns the card or not in other code later on
- The
discard
flagis used to determine if the card is currently in the player's discard pile or is still active in the game
- In the constructor, the first parameter represents the value of the card and the second parameter represents the suit of the card
- Use a member initializer list to assign starting values to the attributes
- The
flipDiscard
method changes the value of thediscard
flag toits opposite value
Player
The second task to complete is to implement a class to represent a player in the game. Use the following UML diagram to guide you on what this class will need:
UML for Player
Player |
---|
- id : unsigned* - name : string* - score : unsigned* |
+ Player(n : string)
+ ~Player()
+ getId() const : unsigned + getName() const : string + getScore() const : unsigned
+ updateScore() : void + ask(deck : Card*[], DECK_SIZE : const unsigned) const : char + check(deck : Card*[], DECK_SIZE : const unsigned, value : char) const : bool
|
The following are implementation notes for the class:
- You must separate the class into two files (specification and implementation)
- All attributes are dynamic
- Make sure to release their memory to avoid memory leaks
- The
id
must be initialized to a random value between 1000 and 9999 (inclusive)
- In the constructor, the parameter represents the name of the player
- Use a member initializer list to assign starting values to the attributes
- The
updateScore
method needs to increment the value that thescore
attribute is pointing to by 1
- The
ask
method allows the player to ask which card value they want
- Use a loop to perform this so that the player must pick a card value that is currently in their hand
- Return the valid card value
- The
check
method determines if the givenvalue
parameter is for a card that is currently in the player's hand
- Make sure to only consider non-discarded cards
- Return
true
if one of the cards in the player's hand matchesvalue
, otherwise returnfalse
bool isGameOver(Card*[], const unsigned)
The first parameter represents the total deck of cards in the game, while the second parameter is for the size of the array.
The Go Fish game is considered over when all the cards from the deck are in discard piles. You will need to use a loop to iterate over all theCard
pointers and determine if they are all discarded.
Returntrue
if the game is indeed over, otherwise returnfalse
.
Card* assignRandomCard(Card*[], const unsigned, Player*)
The first parameter represents the total deck of cards in the game, the second parameter is for the size of the array, and the third parameter is a pointer to the current player.
One of the main aspects of the Go Fish game is having to constantly "go fish" for more cards from the "pond" (AKA, deck). We will simulate this behavior by randomly choosing a card from the deck that is available and assign the current player to the card as its owner.
Use a loop to randomly pick a valid card from the deck that is:
- Not owned by another player
- Not in a discard pile
Once a valid card has been found, update its player ID to the current player's ID. Finally, return the pointer to that valid card.
void checkScore(Card*[], const unsigned, Player*, char)
The first parameter represents the total deck of cards in the game, the second parameter is for the size of the array, the third parameter is a pointer to the current player, and the fourth parameter is the card value that the player just added to their hand.
This function needs to check if the player has 4 copies of the given card value in their hand. This is how points are scored in Go Fish. If the player has the 4 copies, that is called a book, and the player is awarded one point.
Use a loop to iterate over theCard
pointers in the deck array to figure this out. If the player does have all the copies in their hand, then update their score. Don't forget that you also need to mark those 4 cards as discarded if they player gets the point! This is how we can "remove" those cards from the hand.
main
As mentioned, there are fourTODOtasks for you to complete in themain
function.
- There is already a
deck
variable, but you still need to actually create the 52 dynamicCard
objects for the array. You will need to think of a way of generating all the possible cards in a standard deck (except the Jokers, of course).
- Create two dynamic
Player
objects calledplayer1
andplayer2
. You will need to get the names for the players from the user. Print out the ID of each player.
- Within the actual game loop, almost the logic is done for you except one. In the scenario where the other player has our desired card value, the code needs to reassign the ownership of those cards. If you did the
checkScore
function correctly, you'll find this logic to be similar.
- Release all dynamic memory generated by the
main
function.