Skip to content

Instantly share code, notes, and snippets.

@goldsborough
Created October 19, 2015 10:14
Show Gist options
  • Save goldsborough/3896732bd27d8c47b849 to your computer and use it in GitHub Desktop.
Save goldsborough/3896732bd27d8c47b849 to your computer and use it in GitHub Desktop.
Object-oriented representation of a deck of cards.
class Card
{
public:
using value_t = unsigned char;
enum Type : unsigned char
{
Hearts,
Spades,
Diamonds,
Clubs
};
enum Color : unsigned char
{
Red,
Black
};
enum Value : unsigned char
{
Joker = 10,
Queen = 11,
King = 12
};
template<typename T, typename C, typename V>
Card(T type, C color, V value)
: _type(static_cast<Type>(type))
, _color(static_cast<Color>(color))
, _value(value)
{ }
friend std::ostream& operator<<(std::ostream& stream, const Card& card)
{
stream << "[";
switch(card.type())
{
case Type::Hearts: stream << "Hearts, "; break;
case Type::Spades: stream << "Spades, "; break;
case Type::Diamonds: stream << "Diamonds, "; break;
case Type::Clubs: stream << "Clubs, "; break;
}
switch(card.color())
{
case Color::Red: stream << "Red, "; break;
case Color::Black: stream << "Black, "; break;
}
switch(card.value())
{
case Value::Joker: stream << "Joker"; break;
case Value::Queen: stream << "Queen"; break;
case Value::King: stream << "King"; break;
default:
{
stream << std::to_string(card.value());
break;
}
}
stream << "]";
return stream;
}
const Type& type() const
{
return _type;
}
const Color& color() const
{
return _color;
}
const value_t& value() const
{
return _value;
}
private:
Type _type;
Color _color;
unsigned char _value;
};
class Deck
{
public:
enum Value
{
Joker = Card::Value::Joker,
Queen = Card::Value::Queen,
King = Card::Value::King,
Ace = 13
};
Deck()
{
reset();
}
virtual ~Deck() = default;
virtual const Card& peek() const
{
return _cards.back();
}
virtual Card pop()
{
auto card = _cards.back();
_cards.pop_back();
return card;
}
virtual void shuffle()
{
static std::random_device seed;
static std::mt19937 generator(seed());
for (std::size_t i = 1; i < _cards.size(); ++i)
{
std::uniform_int_distribution<std::size_t> distribution(0, i);
std::swap(_cards[i], _cards[distribution(generator)]);
}
}
virtual void reset()
{
_cards.clear();
for (std::size_t color = Card::Color::Red;
color <= Card::Color::Black;
++color)
{
for (std::size_t type = Card::Type::Hearts;
type <= Card::Type::Clubs;
++type)
{
for (std::size_t value = 1; value <= Value::King; ++value)
{
_cards.push_back({type, color, value});
}
_cards.push_back({type, color, Ace});
}
}
shuffle();
}
virtual std::size_t remaining() const
{
return _cards.size();
}
virtual bool is_empty() const
{
return _cards.empty();
}
protected:
std::vector<Card> _cards;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment