Ну, имея Card
class
или struct
и DeckOfCards
класс, который действует как специализированный контейнер является правильный путь (как было указано в @Thomas' answer):
struct Card
{
enum Suit_Type {
Diamonds,
Hearts,
Spades,
Clubs,
} suit;
enum Value_Type {
Two = 2, // <<<<<<<<< Note starts at 2
Three ,
// Four, Five, Six, aso. ...
Ten ,
Jack ,
Queen ,
King ,
Ace , // <<<<<<<<< Note has the highest value here
} value;
void printCard();
};
void Card::printCard() {
switch(suit) {
case Hearts:
std::cout << "♥";
break;
case Diamonds:
std::cout << "♦";
break;
case Clubs:
std::cout << "♣";
break;
case Spades:
std::cout << "♠";
break;
}
if(value < Jack) {
std::cout << (int)value;
}
else {
switch(value) {
case Jack:
std::cout << 'J';
break;
case Queen:
std::cout << 'Q';
break;
case King:
std::cout << 'K';
break;
case Ace:
std::cout << 'A';
break;
}
}
}
Как уже упоминалось, должны быть некоторые операторы сравнения, реализованные на Card
, чтобы сделать implem ентация геймплея проще:
bool operator<(const Card& lhs, const Card& rhs) {
return (lhs.suite < rhs.suite) &&
(lhs.value < rhs.value);
}
bool operator>(const Card& lhs, const Card& rhs) {
return (lhs.suite > rhs.suite) &&
(lhs.value > rhs.value);
}
Обратите внимание, что выполнение теста равенства не имеет большого смысла с семантическим точки зрения, если вы не хотите играть с несколькими DeckOfCards
одновременно.
Как Cards
должен вести себя в определенной игре, может быть полностью делегирован классу Strategy Pattern.
DeckOfCards
может быть инициализирована из соответствующего списка инициализаторов:
class DeckOfCards {
DeckOfCards() : cards_({
{ Diamonds, Two } ,
// ...
{ Diamonds, Ace } ,
{ Hearts, Two } ,
// ...
{ Hearts, Ace } ,
{ Spades, Two } ,
// ...
{ Spades, Ace } , // !!! Extremely important !!!
{ Clubs, Two } ,
// ...
{ Clubs, Ace } ,
}) {}
void printDeck();
void shuffle();
private:
std::array<Card,52> cards_;
};
все остальные функции могут быть реализованы легко, как то:
void DeckOfCards::printDeck() {
bool first = true;
for(auto card : cards_) {
if(!first) {
std::cout << ", ";
}
card.printCard();
first = false;
}
std::cout << std::endl;
}
void DeckOfCards::shuffle() {
std::random_device rd;
std::mt19937 g(rd());
std::shuffle(cards_.begin(), cards_.end(), g);
};
Я не 100% уверен, что вы хотите достичь с currentCard
члена в DeckOfCards
, но я полагаю, вы wan't, что быть смещение к следующему Card
раздавать из DeckOfCards
, так что вы можете просто использовать его в качестве индекса для cards_
массива, чтобы раздать ссылку на подстилающей Card
, например, и увеличиваем его впоследствии:
const Card& getNextCard(bool& cardsAvailable) {
cardsAvailable = true;
if(currentCard < 52) {
return cards_[currentCard++];
}
// Reset the deck
cardsAvailable = false;
currentCard = 0;
shuffle();
}
Go найти пасхальное яйцо
Ради обучения и выступая в качестве объектно-ориентированного программирования конструкций. «Палуба карт» будет контейнером «52 объекта», а не просто 'int'. Таким образом, другая небольшая структура/класс будет представлять собой «карточку». Что делает эта карта (класс)? Он имеет костюм (1 из 4), значение (1/13) и лицо (1/13). Тогда в вашем классе «Deck of cards» будет функция, которая будет заполнять 52 объекта этого маленького класса (карты) в свой собственный закрытый контейнер-член, гарантируя отсутствие дубликатов в карточках. –