Right now I’m using the Mersenne Twister RNG and performing Fisher-Yates shuffle algorithm 100 times:
std::vector<Card> shufCards;
for(int i = 0; i < 4; ++i)
{
for(int j = 0; j < 13; ++j)
{
shufCards.push_back(Card((Card::SuitEnum)i,(Card::RankEnum)j));
}
}
for(int r = 0; r < 100; ++r)
for(int i = shufCards.size() - 1; i >= 1; i--)
{
int j = m_randomGenerator.genrand_int31() % (i + 1);
std::swap(shufCards[i],shufCards[j]);
}
std::vector<Card> cards;
for(int i = 0; i < zeroBasedCut; ++i)
{
cards.push_back(shufCards[i]);
}
for(int i = zeroBasedCut; i < 52; ++i)
{
cards.push_back(shufCards[i]);
}
return cards;
But it feels like the amount of cards per suit is off and somewhat predictable. It is highly unlikely to have a hand of 13 cards with just 1 heart and 5 spades but this happens rather often.
What is a better RNG I could use for this?
Thanks
Our perception of randomness is notoriously poor. If you suspect that your routine is skewed in some way, I’d recommend conducting a large number of random trials using your routine and then looking at the realized probabilities of various hand distributions, and comparing them with what is to be expected theoretically.
Other than this, I’ve got a couple of observations:
zeroBasedCut? What does it achieve that Fisher-Yates doesn’t?std::random_shuffleinstead of your own routine?