Here's the class code:
Code: Select all
class RandomSequence
{
array<int> numbers;
int nextIndex;
double factor;
bool justShuffled;
bool PreventRepeats;
static RandomSequence NewInstance(int FirstValue, int LastValue, double factor = 1.0, bool PreventRepeats=false)
{
//spawn
RandomSequence newSequence = new("RandomSequence");
//populate
for (int i = FirstValue; i <= LastValue; i++) newSequence.numbers.push(i);
newSequence.factor=factor;
newSequence.PreventRepeats=PreventRepeats;
newSequence.shuffle();
return newSequence;
}
void shuffle()
{
int last=numbers[numbers.size()-1];
int size=numbers.size();
for (int i = 0; i < size; i++)
{
int next=random(0,size-1);
int temp=numbers[i];
numbers[i]=numbers[next];
numbers[next]=temp;
}
if (PreventRepeats && numbers[0]==last && numbers.size()>1)
{
int next=random(1,size-1);
numbers[0]=numbers[next];
numbers[next]=last;
}
nextIndex=0;
justShuffled=true;
}
int GetNext()
{
justShuffled=false;
let thisNumber=numbers[nextIndex];
nextIndex++;
if (nextIndex >= numbers.size()) shuffle();
return thisNumber;
}
double fGetNext()
{
return factor * GetNext();
}
void print()//for debugging
{
console.printf("Array from "..GetClassName()..":");
if (!numbers.size()) console.printf("[EMPTY]");
for (int i=0;i<numbers.size();i++)
console.printf("["..i.."]"..numbers[i]..((factor==1.0)?"":" "..(factor*numbers[i])));
}
}
RandomSequence MyRandom=RandomSequence.NewInstance(1,10);
then in your code, instead of this:
let SomeNumber = random(1,10);
do this:
let SomeNumber = MyRandom.GetNext();
If you want fractions instead of integers, for example numbers between 1 and 2 in 0.25 increments, do this:
RandomSequence MyRandom=RandomSequence.NewInstance(4,8,0.25);
and get it like this:
let SomeNumber = MyRandom.fGetNext();
These sequences won't have any repeats, but a repeat is possible. Imagine you have a deck of 52 cards, you draw all the cards and the last one is the Ace of Spades. You shuffle the cards and draw the first one from the new deck. There is a 1/52 chance that this card will be the Ace of Spades, so it appears that there is a repeat in the sequence. If you want to prevent that from happening, set PreventRepeats to true:
RandomSequence MyRandom=RandomSequence.NewInstance(0,51,PreventRepeats:true);
On each shuffle it will check if the old last pick is the same as the new first pick and if so shuffle it back in.
I also created code for creating random number sequences in my sorting library but this is a streamlined version.