Well, I don't know why I did it in the first place, but I had a size variable to track the vector size. I think it was because I didn't want to include the "BADCARD" at the end of the vector. I removed the size variable and changed all references to it to "deck.size()-1". Definitely a lot easier than adding and subtracting from the size every time cards are added or drawn.
So right now I'm fairly happy with how CardDeck is looking. The only thing I wish I could improve more is operator=, which I'm told should call the copy constructor so as to keep from repeating code. I'm sort of stumped on that - I was told how on #gamedev, but I forgot. <_< - but it looks OK enough.
Here's the current implementation of Card and CardDeck. I don't think Card can get much better, it's too simple of a class. :P
Card.h
namespace Twisol{ namespace Suits { enum Suit { BAD_SUIT, DIAMOND, HEART, CLUB, SPADE, JOKER }; } namespace Values { enum Value { BAD_VALUE, ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, JOKER }; } class Card { private: Suits::Suit suit; Values::Value value; public: /// Default constructor. Initializes the Card to BAD_SUIT, BAD_VALUE. Card(); /// Takes a Suit and a Value, and initializes the Card. /// If _suit or _value are negative or too high, initialized to BAD_SUIT, BAD_VALUE Card(Suits::Suit _suit, Values::Value _value); /// Returns the card's Suit Suits::Suit Suit() const; /// Returns the card's Value Values::Value Value() const; bool operator==(const Card& _card) const { if (this->suit == _card.suit && this->value == _card.value) return true; else return false; } bool operator!=(const Card& _card) const { if (this->suit != _card.suit || this->value == _card.value) return true; else return false; } };}
Card.cpp
#include "Card.h"namespace Twisol{Card::Card(Suits::Suit _suit, Values::Value _value){ if (_suit == Suits::BAD_SUIT || _suit > Suits::JOKER) suit = Suits::BAD_SUIT; else suit = _suit; if (_value == Values::BAD_VALUE || _value > Values::JOKER) value = Values::BAD_VALUE; else value = _value;}Card::Card(){ suit = Suits::BAD_SUIT; value = Values::BAD_VALUE;}Suits::Suit Card::Suit() const{ return suit;}Values::Value Card::Value() const{ return value;}} // end namespace Twisol
CardDeck.h
#pragma once#include "Card.h"#include namespace Twisol{ class CardDeck { private: std::vector deck; std::vector::iterator currentCard; int size; bool (*comp_func)(Card const& a, Card const& b); static bool CardDeck::CardCompare(Card const& a, Card const& b); void Init(); void InitDeck(const std::vector& Deck); public: // Pass true for jokers. CardDeck(bool jokers=false, bool empty=false); // Pass a vector of Cards to be copied. // Card(BAD_SUIT, BAD_VALUE) will be pushed back. CardDeck(std::vector _deck); CardDeck(const CardDeck& _deck); ~CardDeck(); void SetComp(bool (*comp_func)(Card const& a, Card const& b)); int DeckSize() const; int TotalSize() const; void Shuffle(); void Sort(); Card Draw(bool remove=false); void Empty(); void Add(Card _card); void Add(std::vector _cards); void Add(CardDeck _deck); CardDeck const& operator= (CardDeck const& _deck); };}
CardDeck.cpp
#include "CardDeck.h"#include #include #include #include namespace Twisol{ Card BADCARD(Suits::BAD_SUIT, Values::BAD_VALUE);CardDeck::CardDeck(bool jokers, bool empty){ if (!empty) { if (jokers) deck.push_back(Card(Suits::JOKER, Values::JOKER)); for (int x = 1; x <= 4; x++) for (int y = 1; y <= 13; y++) deck.push_back(Card(Suits::Suit(x), Values::Value(y))); if (jokers) deck.push_back(Card(Suits::JOKER, Values::JOKER)); } Init();}CardDeck::CardDeck(std::vector Deck){ InitDeck(Deck);}CardDeck::CardDeck(const CardDeck& Deck){ InitDeck(Deck.deck); int diff = static_cast<int>(Deck.currentCard - Deck.deck.begin()); for (; diff > 0; diff--) currentCard++;}void CardDeck::InitDeck(const std::vector& Deck){ for (int i = 0; i < static_cast<signed>(Deck.size()); i++) { deck.push_back(deck.at(i)); if (deck.at(i) == BADCARD) break; } Init();}void CardDeck::Init(){ deck.push_back(BADCARD); currentCard = deck.begin(); comp_func = &CardDeck::CardCompare; srand(static_cast<unsigned int>(time(NULL)));}CardDeck::~CardDeck(){}void CardDeck::SetComp(bool (*comp_func)(Card const& a, Card const& b)){ if (comp_func != 0) { this->comp_func = comp_func; }}int CardDeck::DeckSize() const{ // Subtracts the number of cards that have been drawn from the total vector size. return TotalSize() - static_cast<int>(currentCard - deck.begin());}int CardDeck::TotalSize() const{ // Don't want to count the BADCARD at the end. return static_cast<int>(deck.size() - 1);}void CardDeck::Shuffle(){ deck.pop_back(); std::random_shuffle(deck.begin(), deck.end()); currentCard = deck.begin(); deck.push_back(BADCARD);}bool CardDeck::CardCompare(Card const& a, Card const& b){ if (a.Value() > b.Value() || (a.Value() == b.Value() && a.Suit() > b.Suit())) return true; return false;}void CardDeck::Sort(){ deck.pop_back(); std::sort(deck.begin(), deck.end(), comp_func); currentCard = deck.begin(); deck.push_back(BADCARD);}Card CardDeck::Draw(bool remove){ Card card = *currentCard; if (card != BADCARD && !remove) currentCard++; else if (remove) currentCard = deck.erase(currentCard); return card;}void CardDeck::Add(Card _card){ deck.pop_back(); deck.push_back(_card); deck.push_back(BADCARD); if (deck.capacity() <= 1) { deck.reserve(deck.size() + 20); int diff = static_cast<int>(currentCard - deck.begin()); for (currentCard = deck.begin(); diff > 0; diff--) currentCard++; }}void CardDeck::Add(std::vector _cards){ deck.pop_back(); for (int i = 0; i < static_cast<signed>(_cards.size()); i++) if (_cards.at(i) != BADCARD) deck.push_back(_cards.at(i)); deck.push_back(BADCARD);}void CardDeck::Add(CardDeck _deck){ std::vector _cards = _deck.deck; Add(_cards);}void CardDeck::Empty(){ deck.clear(); deck.push_back(BADCARD); currentCard = deck.begin();}CardDeck const& CardDeck::operator= (CardDeck const& _cardDeck){ deck.clear(); for (int i = 0; i < static_cast<signed>(Deck.size()); i++) { deck.push_back(deck.at(i)); if (deck.at(i) == BADCARD) break; } currentCard = deck.begin(); int diff = static_cast<int>(_cardDeck.currentCard - _cardDeck.deck.begin()); for (; diff > 0; diff--) currentCard++; if (deck.at(static_cast<int>(deck.size())-1) != BADCARD) deck.push_back(BADCARD); return _cardDeck;}} // end namespace Twisol