Reputation: 167
How can someone make a special sort for the following situation: There is a deck of cards. You have a 2D array that was created from the combination of two 1D arrays : one that represents the suit and another that represents the rank as such:
string suit[4] = { "H", "D", "S", "C" };
string rank[13] = { "A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3", "2" };
They are combined to create a 2D array([4][13])
using this combination,
suit[i1] + "-" + rank[i2]
After shuffiling the cards, the array is no longer in order and should be returned to its original order where the Hearts goes first and then Diamonds and so on. Similarly, each group should have the ace first and then the king and so on.
How can one make a special sort for this situation?
My thoughts:
We first have to read the array. The first element should be compared to the next. The tricky part is this very comparison. What type of grounds should we use in the comparison. Lets assume we have a D-A and then H-2. So, we first read the first character of the string which is D and compare it to the next one. If they are the same, we should jump to the third entry of the string "D-A". If not, we make a comparison. Is there an easier way? How can one define a comparison, saying that H>D and A>K? And how can one implement this method using the 2D array because a simple sort only works on 1D arrays and not 2D.
Upvotes: 0
Views: 201
Reputation: 57688
This is why I recommended creating a Card class.
class Card
{
public:
bool operator < (const Card& other_card) const;
// private:
suit m_suit;
rank m_rank;
};
bool Card::operator<(const Card& other_card) const
{
bool is_less_than;
if (m_suit == other_card.m_suit)
{
is_less_than = m_rank < other_card.m_rank;
}
else
{
is_less = m_suit < other_card.m_suit;
}
return is_less_than;
}
By overloading operator <
you can use the operator to compare Card
objects:
Card player1;
player1.rank = two;
player1.suit = spade;
Card player2;
player2.rank = three;
player2.suit = spade;
Card player3;
player3.rank = 4;
player3.suit = club;
if (player1 < player2)
{
cout << "player1 < player2\n";
}
else
{
cout << "player1 not less than player2\n";
}
if (player 1 < player3)
{
cout << "player1 < player3\n";
}
else
{
cout << "player1 not less than player3\n";
}
Also, the sort
methods and functions will automatically use this method, so you don't have to write an comparison function.
If you also overload operator==
, you can easily define all the comparison operators:
operator!= : return !(*this == other_card);
operator>= : return !(*this < other_card);
operator<= : return (*this < other_card) || (*this == other_card);
operator> : return !(*this <= other_card);
Or you include the Boost Library (header file) which will code up all the remaining operations for you.
Edit 1: Deck of cards
Representing a card as a single object, simplifies your program. You can use the Card
in standard containers:
typedef std::vector<Card> Card_Container;
Card_Container deck(52);
Card_Container poker_hand(5);
Card_Container blackjack_hand;
The std::vector
allows for easy implementation of card containers that need dynamic size adjustment, like a hand in BlackJack, War, or "Go Fish".
Printing of a Card
You can overload operator<<
to print the card any way you want in a style that applies to all cards. This makes output simple:
cout << "Blackjack hand:\n";
for (Card_Container::iterator iter = blackjack_hand.begin();
iter != blackjack_hand.end();
++iter)
{
cout << *iter << "\n";
}
Upvotes: 2
Reputation: 7637
Building on the comment by GWW:
enum suit { club, spade, diamond, heart };
enum rank {
two, three, four, five, six, seven, eight,
nine, ten, jack, queen, king, ace
};
using card = std::pair<suit, rank>;
int main ()
{
std::vector<card> deck{
{diamond, five}, {spade, ace},
{club, two}, {spade, nine}
};
std::sort(deck.begin(), deck.end());
for (auto c : deck)
cout << c.first << " " << c.second << endl;
}
That is, separate internal representation from appearance, and use enum
for the former; a custom operator<<
could take care of the latter. A card
based on std::pair
uses its operator<
that compares lexicographically, which is what you want if I get it correctly.
This assumes you store a deck in a one-dimensional vector
. I think this would be more convenient than two-dimensional in most situations. In fact, I can't see why you insist on 2D when you want to sort.
Upvotes: 5