The purpose of doing this is so that the top of the if statements is not preferred over the bottom. I tried assigning enum values to each case. Then choose a random integer r from 0 to the size of the std::list myList
containing those enum elements. The enum value is found using it = std::next (myList, r)
. Then if the if statement corresponding to that enum value is false
, then myList.erase (it)
, and repeat the process with the newly reduce myList
. It works, and everything seems nicely randomized. But it is disappointingly much slower than when I used the original if-else
statements. Any suggestions to a faster method?
Here is a snippet of my code. There is a crowd of girls. Each guy will choose a girl, and then choose a facing direction to dance with his chosen girl. But not all facing directions are possible if someone is standing at the spot he wants to stand at to get his desired facing direction. Without randomizing the if-else
statements, most of the guys will end up facing the same direction, which I don't like.
std::list<FacingDirection> guyFacingDirections = {Positive_x, Negative_x, Positive_y, Negative_y, Positive_xPositive_y, Positive_xNegative_y, Negative_xPositive_y, Negative_xNegative_y};
while (true) {
const int r = rand() % guyFacingDirections.size();
std::list<FacingDirection>::iterator it = std::next(guyFacingDirections.begin(), r);
const FacingDirection facingDirectionChoice = *it;
if (facingDirectionChoice == Positive_x) // I decided that using switch (facingDirectionChoice) {case Positive_x: if (... was too clumsy in code and probably no more efficient.
{
if (mainArea.locationAvailable (xChoice - 1, yChoice, zChoice))
{guy->movesToNewLocation (xChoice - 1, yChoice, zChoice); break;}
else
guyFacingDirections.erase (it); // more efficient than 'guyFacingDirections.remove (Positive_x);'
}
else if (facingDirectionChoice == Negative_x)
{
if (mainArea.locationAvailable (xChoice + 1, yChoice, zChoice))
{guy->movesToNewLocation (xChoice + 1, yChoice, zChoice); break;}
else
guyFacingDirections.erase (it);
}
else if (facingDirectionChoice == Positive_y)
{
if (mainArea.locationAvailable (xChoice, yChoice - 1, zChoice))
{guy->movesToNewLocation (xChoice, yChoice - 1, zChoice); break;}
else
guyFacingDirections.erase (it);
}
else if (facingDirectionChoice == Negative_y)
{
if (mainArea.locationAvailable (xChoice, yChoice + 1, zChoice))
{guy->movesToNewLocation (xChoice, yChoice + 1, zChoice); break;}
else
guyFacingDirections.erase (it);
}
else if (facingDirectionChoice == Positive_xPositive_y)
{
if (mainArea.locationAvailable (xChoice - 1, yChoice - 1, zChoice))
{guy->movesToNewLocation (xChoice - 1, yChoice - 1, zChoice); break;}
else
guyFacingDirections.erase (it);
}
else if (facingDirectionChoice == Positive_xNegative_y)
{
if (mainArea.locationAvailable (xChoice - 1, yChoice + 1, zChoice))
{guy->movesToNewLocation (xChoice - 1, yChoice + 1, zChoice); break;}
else
guyFacingDirections.erase (it);
}
else if (facingDirectionChoice == Negative_xPositive_y)
{
if (mainArea.locationAvailable (xChoice + 1, yChoice - 1, zChoice))
{guy->movesToNewLocation (xChoice + 1, yChoice - 1, zChoice); break;}
else
guyFacingDirections.erase (it);
}
else if (facingDirectionChoice == Negative_xNegative_y)
{
if (mainArea.locationAvailable (xChoice + 1, yChoice + 1, zChoice))
{guy->movesToNewLocation (xChoice + 1, yChoice + 1, zChoice); break;}
else
guyFacingDirections.erase (it);
}
}
Yes, I did try the following:
Thanks to JLBorges for this suggestion. It turns out that it does NOT perform faster than my original method, but it does tackle the problem of handling arbitrary large number of cases.
It appears that there is currently no way to randomize the ordering of if-else statements while getting the performance to almost match that of an un-randomized set of if-else statements. It should be something for the C++14 committee to work on.