MODULE: Shuffler 1.0 - Linear Feedback Shift Registers for all! (AGS 3.4.0.3+)

Started by Gurok, Fri 10/04/2015 18:59:43

Previous topic - Next topic

Gurok

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:

Code: ags
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.

You can use this function for a variety of things. For instance:

  • Arranging 10 products in a different way on a shelf each time the player plays your game
  • A minigame where the player has to match a random pattern, with one additional step revealed each round
  • A lottery or bingo minigame where every number can be drawn
  • Better emulation of Sierra's dissolve effect (the one with boxes)
  • A shuffled deck:
Code: ags
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:



(Requires AGS 3.4.0.3 or better)
[img]http://7d4iqnx.gif;rWRLUuw.gi

Monsieur OUXX

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.
 

SMF spam blocked by CleanTalk