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);
}
}
Good news, you can both make this run faster, make the code a lot shorter, a lot clearer and easier to move...not to mention give the behavior you want - all in one easy move :)
Define a list of facing directions:
Then define an array:
Define a random number generator somewhere:
Now your code to process it just becomes:
The general idea is that your define a Strategy pattern to determine if something is valid.
You then set up a list containing all the various permutations of that strategy pattern.
You then loop through the list starting from a random position.
The code above may need some tidying up as I just threw it together, it should give you something to build on though.