Programming: Week 3 (cont. 2)
|
Ex. 6 Define a class that is able to describe any of the 52 cards in a pack of cards. Include a Print method that outputs the suit and the rank of a card. Class Design Considerations The class The class needs at least two member variables, one for suit and one for rank. You can uniquely identify a card by giving its suit and rank. However, it is more convenient to uniquely identify obejcts by using a single identifier as opposed to several identifiers, such as suit and rank. Consider every card in the pack is numbered, the numbers running from 1 to 52. Such a number could serve as the single unique identifier. Let’s call it a card’s ID. The order of cards (and consequently, which card each of the 52 IDs refers to) is arbitrary. Were the cards arranged differently, the same ID (e.g., However, numbering the cards in advance does not reduce generality. We need this fixed card order only inside the class so that we have some convenient way to identify each card; the user outside the class will not experience this fixed order because they will be interested in cards independently of one another. This will become more apparent when we define another class for the whole pack of cards and have that class manipulate individual cards via this class. Now that we have card ID, the suit and the rank of a specific card become properties of that card and they are calculated based on the ID. When you instantiate an object of the Here is a visual representation of the class: The class takes in one external value, Class Code (Implementation) Having discussed the design of the card class we can turn to the C++ implementation of the card class. Here is the code:
#include
#include
#include
class Card
{
public:
Card(int id)
{
m_id = id;
SetSuitRank();
};
char GetSuit()
{
return m_suit;
};
std::string GetRank()
{
return m_rank;
};
void PrintCard()
{
std::cout << GetSuit() << GetRank();
};
private:
int m_id;
char m_suit;
std::string m_rank;
void SetSuitRank()
{
switch (m_id / 13)
{
case 0:
m_suit = 'H';
break;
case 1:
m_suit = 'D';
break;
case 2:
m_suit = 'S';
break;
case 3:
m_suit = 'C';
break;
};
switch (m_id % 13)
{
case 0:
m_rank = "A";
break;
case 1:
m_rank = "2";
break;
case 2:
m_rank = "3";
break;
case 3:
m_rank = "4";
break;
case 4:
m_rank = "5";
break;
case 5:
m_rank = "6";
break;
case 6:
m_rank = "7";
break;
case 7:
m_rank = "8";
break;
case 8:
m_rank = "9";
break;
case 9:
m_rank = "10";
break;
case 10:
m_rank = "J";
break;
case 11:
m_rank = "Q";
break;
case 12:
m_rank = "K";
break;
};
};
};
A few short comments about the class. The logic which assigns the suit and the rank to a card is in the private method The public Testing the class We are going to test the class. Let’s create two different cards, e.g. an HQ and an S7. Looking at the table above, we can see that the numbers of these cards are 12 and 33, respectively. To create these cards we pass the values 11 and 32 to the constructor because the logic in Then we will call the
int main(int argc, char* argv[])
{
Card card(11);
Card card2(32);
card.PrintCard();
std::cout << std::endl;
card2.PrintCard();
std::cout << std::endl;
return 0;
}
This is the output:
So the class works correctly. Notice that if the user wants to create a particular card, they have to know the card’s ID from the table above (using any other arrangements for IDs will create wrong cards). However, the user will not manually create cards using this class. We will write another class, Separating declarations from implementation To better prepare for the next exercise and improve code readability, we will break the code we wrote in a *.cpp and a *.h file. Card.h
#pragma once
class Card
{
public:
Card(int id);
char GetSuit();
std::string GetRank();
void PrintCard();
private:
int m_id;
char m_suit;
std::string m_rank;
void SetSuitRank();
};
Card.cpp
#include "stdafx.h"
#include "Card.h"
Card::Card(int id)
{
m_id = id;
SetSuitRank();
}
char Card::GetSuit()
{
return m_suit;
}
std::string Card::GetRank()
{
return m_rank;
}
void Card::PrintCard()
{
std::cout << GetSuit() << GetRank();
}
void Card::SetSuitRank()
{
switch (m_id / 13)
{
case 0:
m_suit = 'H';
break;
case 1:
m_suit = 'D';
break;
case 2:
m_suit = 'S';
break;
case 3:
m_suit = 'C';
break;
};
switch (m_id % 13)
{
case 0:
m_rank = "A";
break;
case 1:
m_rank = "2";
break;
case 2:
m_rank = "3";
break;
case 3:
m_rank = "4";
break;
case 4:
m_rank = "5";
break;
case 5:
m_rank = "6";
break;
case 6:
m_rank = "7";
break;
case 7:
m_rank = "8";
break;
case 8:
m_rank = "9";
break;
case 9:
m_rank = "10";
break;
case 10:
m_rank = "J";
break;
case 11:
m_rank = "Q";
break;
case 12:
m_rank = "K";
break;
};
}
main.cpp
#include
#include "Card.h"
int main(int argc, char* argv[])
{
//do things
}
NB: include directives for |

