I want to shuffle an array, simple! There are many examples of code to do this, but the problem is, I want to be able to vary the amount of shuffle.
I have found lots of info on Random number generation, and pseudo-random numbers and their generation techniques.
I have also read up on shuffle algorithms and their importance in some cases
But my implementation is for sequencing lights so the TRUE randomness of the shuffle is not important but the ability to vary the degree of shuffle is.
I.e. I don’t care if the output isn’t absolutely bias free random, so long as I can change the amount of shuffle down to say 50% and see some (half ideally) of the original sequence taking place
Here’s what I wrote, I’d love your feedback and thoughts, not sure how efficient this is or if there’s other ways of doing it so looking forward to some suggestions.
Cheers
// Shuffles values in an array by swapping around 2 random slots, by designating the amount of swaps you can adjust the shuffle amount
// Not much amount range for small arrays - May be too clumsy/time consuming for large arrays
// if array has 20 elements 10 swapcount renders all values shuffled. 5 swapcounts = 50% shuffled
int Temp1;
int Temp2;
int OrgPos;
int SwapPos;
int SwapCount=0;
int LoopCount=0;
int StepPos[16] = { // array with elements numbered from 0 to 19
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
int SeqFor[16] = { // array initializer for comparing
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
void setup() {
Serial.begin(28800);
randomSeed(analogRead(0));
}
void loop() {
if (SwapCount == 0){
Serial.print(" StartTime ");
Serial.println(millis());
}
tryagain:
OrgPos = random(0,16); // choose random table slot and save as OrgPos
if (StepPos[OrgPos] == SeqFor[OrgPos]){ // is StepPos[OrgPos] equal to seqFor[OrgPos]
Temp1 = StepPos[OrgPos]; // if is copy val to Temp1 - end if
}
else goto tryagain; // if not try again
tryagain2:
SwapPos = random (0,16); // choose random table slot and save as SwapPos
if (StepPos[SwapPos] == SeqFor[SwapPos] && SwapPos != OrgPos){ // is StepPos[SwapPos] equal to seqFor[SwapPos] and not same as OrgPos
Temp2 = StepPos[SwapPos]; // if is copy val to Temp2
StepPos[OrgPos] = Temp2; // Paste Temp2 to OrgPos
StepPos[SwapPos] = Temp1; // Paste Temp1 to SwapPos
SwapCount++; // increse swap counter - end if
}
else goto tryagain2; // if not try again
LoopCount++; // for testing only
///////For Testing
// for (int i=0; i<16; i++){
// Serial.print(StepPos[i]);
// Serial.print("-");
// }
// Serial.print(" Swap Count: ");
// Serial.print(SwapCount);
// Serial.print(" Loop Count: ");
// Serial.println(LoopCount);
// for (int i=0; i<16; i++){
// Serial.print(SeqFor[i]);
// Serial.print("-");
// }
// Serial.print(" OrgPos");
// Serial.print(OrgPos+1);
// Serial.print(" SwapPos");
// Serial.print(SwapPos+1);
// Serial.print(" -");
// Serial.println();
// Serial.println();
if (StepPos[0] != SeqFor[0] && StepPos[1] != SeqFor[1] && StepPos[2] != SeqFor[2]
&& StepPos[3] != SeqFor[3] && StepPos[4] != SeqFor[4] && StepPos[5] != SeqFor[5]
&& StepPos[6] != SeqFor[6] && StepPos[7] != SeqFor[7] && StepPos[8] != SeqFor[8]
&& StepPos[9] != SeqFor[9] && StepPos[10] != SeqFor[10] && StepPos[11] != SeqFor[11]
&& StepPos[12] != SeqFor[12] && StepPos[13] != SeqFor[13] && StepPos[14] != SeqFor[14]
&& StepPos[15] != SeqFor[15]){
Serial.print(" ENDTime ");
Serial.println(millis());
// comment out above 'for testing' or this part with reset
for (int i=0; i<16; i++){
Serial.print(StepPos[i]);
Serial.print("-");
}
Serial.print(" All Random");
Serial.println();
for (int i=0; i<16; i++){
Serial.print(SeqFor[i]);
Serial.print("-");
}
Serial.print(" All Original");
//reset
Serial.println();
for (int l=0; l<=15; l++) {
StepPos[l] = SeqFor[l];
}
SwapCount=0;
Serial.println();
}
}