Как кто-то может сделать особый вид для следующей ситуации: есть колода карт. У вас есть 2D-массив, созданный из комбинации двух 1D-массивов: один, который представляет костюм, и другой, который представляет ранг как таковой:
string suit[4] = { "H", "D", "S", "C" };
string rank[13] = { "A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3", "2" };
Они объединяются для создания 2D-массива ([4][13])
с использованием этой комбинации,
suit[i1] + "-" + rank[i2]
После перетаскивания карт массив перестает быть порядком и должен быть возвращен в исходный порядок, где сначала идут Hearts, а затем Diamonds и т.д. Точно так же каждая группа должна сначала иметь туза, а затем короля и так далее.
Как можно сделать особый вид для этой ситуации?
Мои мысли:
Сначала нам нужно прочитать массив. Первый элемент следует сравнить со следующим. Трудная часть - это самое сравнение. Какие типы оснований мы должны использовать при сравнении. Предположим, что у нас есть DA, а затем H-2. Итак, сначала мы читаем первый символ строки, который является D, и сравниваем его со следующей. Если они одинаковы, мы должны перейти к третьей записи строки "DA". Если нет, сравним. Есть ли более простой способ? Как можно определить сравнение, говоря, что H> D и A> K? И как можно реализовать этот метод с использованием 2D-массива, потому что простая сортировка работает только на 1D массивах, а не на 2D.
Вот почему я рекомендовал создать класс карты.
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;
}
При перегрузке operator <
вы можете использовать оператор для сравнения объектов Card
:
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";
}
Кроме того, методы sort
и функции будут автоматически использовать этот метод, поэтому вам не нужно писать функцию сравнения.
Если вы также перегружаете operator==
, вы можете легко определить все операторы сравнения:
operator!= : return !(*this == other_card);
operator>= : return !(*this < other_card);
operator<= : return (*this < other_card) || (*this == other_card);
operator> : return !(*this <= other_card);
Или вы включаете библиотеку Boost (заголовочный файл), которая будет кодировать все остальные операции для вас.
Редактировать 1: Палуба карт
Представление карты как единого объекта упрощает вашу программу. Card
можно использовать в стандартных контейнерах:
typedef std::vector<Card> Card_Container;
Card_Container deck(52);
Card_Container poker_hand(5);
Card_Container blackjack_hand;
std::vector
позволяет легко реализовать карточные контейнеры, которые нуждаются в динамической настройке размера, например, в BlackJack, War или "Go Fish".
Печать карточки
Вы можете перегрузить operator<<
чтобы распечатать карту так, как вы хотите, в стиле, применимом ко всем картам. Это упрощает вывод:
cout << "Blackjack hand:\n";
for (Card_Container::iterator iter = blackjack_hand.begin();
iter != blackjack_hand.end();
++iter)
{
cout << *iter << "\n";
}
Основываясь на комментарии 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;
}
То есть, отдельное внутреннее представление из внешнего вида и использование enum
для первого; пользовательский operator<<
может позаботиться о последнем. card
основанная на std::pair
использует свой operator<
который сравнивает лексикографически, что вы хотите, если я получу его правильно.
Это предполагает, что вы храните колоду в одномерном vector
. Я думаю, что это было бы более удобно, чем двумерное в большинстве ситуаций. На самом деле, я не понимаю, почему вы настаиваете на 2D, когда хотите сортировать.
pair
@ user29568 - это не функция, это структура, которая содержит только два элемента. У него есть предопределенный operator<
который позволяет сравнивать их, и это означает, что содержимое pair
s может быть отсортировано с помощью функции std::sort
.