Sign in to follow this  
  • entries
    122
  • comments
    121
  • views
    68316

CardDeck

Sign in to follow this  
Twisol

88 views

Over the past few days I've been slimming down CardDeck, and trying to fix some inconsistencies I've noticed (like the previously mentioned BAD_SUIT, BAD_VALUE cards when I know there's still more cards). If I clear up some of the clutter, though, maybe I can see what's going wrong.

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

Sign in to follow this  


0 Comments


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now