Created
October 19, 2015 10:14
-
-
Save goldsborough/3896732bd27d8c47b849 to your computer and use it in GitHub Desktop.
Object-oriented representation of a deck of cards.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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