Adventure Game Studio

AGS Support => Modules, Plugins & Tools => Topic started by: Gurok on Fri 10/04/2015 18:59:43

Title: MODULE: Shuffler 1.0 - Linear Feedback Shift Registers for all! (AGS 3.4.0.3+)
Post by: Gurok on Fri 10/04/2015 18:59:43
If you've ever wanted a *really* efficient way to generate a set of shuffled numbers, then this is the module for you.

Shuffler contains a single function called sequence. You call it like so:

int myArray[ ];

myArray = Shuffler.Sequence(10);


The result is that myArray contains 10 numbers (0-9) in a random order. e.g. (2, 5, 7, 3, 9, 0, 6, 1, 8, 4)

The array will always contain all of the numbers that make up a sequence starting at 0 and ending at N-1 where N is the array size you specified.

It works by using linear feedback shift registers. You can read more about them here (http://en.wikipedia.org/wiki/Linear_feedback_shift_register).

You can use this function for a variety of things. For instance:
String GetCardName(int index)
{
String suit;
String face;
int value;

value = index / 13;
if(value == 0)
suit = "spades";
else
if(value == 1)
suit = "hearts";
else
if(value == 2)
suit = "diamonds";
else
suit = "clubs";
value = index % 13;
if(value == 0)
face = "ace";
else
if(value == 10)
face = "jack";
else
if(value == 11)
face = "queen";
else
if(value == 12)
face = "king";
else
face = String.Format("%d", value + 2);

return(String.Format("The %s of %s", face, suit));
}

function DrawDeck()
{
int list[ ];
int index;
String output;

list = Shuffler.Sequence(52);
output = GetCardName(list[0] + 1);
for(index = 1; index < 52; index++)
{
output = output.Append("[");
output = output.Append(GetCardName(list[index] + 1));
}
Display(output);

return;
}


Note: If you run DrawDeck in the example above, you'll notice one of the limitations of linear feedback shift registers. The code will most likely give you a different shuffle each time you run it, but you might notice similarities between two shuffles. e.g. One may appear to be a shifted version of another.

You might be thinking, hang on, this module is a huge chunk of code. Why would I use this instead of a naive approach (like choose a number, scan the list to see if it's already been chosen, if so, choose again)? And to top it off it's also flawed (see note above).

Well, it's fast. VERY fast. In computer science terms, its speed is also pretty well defined. Big O for this algorithm is just under 2N. That means at worst, it performs half as well as a linear function. The naive alternative? That might run forever.

It's also predictable. There's a second parameter to the Shuffler.Sequence function that lets you specify a seed number. A seeded sequence is guaranteed to give you the same sequence for that seed every time. That means you can save an entire sequence by saving a single number. The limit for seed numbers is the next power of 2 above your chosen limit. So for 52, unique seed numbers are 1-64 and they repeat after that. 0 means let Shuffler choose one.

Download here:


Shuffler 1.0 (http://goo.gl/9WSi0d)

(Requires AGS 3.4.0.3 or better)
Title: Re: MODULE: Shuffler 1.0 - Linear Feedback Shift Registers for all! (AGS 3.4.0.3+)
Post by: Monsieur OUXX on Mon 13/04/2015 16:36:52
Cool. I always write my own and it's really, really poorly written. I'm even pretty sure mine could make the game slow down in some unlucky cases.