Using the compenents of the standard templates library to make a deck of cards.
ID: 3625084 • Letter: U
Question
Using the compenents of the standard templates library to make a deck of cards.
1. Create a class card ( need attributes for the suit (e.g. spades), value(e.g. ace) and points(e.g. 13) Should define constructors, accessors, and mutators for this class. An overloaded insertion operator << is also a nice thing to have.
2. Create a deck of cards
Select one of the containter classess( e.g. vector, deque, or stack) from the standard template library to model your deck. since these are template classes, you can make your container class hold the cards, e.g. vectordeck1
3.Initialize your deck
add all the possible cars into your deck. you can do this by exhaustion or by using nested loop to set the suit, value, and points for the cards. Hint:The character values for the various cards suits are 3, 4, 5, and 6
4.Shuffle your deck
use the random shuffle function from the alorithms from library to randomize your deck.
5.Create Two hand of cards
Use a different container class to make two hands of cards. one hand should be for the player while the other hand should be the computer.
6 Print out the hands
declare an itertor for the set and use it to print out the cards in each hand.
Explanation / Answer
Main just basically calls all the functions we made in the other files with cards. It makes a deck and two hands and then shuffles the deck then deals out two hands.
main.h
#include "card.h"
int main(void)
{
//Need to seed at the beginning
srand((unsigned)time(NULL));
Deck deck;
Hand p1, p2;
//Shuffle the deck after making it
deck.Shuffle();
//Create the two hands
p1.CreateHand(deck);
p2.CreateHand(deck);
std::cout << "Player ";
p1.Print();
std::cout << "Computer ";
p2.Print();
}
Card.h deals only with implementation of the classes and the enums as well as the definition of the hand size. It gives what a card is, its suit, its value and its rank (The value for the card is just the rank casted as an int, so adding another parameter for it is a little unneeded).
I chose to use a vector for this example because it’s got very quick indexing and we only need to worry about one side of the deck, so I chose the back of it (which will act as the top of the deck).
card.h
#ifndef CARD_H_
#define CARD_H_
#include <vector>
#include <ctime>
#include <iostream>
#include <algorithm>
#define HAND_SIZE 5
typedef enum
{
RAce = 0,
R2,
R3,
R4,
R5,
R6,
R7,
R8,
R9,
R10,
RJack,
RQueen,
RKing
} _Rank;
typedef enum
{
Club = 0,
Diamond,
Heart,
Spade
} _Suit;
class Card
{
public:
Card(_Suit suit, _Rank rank) :
suit_(suit), rank_(rank) {}
_Suit GetSuit();
_Rank GetRank();
void SetSuit(_Suit s);
void SetRank(_Rank r);
private:
_Suit suit_;
_Rank rank_;
};
class Deck
{
public:
Deck();
~Deck();
void Shuffle();
Card PickCard();
void operator<< (const Card& c);
private:
std::vector<Card> cards_;
};
class Hand
{
public:
void AddCard(Card c);
void CreateHand(Deck& d);
void Print();
private:
std::vector<Card> hand_;
};
#endif
This is the real workhorse of the program, the implementation of all the functions we will use in this program. The card itself isn’t much other than mutator functions as it just needs to define what a card is and nothing more. The deck itself only has to make a full deck of cards from all suits to all ranks. Done with a double nested for loop that just pushes back the values into the vector of cards.
#include "card.h"
_Suit Card::GetSuit()
{
return suit_;
}
_Rank Card::GetRank()
{
return rank_;
}
void Card::SetSuit(_Suit s)
{
suit_ = s;
}
void Card::SetRank(_Rank r)
{
rank_ = r;
}
Deck::Deck()
{
for (int suit = (int)Club; suit <= (int)Spade; ++suit)
for (int rank = (int)RAce; rank <= (int)RKing; ++rank)
cards_.push_back(Card(_Suit(suit), _Rank(rank)));
}
Deck::~Deck()
{
cards_.clear();
}
The shuffle function of the deck just deals with calling random_shuffle on the vector of cards, quick and easy call.
void Deck::Shuffle()
{
random_shuffle(cards_.begin(), cards_.end());
}
Insertion operator by request, all it does is insert a card onto the “top” of the deck of cards.
void Deck::operator<< (const Card& c)
{
cards_.push_back(c);
Shuffle();
}
Pick card will just give you the top card of the deck, essetially the same as if you were to draw a card, also deals with removing the card from the deck so a duplicate of that card does not show up elsewhere.
Card Deck::PickCard()
{
Card ret = cards_.back();
cards_.pop_back();
return ret;
}
Dealing with hands, addcard will just add a card to whatever is currently in your hand.
void Hand::AddCard(Card c)
{
hand_.push_back(c);
}
Printing just deals with using an iterator to iterate through the vector and prints out (based on the set character arrays and whatever the card is defined as) to the screen what cards they are.
A short description of how this works is when we take the enum from the card, if we cast it as an int, we can use that int to index into the array of suits and or ranks. And since these are both 0 based, they work just like an index.
void Hand::Print()
{
const char suits[] = {'C','D','H','S'};
const char ranks[] =
{'A', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'J', 'Q', 'K'};
std::cout << "Hand:" << std::endl;
for(std::vector<Card>::iterator it = hand_.begin(); it != hand_.end(); ++it)
{
char suit = suits[(int)it->GetSuit()];
char rank = ranks[(int)it->GetRank()];
std::cout << '[' << suit << ',' << rank << ']';
}
std::cout << std::endl;
}
Create hand just calls add card however many times you set the max hand size to.
void Hand::CreateHand(Deck& d)
{
for (unsigned i = 0; i < HAND_SIZE; ++i)
AddCard(d.PickCard());
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.