Filling up a hand with random cards that are not yet drawn - Monte Carlo











up vote
2
down vote

favorite












I would like to know if there is a more efficient way to speed up below code. This function is meant to fill in a set of poker hand with the remaining
cards using Mersenne Twister for a Monte Carlo simulation.



void HandEvaluator::RandomFill(std::vector<std::shared_ptr<Card>>& _Set, std::vector<std::shared_ptr<Card>>& _Dead, unsigned int _Target){
//Add the cards that are currently in Set as dead cards
for (auto const& CardInSet : _Set)
{
if (CardInSet == nullptr)
break;

_Dead.push_back(CardInSet);
}

bool IsDead;
unsigned int RequiredAmt = _Target - _Set.size();

unsigned int CardIndex = 0;
std::uniform_int_distribution<unsigned int> CardsDistribution(0, 51);

for (unsigned int Index = 0; Index < RequiredAmt; Index++)
{
while (true)
{
IsDead = false;
CardIndex = CardsDistribution(MTGenerator);

for (auto const& Dead : _Dead)
{
if (ReferenceDeck[CardIndex]->GetRank() == Dead->GetRank() && ReferenceDeck[CardIndex]->GetSuit() == Dead->GetSuit())
{
IsDead = true;
break;
}
}

if (!IsDead)
{
_Set.push_back(ReferenceDeck[CardIndex]);
break;
}
}
}
}


The Visual Studio Profiler had identified that this line



    CardIndex = CardsDistribution(MTGenerator);


is the main culprit behind the high compute time. Is Mersenne Twister itself not meant for a Monte Carlo Simulation and another PRNG should be used instead ? Or there are some inefficient lines that I had missed out ?










share|improve this question
























  • Hi, and welcome to CodeReview! I reformatted your code section. Next time, please just paste the code, select it, then press Ctrl + K.
    – Incomputable
    Dec 1 at 9:55










  • Could you please also post other parts of the code used in the post? A little example program which can be compiled and run would be awesome! Don't be concerned with size of the program, 100-200 lines of code is common for a CR question.
    – Incomputable
    Dec 1 at 10:59












  • Thanks for the help ! I've done up a sample project that can be compiled and run. However, my sample project relies on a relatively large .dat file (~126mb) to perform the simulation. Should I include the .dat file into the project and upload them into a file storage site like Google Drive or include another project that generate .dat file?
    – Tomashiwa
    Dec 1 at 12:57










  • Whichever is more convenient for you. People might want to check their modifications, like comparing the output of your version and their version. I believe the code you've shown here just generates the deck of cards. Maybe you could include all of the code used for it and create a small main function which generates one deck and prints it? For example, at the moment I don't know what Card is (I can guess that it is either an integer or pair which represents a card) and what is ReferenceDeck (vector of cards?).
    – Incomputable
    Dec 1 at 13:13












  • Ah sorry for the confusion, this function is meant to generate a hand, _Target amt of cards, based on the remaining cards in a deck. The generation of ReferenceDeck is in another part of the HandEvaluator class and Card is a class that contains the Suit and Rank with functions to compare with other Cards. Here's the link to the sample project: drive.google.com/file/d/1U3d8ZuS_wzkq4RVIj2RV6gj1zyv_yrco/…
    – Tomashiwa
    Dec 1 at 13:52

















up vote
2
down vote

favorite












I would like to know if there is a more efficient way to speed up below code. This function is meant to fill in a set of poker hand with the remaining
cards using Mersenne Twister for a Monte Carlo simulation.



void HandEvaluator::RandomFill(std::vector<std::shared_ptr<Card>>& _Set, std::vector<std::shared_ptr<Card>>& _Dead, unsigned int _Target){
//Add the cards that are currently in Set as dead cards
for (auto const& CardInSet : _Set)
{
if (CardInSet == nullptr)
break;

_Dead.push_back(CardInSet);
}

bool IsDead;
unsigned int RequiredAmt = _Target - _Set.size();

unsigned int CardIndex = 0;
std::uniform_int_distribution<unsigned int> CardsDistribution(0, 51);

for (unsigned int Index = 0; Index < RequiredAmt; Index++)
{
while (true)
{
IsDead = false;
CardIndex = CardsDistribution(MTGenerator);

for (auto const& Dead : _Dead)
{
if (ReferenceDeck[CardIndex]->GetRank() == Dead->GetRank() && ReferenceDeck[CardIndex]->GetSuit() == Dead->GetSuit())
{
IsDead = true;
break;
}
}

if (!IsDead)
{
_Set.push_back(ReferenceDeck[CardIndex]);
break;
}
}
}
}


The Visual Studio Profiler had identified that this line



    CardIndex = CardsDistribution(MTGenerator);


is the main culprit behind the high compute time. Is Mersenne Twister itself not meant for a Monte Carlo Simulation and another PRNG should be used instead ? Or there are some inefficient lines that I had missed out ?










share|improve this question
























  • Hi, and welcome to CodeReview! I reformatted your code section. Next time, please just paste the code, select it, then press Ctrl + K.
    – Incomputable
    Dec 1 at 9:55










  • Could you please also post other parts of the code used in the post? A little example program which can be compiled and run would be awesome! Don't be concerned with size of the program, 100-200 lines of code is common for a CR question.
    – Incomputable
    Dec 1 at 10:59












  • Thanks for the help ! I've done up a sample project that can be compiled and run. However, my sample project relies on a relatively large .dat file (~126mb) to perform the simulation. Should I include the .dat file into the project and upload them into a file storage site like Google Drive or include another project that generate .dat file?
    – Tomashiwa
    Dec 1 at 12:57










  • Whichever is more convenient for you. People might want to check their modifications, like comparing the output of your version and their version. I believe the code you've shown here just generates the deck of cards. Maybe you could include all of the code used for it and create a small main function which generates one deck and prints it? For example, at the moment I don't know what Card is (I can guess that it is either an integer or pair which represents a card) and what is ReferenceDeck (vector of cards?).
    – Incomputable
    Dec 1 at 13:13












  • Ah sorry for the confusion, this function is meant to generate a hand, _Target amt of cards, based on the remaining cards in a deck. The generation of ReferenceDeck is in another part of the HandEvaluator class and Card is a class that contains the Suit and Rank with functions to compare with other Cards. Here's the link to the sample project: drive.google.com/file/d/1U3d8ZuS_wzkq4RVIj2RV6gj1zyv_yrco/…
    – Tomashiwa
    Dec 1 at 13:52















up vote
2
down vote

favorite









up vote
2
down vote

favorite











I would like to know if there is a more efficient way to speed up below code. This function is meant to fill in a set of poker hand with the remaining
cards using Mersenne Twister for a Monte Carlo simulation.



void HandEvaluator::RandomFill(std::vector<std::shared_ptr<Card>>& _Set, std::vector<std::shared_ptr<Card>>& _Dead, unsigned int _Target){
//Add the cards that are currently in Set as dead cards
for (auto const& CardInSet : _Set)
{
if (CardInSet == nullptr)
break;

_Dead.push_back(CardInSet);
}

bool IsDead;
unsigned int RequiredAmt = _Target - _Set.size();

unsigned int CardIndex = 0;
std::uniform_int_distribution<unsigned int> CardsDistribution(0, 51);

for (unsigned int Index = 0; Index < RequiredAmt; Index++)
{
while (true)
{
IsDead = false;
CardIndex = CardsDistribution(MTGenerator);

for (auto const& Dead : _Dead)
{
if (ReferenceDeck[CardIndex]->GetRank() == Dead->GetRank() && ReferenceDeck[CardIndex]->GetSuit() == Dead->GetSuit())
{
IsDead = true;
break;
}
}

if (!IsDead)
{
_Set.push_back(ReferenceDeck[CardIndex]);
break;
}
}
}
}


The Visual Studio Profiler had identified that this line



    CardIndex = CardsDistribution(MTGenerator);


is the main culprit behind the high compute time. Is Mersenne Twister itself not meant for a Monte Carlo Simulation and another PRNG should be used instead ? Or there are some inefficient lines that I had missed out ?










share|improve this question















I would like to know if there is a more efficient way to speed up below code. This function is meant to fill in a set of poker hand with the remaining
cards using Mersenne Twister for a Monte Carlo simulation.



void HandEvaluator::RandomFill(std::vector<std::shared_ptr<Card>>& _Set, std::vector<std::shared_ptr<Card>>& _Dead, unsigned int _Target){
//Add the cards that are currently in Set as dead cards
for (auto const& CardInSet : _Set)
{
if (CardInSet == nullptr)
break;

_Dead.push_back(CardInSet);
}

bool IsDead;
unsigned int RequiredAmt = _Target - _Set.size();

unsigned int CardIndex = 0;
std::uniform_int_distribution<unsigned int> CardsDistribution(0, 51);

for (unsigned int Index = 0; Index < RequiredAmt; Index++)
{
while (true)
{
IsDead = false;
CardIndex = CardsDistribution(MTGenerator);

for (auto const& Dead : _Dead)
{
if (ReferenceDeck[CardIndex]->GetRank() == Dead->GetRank() && ReferenceDeck[CardIndex]->GetSuit() == Dead->GetSuit())
{
IsDead = true;
break;
}
}

if (!IsDead)
{
_Set.push_back(ReferenceDeck[CardIndex]);
break;
}
}
}
}


The Visual Studio Profiler had identified that this line



    CardIndex = CardsDistribution(MTGenerator);


is the main culprit behind the high compute time. Is Mersenne Twister itself not meant for a Monte Carlo Simulation and another PRNG should be used instead ? Or there are some inefficient lines that I had missed out ?







c++ random simulation ai






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 1 at 9:55









Incomputable

6,45521453




6,45521453










asked Dec 1 at 9:24









Tomashiwa

111




111












  • Hi, and welcome to CodeReview! I reformatted your code section. Next time, please just paste the code, select it, then press Ctrl + K.
    – Incomputable
    Dec 1 at 9:55










  • Could you please also post other parts of the code used in the post? A little example program which can be compiled and run would be awesome! Don't be concerned with size of the program, 100-200 lines of code is common for a CR question.
    – Incomputable
    Dec 1 at 10:59












  • Thanks for the help ! I've done up a sample project that can be compiled and run. However, my sample project relies on a relatively large .dat file (~126mb) to perform the simulation. Should I include the .dat file into the project and upload them into a file storage site like Google Drive or include another project that generate .dat file?
    – Tomashiwa
    Dec 1 at 12:57










  • Whichever is more convenient for you. People might want to check their modifications, like comparing the output of your version and their version. I believe the code you've shown here just generates the deck of cards. Maybe you could include all of the code used for it and create a small main function which generates one deck and prints it? For example, at the moment I don't know what Card is (I can guess that it is either an integer or pair which represents a card) and what is ReferenceDeck (vector of cards?).
    – Incomputable
    Dec 1 at 13:13












  • Ah sorry for the confusion, this function is meant to generate a hand, _Target amt of cards, based on the remaining cards in a deck. The generation of ReferenceDeck is in another part of the HandEvaluator class and Card is a class that contains the Suit and Rank with functions to compare with other Cards. Here's the link to the sample project: drive.google.com/file/d/1U3d8ZuS_wzkq4RVIj2RV6gj1zyv_yrco/…
    – Tomashiwa
    Dec 1 at 13:52




















  • Hi, and welcome to CodeReview! I reformatted your code section. Next time, please just paste the code, select it, then press Ctrl + K.
    – Incomputable
    Dec 1 at 9:55










  • Could you please also post other parts of the code used in the post? A little example program which can be compiled and run would be awesome! Don't be concerned with size of the program, 100-200 lines of code is common for a CR question.
    – Incomputable
    Dec 1 at 10:59












  • Thanks for the help ! I've done up a sample project that can be compiled and run. However, my sample project relies on a relatively large .dat file (~126mb) to perform the simulation. Should I include the .dat file into the project and upload them into a file storage site like Google Drive or include another project that generate .dat file?
    – Tomashiwa
    Dec 1 at 12:57










  • Whichever is more convenient for you. People might want to check their modifications, like comparing the output of your version and their version. I believe the code you've shown here just generates the deck of cards. Maybe you could include all of the code used for it and create a small main function which generates one deck and prints it? For example, at the moment I don't know what Card is (I can guess that it is either an integer or pair which represents a card) and what is ReferenceDeck (vector of cards?).
    – Incomputable
    Dec 1 at 13:13












  • Ah sorry for the confusion, this function is meant to generate a hand, _Target amt of cards, based on the remaining cards in a deck. The generation of ReferenceDeck is in another part of the HandEvaluator class and Card is a class that contains the Suit and Rank with functions to compare with other Cards. Here's the link to the sample project: drive.google.com/file/d/1U3d8ZuS_wzkq4RVIj2RV6gj1zyv_yrco/…
    – Tomashiwa
    Dec 1 at 13:52


















Hi, and welcome to CodeReview! I reformatted your code section. Next time, please just paste the code, select it, then press Ctrl + K.
– Incomputable
Dec 1 at 9:55




Hi, and welcome to CodeReview! I reformatted your code section. Next time, please just paste the code, select it, then press Ctrl + K.
– Incomputable
Dec 1 at 9:55












Could you please also post other parts of the code used in the post? A little example program which can be compiled and run would be awesome! Don't be concerned with size of the program, 100-200 lines of code is common for a CR question.
– Incomputable
Dec 1 at 10:59






Could you please also post other parts of the code used in the post? A little example program which can be compiled and run would be awesome! Don't be concerned with size of the program, 100-200 lines of code is common for a CR question.
– Incomputable
Dec 1 at 10:59














Thanks for the help ! I've done up a sample project that can be compiled and run. However, my sample project relies on a relatively large .dat file (~126mb) to perform the simulation. Should I include the .dat file into the project and upload them into a file storage site like Google Drive or include another project that generate .dat file?
– Tomashiwa
Dec 1 at 12:57




Thanks for the help ! I've done up a sample project that can be compiled and run. However, my sample project relies on a relatively large .dat file (~126mb) to perform the simulation. Should I include the .dat file into the project and upload them into a file storage site like Google Drive or include another project that generate .dat file?
– Tomashiwa
Dec 1 at 12:57












Whichever is more convenient for you. People might want to check their modifications, like comparing the output of your version and their version. I believe the code you've shown here just generates the deck of cards. Maybe you could include all of the code used for it and create a small main function which generates one deck and prints it? For example, at the moment I don't know what Card is (I can guess that it is either an integer or pair which represents a card) and what is ReferenceDeck (vector of cards?).
– Incomputable
Dec 1 at 13:13






Whichever is more convenient for you. People might want to check their modifications, like comparing the output of your version and their version. I believe the code you've shown here just generates the deck of cards. Maybe you could include all of the code used for it and create a small main function which generates one deck and prints it? For example, at the moment I don't know what Card is (I can guess that it is either an integer or pair which represents a card) and what is ReferenceDeck (vector of cards?).
– Incomputable
Dec 1 at 13:13














Ah sorry for the confusion, this function is meant to generate a hand, _Target amt of cards, based on the remaining cards in a deck. The generation of ReferenceDeck is in another part of the HandEvaluator class and Card is a class that contains the Suit and Rank with functions to compare with other Cards. Here's the link to the sample project: drive.google.com/file/d/1U3d8ZuS_wzkq4RVIj2RV6gj1zyv_yrco/…
– Tomashiwa
Dec 1 at 13:52






Ah sorry for the confusion, this function is meant to generate a hand, _Target amt of cards, based on the remaining cards in a deck. The generation of ReferenceDeck is in another part of the HandEvaluator class and Card is a class that contains the Suit and Rank with functions to compare with other Cards. Here's the link to the sample project: drive.google.com/file/d/1U3d8ZuS_wzkq4RVIj2RV6gj1zyv_yrco/…
– Tomashiwa
Dec 1 at 13:52












1 Answer
1






active

oldest

votes

















up vote
0
down vote













In the end, I opt to replace Mersenne Twister with another PRNG, xoroshiro128+, it managed to cut the compute time by around 15%. I also did some minor optimization on the for-loop but the improvement is minuscule. Anyway, here is the same function but with new PRNG:



Seeding in HandEvaluator's constructor:



HandEvaluator::HandEvaluator()
{
Initialize();
MTGenerator.seed(std::chrono::high_resolution_clock::now().time_since_epoch().count());

s[0] = std::chrono::high_resolution_clock::now().time_since_epoch().count();
std::cout << "Seed 1: " << s[0] << "n";

s[1] = std::chrono::high_resolution_clock::now().time_since_epoch().count();
std::cout << "Seed 2: " << s[1] << "n";
}


HandEvaluator's RandomFill function:



void HandEvaluator::RandomFill(std::vector<std::shared_ptr<Card>>& _Set, std::vector<std::shared_ptr<Card>>& _Dead, unsigned int _Target)
{
//Add the cards that are currently in Set as dead cards
for (auto const& CardInSet : _Set)
{
if (CardInSet == nullptr)
break;

_Dead.push_back(CardInSet);
}

bool IsDead;
unsigned int RequiredAmt = _Target - _Set.size();

for (unsigned int Index = 0; Index < RequiredAmt; Index++)
{
while (true)
{
_Set.push_back(ReferenceDeck[next() % 52]);

IsDead = false;

for (auto const& Dead : _Dead)
{
if (Dead->IsEqualTo(_Set[_Set.size() - 1]))
{
IsDead = true;
break;
}
}

if (IsDead)
_Set.pop_back();
else
break;
}
}
}





share|improve this answer





















  • If you got rid of the Mersenne Twister you should probably rename MTGenerator
    – bruglesco
    Dec 2 at 15:54










  • Thanks for the heads-up, I had removed MTGenerator from HandEvaluator class as its no longer necessary
    – Tomashiwa
    Dec 2 at 23:27













Your Answer





StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");

StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208814%2ffilling-up-a-hand-with-random-cards-that-are-not-yet-drawn-monte-carlo%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
0
down vote













In the end, I opt to replace Mersenne Twister with another PRNG, xoroshiro128+, it managed to cut the compute time by around 15%. I also did some minor optimization on the for-loop but the improvement is minuscule. Anyway, here is the same function but with new PRNG:



Seeding in HandEvaluator's constructor:



HandEvaluator::HandEvaluator()
{
Initialize();
MTGenerator.seed(std::chrono::high_resolution_clock::now().time_since_epoch().count());

s[0] = std::chrono::high_resolution_clock::now().time_since_epoch().count();
std::cout << "Seed 1: " << s[0] << "n";

s[1] = std::chrono::high_resolution_clock::now().time_since_epoch().count();
std::cout << "Seed 2: " << s[1] << "n";
}


HandEvaluator's RandomFill function:



void HandEvaluator::RandomFill(std::vector<std::shared_ptr<Card>>& _Set, std::vector<std::shared_ptr<Card>>& _Dead, unsigned int _Target)
{
//Add the cards that are currently in Set as dead cards
for (auto const& CardInSet : _Set)
{
if (CardInSet == nullptr)
break;

_Dead.push_back(CardInSet);
}

bool IsDead;
unsigned int RequiredAmt = _Target - _Set.size();

for (unsigned int Index = 0; Index < RequiredAmt; Index++)
{
while (true)
{
_Set.push_back(ReferenceDeck[next() % 52]);

IsDead = false;

for (auto const& Dead : _Dead)
{
if (Dead->IsEqualTo(_Set[_Set.size() - 1]))
{
IsDead = true;
break;
}
}

if (IsDead)
_Set.pop_back();
else
break;
}
}
}





share|improve this answer





















  • If you got rid of the Mersenne Twister you should probably rename MTGenerator
    – bruglesco
    Dec 2 at 15:54










  • Thanks for the heads-up, I had removed MTGenerator from HandEvaluator class as its no longer necessary
    – Tomashiwa
    Dec 2 at 23:27

















up vote
0
down vote













In the end, I opt to replace Mersenne Twister with another PRNG, xoroshiro128+, it managed to cut the compute time by around 15%. I also did some minor optimization on the for-loop but the improvement is minuscule. Anyway, here is the same function but with new PRNG:



Seeding in HandEvaluator's constructor:



HandEvaluator::HandEvaluator()
{
Initialize();
MTGenerator.seed(std::chrono::high_resolution_clock::now().time_since_epoch().count());

s[0] = std::chrono::high_resolution_clock::now().time_since_epoch().count();
std::cout << "Seed 1: " << s[0] << "n";

s[1] = std::chrono::high_resolution_clock::now().time_since_epoch().count();
std::cout << "Seed 2: " << s[1] << "n";
}


HandEvaluator's RandomFill function:



void HandEvaluator::RandomFill(std::vector<std::shared_ptr<Card>>& _Set, std::vector<std::shared_ptr<Card>>& _Dead, unsigned int _Target)
{
//Add the cards that are currently in Set as dead cards
for (auto const& CardInSet : _Set)
{
if (CardInSet == nullptr)
break;

_Dead.push_back(CardInSet);
}

bool IsDead;
unsigned int RequiredAmt = _Target - _Set.size();

for (unsigned int Index = 0; Index < RequiredAmt; Index++)
{
while (true)
{
_Set.push_back(ReferenceDeck[next() % 52]);

IsDead = false;

for (auto const& Dead : _Dead)
{
if (Dead->IsEqualTo(_Set[_Set.size() - 1]))
{
IsDead = true;
break;
}
}

if (IsDead)
_Set.pop_back();
else
break;
}
}
}





share|improve this answer





















  • If you got rid of the Mersenne Twister you should probably rename MTGenerator
    – bruglesco
    Dec 2 at 15:54










  • Thanks for the heads-up, I had removed MTGenerator from HandEvaluator class as its no longer necessary
    – Tomashiwa
    Dec 2 at 23:27















up vote
0
down vote










up vote
0
down vote









In the end, I opt to replace Mersenne Twister with another PRNG, xoroshiro128+, it managed to cut the compute time by around 15%. I also did some minor optimization on the for-loop but the improvement is minuscule. Anyway, here is the same function but with new PRNG:



Seeding in HandEvaluator's constructor:



HandEvaluator::HandEvaluator()
{
Initialize();
MTGenerator.seed(std::chrono::high_resolution_clock::now().time_since_epoch().count());

s[0] = std::chrono::high_resolution_clock::now().time_since_epoch().count();
std::cout << "Seed 1: " << s[0] << "n";

s[1] = std::chrono::high_resolution_clock::now().time_since_epoch().count();
std::cout << "Seed 2: " << s[1] << "n";
}


HandEvaluator's RandomFill function:



void HandEvaluator::RandomFill(std::vector<std::shared_ptr<Card>>& _Set, std::vector<std::shared_ptr<Card>>& _Dead, unsigned int _Target)
{
//Add the cards that are currently in Set as dead cards
for (auto const& CardInSet : _Set)
{
if (CardInSet == nullptr)
break;

_Dead.push_back(CardInSet);
}

bool IsDead;
unsigned int RequiredAmt = _Target - _Set.size();

for (unsigned int Index = 0; Index < RequiredAmt; Index++)
{
while (true)
{
_Set.push_back(ReferenceDeck[next() % 52]);

IsDead = false;

for (auto const& Dead : _Dead)
{
if (Dead->IsEqualTo(_Set[_Set.size() - 1]))
{
IsDead = true;
break;
}
}

if (IsDead)
_Set.pop_back();
else
break;
}
}
}





share|improve this answer












In the end, I opt to replace Mersenne Twister with another PRNG, xoroshiro128+, it managed to cut the compute time by around 15%. I also did some minor optimization on the for-loop but the improvement is minuscule. Anyway, here is the same function but with new PRNG:



Seeding in HandEvaluator's constructor:



HandEvaluator::HandEvaluator()
{
Initialize();
MTGenerator.seed(std::chrono::high_resolution_clock::now().time_since_epoch().count());

s[0] = std::chrono::high_resolution_clock::now().time_since_epoch().count();
std::cout << "Seed 1: " << s[0] << "n";

s[1] = std::chrono::high_resolution_clock::now().time_since_epoch().count();
std::cout << "Seed 2: " << s[1] << "n";
}


HandEvaluator's RandomFill function:



void HandEvaluator::RandomFill(std::vector<std::shared_ptr<Card>>& _Set, std::vector<std::shared_ptr<Card>>& _Dead, unsigned int _Target)
{
//Add the cards that are currently in Set as dead cards
for (auto const& CardInSet : _Set)
{
if (CardInSet == nullptr)
break;

_Dead.push_back(CardInSet);
}

bool IsDead;
unsigned int RequiredAmt = _Target - _Set.size();

for (unsigned int Index = 0; Index < RequiredAmt; Index++)
{
while (true)
{
_Set.push_back(ReferenceDeck[next() % 52]);

IsDead = false;

for (auto const& Dead : _Dead)
{
if (Dead->IsEqualTo(_Set[_Set.size() - 1]))
{
IsDead = true;
break;
}
}

if (IsDead)
_Set.pop_back();
else
break;
}
}
}






share|improve this answer












share|improve this answer



share|improve this answer










answered Dec 2 at 7:41









Tomashiwa

111




111












  • If you got rid of the Mersenne Twister you should probably rename MTGenerator
    – bruglesco
    Dec 2 at 15:54










  • Thanks for the heads-up, I had removed MTGenerator from HandEvaluator class as its no longer necessary
    – Tomashiwa
    Dec 2 at 23:27




















  • If you got rid of the Mersenne Twister you should probably rename MTGenerator
    – bruglesco
    Dec 2 at 15:54










  • Thanks for the heads-up, I had removed MTGenerator from HandEvaluator class as its no longer necessary
    – Tomashiwa
    Dec 2 at 23:27


















If you got rid of the Mersenne Twister you should probably rename MTGenerator
– bruglesco
Dec 2 at 15:54




If you got rid of the Mersenne Twister you should probably rename MTGenerator
– bruglesco
Dec 2 at 15:54












Thanks for the heads-up, I had removed MTGenerator from HandEvaluator class as its no longer necessary
– Tomashiwa
Dec 2 at 23:27






Thanks for the heads-up, I had removed MTGenerator from HandEvaluator class as its no longer necessary
– Tomashiwa
Dec 2 at 23:27




















draft saved

draft discarded




















































Thanks for contributing an answer to Code Review Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


Use MathJax to format equations. MathJax reference.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208814%2ffilling-up-a-hand-with-random-cards-that-are-not-yet-drawn-monte-carlo%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Список кардиналов, возведённых папой римским Каликстом III

Deduzione

Mysql.sock missing - “Can't connect to local MySQL server through socket”