forked from trolley813/OpenFool
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcarddeck.cpp
62 lines (54 loc) · 1.48 KB
/
carddeck.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include "carddeck.h"
#ifdef WIN32
#include <windows.h>
#include <wincrypt.h>
#endif
#include <QDebug>
#include <random>
#include <functional>
#include <array>
static std::mt19937 rng;
static std::array<uint8_t, 2496> seedData;
CardDeck::CardDeck(QObject *parent, bool pristine, Rank lowestRank, int jokers)
: _lowestRank(lowestRank), _jokers(jokers), QObject(parent)
{
reset();
#ifdef WIN32
HCRYPTPROV p = 0;
CryptAcquireContextW(&p, 0, 0, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
CryptGenRandom(p, seedData.size(), seedData.data());
CryptReleaseContext(p, 0);
#else
std::random_device rd;
std::generate_n(seedData.data(), seedData.size(), std::ref(rd));
#endif
std::seed_seq seq(std::begin(seedData), std::end(seedData));
rng = std::mt19937(seq);
if (!pristine) {
shuffle();
}
}
void CardDeck::shuffle() { std::shuffle(_cards.begin(), _cards.end(), rng); }
void CardDeck::reset()
{
_cards.clear();
for (int s = 0; s < 4; s++) {
for (int r = _lowestRank; r <= RANK_KING; r++) {
_cards << Card(Suit(s), Rank(r));
}
_cards << Card(Suit(s), RANK_ACE);
}
for (int j = 0; j < _jokers; j++) {
_cards << Card(SUIT_SPADES, RANK_JOKER);
}
}
Card CardDeck::draw()
{
Card c = _cards.back();
_cards.pop_back();
emit cardDrawn();
return c;
}
bool CardDeck::empty() { return _cards.isEmpty(); }
QList<Card> CardDeck::cards() const { return _cards; }