I am porting a game I originally started in Java into Codea. It’s a solitaire engine that is kind of a geek version of solitaire. I know a geek who kept track of the seed values in free cell because he wanted to make sure he won each game – it’s that built to appeal to that type of crowd.
Anyway I wanted a nice random algorithm. I don’t know what Codea uses, so maybe it’s a good one, but my Googling has indicated that few programming languages default to a “good” random generator. Also, the Mersenne Twister provides a well-documented, decent performance, and commonly used PRNG. Python uses it by default. Lua 5.2 includes a C implementation of it (alas, Codea is 5.1). I used the MT algorithm in my Java code originally. Plus Wikipedia has pseudocode for it, which I can read more easily than C.
I quickly ran into issues when trying to port it into Codea.
- Codea doesn’t do 32-bit unsigned integers
- It’s not obvious how (if even possible) to get a 32-bit number for milliseconds that is usually used as a seed
- Codea doesn’t natively include the bit math (until 5.2, again)
So what I have now appears to be working. It’s entirely possible I messed up part of the algorithm so I need to do some kind of distribution tests to see. But it definitely produces a deck of cards that don’t have an obvious order, so if something is wrong it is one of the bit things were implemented wrong.
I want to share it because it seems like some or all of the code could be useful to lots of people.
If you see stuff to fix, I would welcome it. I wasn’t a CS major so your brains will probably find obvious stuff. I pulled 10,000 numbers from it, put them in a table, added concat and printed and it took under a minute to show.
Parts:
1st is the MT algorithm itself. It is pretty much directly translated from the pseudocode on Wikipedia. To run it, initialize with a seed (format is vec2(16-bit unsigned int, 16-bit unsigned int) … Keep reading for how to get one of those). Next, use mt_inRange(r) to get an int in the range [0,R). I don’t know how to convert 2 16-bit int values into 32-it floating point and since I really just want a value in a range anyway, I didn’t write it. If you prefer to get back 32 bits, just mt_extract instead.
2nd part gets entropy.
HandleGravity, handleAccel, and handleTaps take sensor info from the iPad and get squeeze out the least significant bits from them (my belief is they would be closest to random).
I left handleTaps in there, but I’m only using Gravity and UserAcceleration right now. Another note is I found neither was initialized to anything until at least sometime after setup, after the first draw. The soonest I got any number was after a screen tap, I added a “Tap to continue!” to my UI and collect my entropy after the tap. Not sure if this is on purpose, but not really a problem to my game, so…I left it.
Eventually I want to consider the holy grail of card games, a 52! shuffle (or 104! for double deck games). Right now 32-bits is ok.
3rd part does bit math with a focus on the unique challenges of doing so with vec2(16-bit int, 16-bit int).
Anyway, I submit the code so if any whole or part of it is useful, people can use it.
I’m still kind of new to Lua, so I wasn’t sure if this would be better in a class or 3 classes. So far they seem mostly just for organizational purposes and my code is pretty much 3 distinct things that all need each other … So … It’s just functions for now.
https://docs.google.com/document/d/1_WPn5yOAZWjvtKxbcQI5LAdCcTq6DPwgJgZ-pmVkat8/edit