I found this great code to pick a random number from a "hat" without repeat:
/* RandomHat
Paul Badger 2007 - updated for Teensy compile 2017
choose one from a hat of n consecutive choices each time through loop
Choose each number exactly once before reseting and choosing again
*/
#define randomHatStartNum 0 // starting number in hat
#define randomHatEndNum 25 // ending number in hat - end has to be larger than start
#define numberInHat (randomHatEndNum - randomHatStartNum) + 1
void setup()
{
Serial.begin(9600);
Serial.println("start ");
}
void loop()
{ // randomHat test
for (int i = 1; i <= numberInHat; i++) {
int x = randomHat();
Serial.print(x);
Serial.print(", ");
delay(50);
}
Serial.println(" ");
}
int randomHat() {
int thePick; //this is the return variable with the random number from the pool
int theIndex;
static int currentNumInHat = 0;
static int randArray[numberInHat];
if (currentNumInHat == 0) { // hat is emply - all have been choosen - fill up array again
for (int i = 0 ; i < numberInHat; i++) { // Put 1 TO numberInHat in array - starting at address 0.
if (randomHatStartNum < randomHatEndNum) {
randArray[i] = randomHatStartNum + i;
}
}
currentNumInHat = abs(randomHatEndNum - randomHatStartNum) + 1; // reset current Number in Hat
Serial.print(" hat is empty ");
// if something should happen when the hat is empty do it here
}
theIndex = random(currentNumInHat); //choose a random index from number in hat
thePick = randArray[theIndex];
randArray[theIndex] = randArray[currentNumInHat - 1]; // copy the last element in the array into the the empty slot
// // as the the draw is random this works fine, and is faster
// // the previous version. - from a reader suggestion on this page
currentNumInHat--; // decrement number in hat
return thePick;
}
I would like to use a custom array to choose from like so:
char *things[]={
"Thing 1",
"Thing 2",
"Thing 3",
"Thing 4",
"Thing 5",
"Thing 6",
};
Which is quite possible as I use the numbers from to first piece of code to select items from my custom array.
So I have two questions about this:
The first being the code first returns "hat is empty" before the numbers.
start
hat is empty 11, 24, 17, .......
hat is empty 4, 19, 23, .......
Is there a way to reverse this?
And secondly, I would like define the randomHatEndNum
automatic by the lenght of my custom array, but I have trouble implementing that code. What is the right way to approach this?