Кажется, есть два способа представления карты в C ++.
Очевидный способ выглядит так:
const int numCards = 52;
const int numRanks = 13;
const int numSuits = 4;
enum Suit {
HEARTS = 1;
DIAMOND = 2;
SPADES = 3;
CLUBS = 4;
}
card Class {
private:
const Suit suit;
const int rank;
public:
/// Constructor
Card(int rank, Suit suit)
/// Get rank between 1 and 13
int getRank();
/// Get suit
Suit getSuit();
/// Get string representation
std::string toString();
};
и есть еще один способ, которым вся карта представлена одним байтом.
namespace Cards {
typedef byte Card;
/// Constructor
Card getCard(int rank, Suit suit); // return (rank - 1) + numRanks * (suit - 1);
/// Validity check
boolean isValid(Card);
/// Get a rank between 1 and 13
int getRank(Card); // return 1 + (card % numRanks);
/// Get suit
Suit getSuit(Card); // return 1 + (card // numSuits)
/// Get string representation
std::string toString(Card);
};
typedef Cards::Card Card;
Первый кажется более очевидным, и преимущество в том, что карта имеет свой собственный тип.
Это делает его более безопасным, потому что его нельзя спутать с другим типом.
С другой стороны, второе представление эффективно использует память и делает некоторые
Операции относительно просты.
Например, создание колоды может быть сделано
void initializeDeck(Card[] deck) {
// Pre: sizeof(deck) >= 52!!!
// No need to iterate over both rank and suit!!!
for(Card card = 0; card < numCards; card++) {
deck[card] = card;
}
}
Должен ли я по-прежнему использовать первый способ или есть способ получить преимущества обоих?
Другим вариантом будет использование битового поля.
struct Card {
unsigned char suit:2;
unsigned char rank:6;
};
Затем вы можете получить доступ к компонентам, как и к любой другой переменной-члену.
Card card;
card.suit = HEARTS;
card.rank = 5;
Вы также можете добавить дополнительные методы Card
Структура для добавления таких вещей, как сериализация строк.
В качестве быстрой заметки я бы назвал ваши костюмы от 0 до 3, чтобы они могли вместиться в 2 бита, а не в 3.