allegroflare / allegro_flare

Application toolkit for Allegro 5
https://clubcatt.com/allegroflare
MIT License
35 stars 6 forks source link

Enable generating *predictable random numbers from Random #205

Closed MarkOates closed 2 years ago

MarkOates commented 2 years ago

Problem

At this time, Random will generate a consistent set of random numbers if the seed is the same ONLY if it is on the same platform and compiler (MacOS, Windows, gcc, clang, etc). If the platform or compiler is different, then the random number output could be different. This can be an issue if you wanted to rely on random numbers to create content (flowers distributed in your game world, procedurally generated content, etc), and you wanted the content to be the same across all the different platforms.

The issue is mentioned in this DISABLED test.

Solution

Random should have options to produce predictable reliable sequences of random numbers, given the same seed.

The solution of how to do it is listed in this SO: https://stackoverflow.com/questions/61069954/c-how-to-produce-random-sequence-completely-determined-by-seed-independent-of

MarkOates commented 2 years ago

This has been fixed in the get_random_int implementation (which is used under-the-hood for get_random_bool, get_one_in_chance, roll_dice, and get_random_color, thus fixing them as well) in 70750ee.

The disabled test has been re-enabled, though it has not yet run on other platforms (Windows) to make sure it works.

Two issues still remain on this topic:

MarkOates commented 2 years ago

get_random_float fixed in 3373f91. get_random_double fixed in 5de4b2e.

Some testing on floating point float and double values were converted to std::string for assertion. A TODO note was added in e829f0b to eventually restore them back to float and double rather than coerced to std::string.

✅ Issue is done

MarkOates commented 2 years ago

Final take

For more background, one test will remain coercing float to string and asserting on string, while the other test will evaluate on the double value directly.

Note the comment:

   // NOTE: this test opts to coerce the floats to strings for comparison due to differences in floating point
   // implementations across platforms.  In the test following this (get_random_double), the test is
   // asserted on the double values themselves.  These two tests are done differently entilrely to demonstrate
   // different techniques, in the event on technique is ultimately preferred over the other.

Note that it's possible and expected that even with direct string and/or double comparisons, it's still possible that floating point hardware could implement floats differently and either of these tests could fail. Here's a SO about the issue.

If we reeeeaaally wanted to be sure floats are reliable across platforms, then we could add a bool to Random that would check if the floats and doubles are a compliant IEEE type, and the user could query that bool to be sure. There's an SO solution to this here.