#include <iostream> // std::cout
#include <algorithm> // std::shuffle
#include <array> // std::array
#include <chrono> // std::chrono::system_clock
#include <thread> // std::this_thread::get_id()
#include <functional> // std::hash
#include <random> // std::mt19937_64, et al.
struct Card {
size_t value;
enum Suit { spades, hearts, clubs, diamonds };
static const size_t numPerSuit = 13;
Suit suit;
friend std::ostream& operator<<(std::ostream& os, const Card& card);
Card() {
static thread_local size_t numcards = 0;
suit = Suit(numcards/numPerSuit & 3);
value = numcards%numPerSuit + 1;
++numcards;
}
};
std::ostream& operator<<(std::ostream& os, const Card& card) {
switch (card.value) {
case 11:
os << "Jack of "; break;
case 12:
os << "Queen of "; break;
case 13:
os << "King of "; break;
case 1:
os << "Ace of "; break;
default:
os << card.value << " of ";
}
switch (card.suit) {
case card.spades:
os << "Spades"; break;
case card.hearts:
os << "Hearts"; break;
case card.clubs:
os << "Clubs"; break;
case card.diamonds:
os << "Diamonds";
}
return os;
}
template<size_t numCards = 52>
struct Deck {
public:
std::array<Card, numCards> cards;
void shuffle_cards() {
static thread_local std::seed_seq seed = {
(size_t)std::random_device{}(),
(size_t)std::chrono::system_clock::now().time_since_epoch().count(),
(size_t)std::hash<std::thread::id>{}(std::this_thread::get_id())
};
static thread_local std::mt19937_64 random_gen(seed);
std::shuffle (cards.begin(), cards.end(), random_gen);
return;
}
};
int main () {
Deck<> mydeck;
mydeck.shuffle_cards();
std::cout << "Shuffled elements:\n";
for (auto& x : mydeck.cards) std::cout << x << '\n';
return 0;
}