FlixelCommunity / flixel

Community fork of Adam “Atomic” Saltsman's popular game engine Flixel. Distilled from a variety of Flash games he worked on over the last couple years, including Gravity Hook, Fathom and Canabalt, its primary function is to provide some useful base classes that you can extend to make your own game objects.
http://flixelcommunity.org/
Other
84 stars 17 forks source link

Add FlxRandom seeded random generator #197

Closed IQAndreas closed 10 years ago

IQAndreas commented 10 years ago

(I touched on this briefly, but I would like to present the idea completely)

Flixel already has a seeded random number generator, but right now the functions are strewn about a little everywhere: Google Docs: FlxMath (see the highlighted blue functions)

What I would like to do is use GSkinner's seeded random generator as a base for a new FlxRandom class.

First of all you have all the static functions:

random():Number // Returns a float between 0 and 1
float(min:Number,max:Number=NaN):Number
boolean(chance:Number=0.5):Boolean
sign(chance:Number=0.5):int // Returns either 1 or -1
bit(chance:Number=0.5):int // Returns either 1 or 0
integer(min:Number,max:Number=NaN):int
shuffle(array:Array):Array
item(array:Array):* // Pick a random item out of an array

Or, you can instead create a new instance (which contains all those methods) that uses a specific seed:

var random:FlxRandom = new FlxRandom(config.seed);
if (random.boolean) { trace("You win!"); }

And most importantly, the static random methods of FlxG are replaced with an instance of FlxRandom. So instead of accessing FlxG.shuffle(array), you use FlxG.random.shuffle(array), plus you get access to the entire collection of FlxRandom helper functions.

Dovyski commented 10 years ago

I like this idea. At first I thought it would just make things more complicated, but since FlxG.random will become an object with several useful methods, it's worth it :)

The only problem I see is random() method, it would lead to FlxG.random.random(). Is it ok?

Gama11 commented 10 years ago

FlxG.random.random() is not very nice IMO. It could be float() and the current float() could be floatRanged() - that's the pattern we followed in HaxeFlixel's FlxRandom.

Dovyski commented 10 years ago

We could also change the float() method to float(min:Number = 0, max:Number=1):Number.

IQAndreas commented 10 years ago

We could also change the float() method to float(min:Number = 0, max:Number=1):Number.

I think that's an excellent solution! We'll go with that.

IQAndreas commented 10 years ago

I love GSkinner's seeded random generator (and I was hoping just to make this a frontend of that class); but, I will be using HaxeFlixel's FlxRandom as a base. That way, someone can do a project in HaxeFlixel and get the same results using the same seed in AS3Flixel.

However, I think HaxeFlixel's random class looks to cluttered and complicated, so even though this class will use the same seeded random generator under the hood and HaxeFlixel, I will be making this FlxRandom class more easy to use, and look more like GSkinner's Rndm.as.

IQAndreas commented 10 years ago

EDIT: This monologue can be safely ignored! See my next comment.

Notice: In these examples, I'm using the ~ operator to mean "roughly" or "about", not the bitwise operator as used in AS3.

One problem I am already noticing (which may or may not end up being any issue), Haxe doesn't "use" the uint datatype natively; instead, that's just a fancy version of int (and with the same max value of ~2 billion). In AS3, the max value of int is ~2 billion, and uint is ~4 billion.

The current random number generator used by HaxeFlixel returns a value between 1 and that ~2 billion value inclusively (and never results in 0!). This means, if you have a function which returns a random uint in the max ranges (that is, between 0 and ~4b), the function will always return an even value between 2 and ~4b. That seems "odd".

You get a similar problem of only returning even (or perhaps it's odd) values if you return the max ranges of int (between ~ -2b and ~ +2b).

Is this going to be an issue? Will people in practice ever want values exactly between the minimum and maximum of a data type?

IQAndreas commented 10 years ago

Ignore my last monologue, after doing more research, according to the experts, HaxeFlixel uses a "better" multiplier. The only large difference is that Rndm.as returns a float from the "main generation function", while FlxRandom.hx returns a uint. However, all helper functions (including intRanged()) call the float() method anyway, so no real performance is being saved.

Give me one more night to do a bit more research, and after that, I will have random number generation down.

dector commented 10 years ago

That's how it's done in Java (using algorithms described in "Art of Programming"):

https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/util/Random.java

IQAndreas commented 10 years ago

Temporarily on hold for this reason:

I would like to make sure the random number generator works the same in both AS3 and Haxe. However, I could theoretically just upload what I have of the generator now, and then tweak it if needed when the reason for the problem (whether it be in my code or Haxe) has been found.

Dovyski commented 10 years ago

I think you could upload what you have and work on it later. The idea of an inter-operable RNG is awesome, but for now we need all classes in place so there will be no merge conflicts in the future.

IQAndreas commented 10 years ago

I feel as a monk walking down from his mountain, enlightened with new wisdom; Lehmer pseudo-randomness: I understand you, and we are one.* I have also learned why the Haxe FlxRandom wasn't working as expected, and how it can be fixed (pull request on its way there too soon).

I have created a pull request with the new FlxRandom class: https://github.com/FlixelCommunity/flixel/pull/207

* I still don't understand how to tell if a multiplier creates a full period without bruteforce testing it, but I'll get there eventually.

Dovyski commented 10 years ago

I feel as a monk walking down from his mountain, enlightened with new wisdom

haha, best comment ever! :smile:

IQAndreas commented 10 years ago

Added in 8bad64f6e9bfba12cc4deae8518de44e09cef474