[SOLVED] Random: don't output the same thing twice

Hi, I have a question about the random command.
It's basically outputing from 1 to 4, but sometimes it prints out 2 same numbers.
Is there any way to prevent this?
Thanks.

What do you expect the random function to do but output random numbers some of which will be same as previously output ?

If you want to have the numbers 1 to 4 in random order and not to be repeated, then the easy way is to put the numbers 1 to 4 in an array and swap 2 values a random number of times

Note, however, that the random() function does not actually output random numbers at all but a fixed series of numbers based on how the function is seeded

Can you show me an example, please?

It sounds like you want a shuffle, not a random number. Search for "arduino shuffle array".

Oh, sorry that I didn't mention that.
I actually want a number.

We understand that you want a number, from a "deck" of numbers, but with the order shuffled.

What did you find in the search suggested earlier?

Oh yeah, I didn't search it up first, now I know what it means.
If I understand, it's basically numbers following a row (2, 3, 8, 6, ...)

An example

byte numbers[] = {1, 2, 3, 4};

void setup()
{
  Serial.begin(115200);
  while (!Serial);
  randomSeed(analogRead(A0));   //a nod towards a real random number
  for (int x = 0; x < 1000; x++)
  {
    byte from = random(4);
    byte to = random(4);
    byte swap = numbers[to];
    numbers[to] = numbers[from];
    numbers[from] = swap;
  }
  for (int x = 0; x < 4; x++)
  {
    Serial.println(numbers[x]);
  }
}

void loop()
{
}
1 Like

You need to read and understand the documentation for the random number generator. Also, any time you have a question about the code you've written, you should post that code so we have a frame of reference for your problem. Read the first 3 posts at the top of this Forum so you know how to properly post source code. You'll get much better responses if you do this.

1 Like

Hi,
You could simply compare the new random number with the last random number.
IF they are the same then go back a generate another random number.
Check again,
IF they aren't the same then output it.

Simple little loop, I have used it many times no array needed to be setup.

Tom... :smiley: :+1: :coffee: :australia:

That was the first thing I was thinking of how to stop it, but I didn't know how.
Could you show me an example?

Hi,
Can you post your code and we will see what we can do..

Tom... :smiley: :+1: :australia:

Sure!
Here it is:

#define middle 0;
#define down 1;
#define up 2;
#define left 3;
#define right 4;

int xValue;
int yValue;
int X;
int Y;
int xCoord = A0;
int yCoord = A1;
int Position;

int Generator;
int counter;

int stopPrint;

String roundsInputString;
int roundsInput;
int roundsCounter;
int roundsPrint;
int waitForRoundsInput;

float timme;
float counted_time;

extern volatile unsigned long timer0_millis;
 
void setup() {
  Serial.begin(9600);
  Serial.println("Hello, and welcome to this observation game!");
  Serial.println("Enjoy!");
}
 
void loop() {
  if (roundsPrint == 0) {
    Serial.println("Enter in a number of how many rounds do you want to play.");
    roundsPrint = 1;
  }
    if (roundsPrint == 1) {
    if (waitForRoundsInput == 0) {
      roundsInputString = Serial.readString(); 
      roundsInput = roundsInputString.toInt();
      if (roundsInput > 0) {waitForRoundsInput = 1;}
     }
     if (waitForRoundsInput == 1) {
      char roundsPrint2[50];
      sprintf(roundsPrint2, "Playing for %d rounds.\n", roundsInput);
      Serial.println(roundsPrint2);
      
      Serial.println("3");
      delay(1000);
      Serial.println("2");
      delay(1000);
      Serial.println("1");
      delay(1000);
      Serial.println("GO!\n");
      
      roundsPrint = 2;
      }
    }
  if (roundsPrint == 2) {
    noInterrupts();
    timer0_millis = 0;
    interrupts ();
      
    Generator = random(1, 5);
    if (Generator == 1) {Serial.print("down\t");}
    if (Generator == 2) {Serial.print("up\t");}
    if (Generator == 3) {Serial.print("left\t");}
    if (Generator == 4) {Serial.print("right\t");}
    
    while(Generator > 0) {
      
      float timme= millis();
      
      xValue = analogRead(xCoord);
      yValue = analogRead(yCoord); 
      X = map(xValue, 50, 1015, 0, 100);
      Y = map(yValue, 50, 1010, 0, 100);
      if(X < 10) {Position = down;}
      if(X > 90) {Position = up;}
      if(Y < 10) {Position = left;}
      if(Y > 90) {Position = right;}
      
      if (Generator == Position) {
        Generator = 0;
        Position = 0;
       }
     }
     roundsCounter = roundsCounter + 1;
     char roundsCounter2[50];
     sprintf(roundsCounter2, "%d/%d", roundsCounter, roundsInput);
     Serial.println(roundsCounter2);
     
     if (roundsCounter == roundsInput) {
      Serial.println("You've done it!\n");
      
      float counted_time= (millis()-timme)/1000;
      Serial.println("Time: " + String(counted_time) + "s\n");
      
      roundsCounter = 0;
      roundsPrint = 0;
      waitForRoundsInput = 0;
      }
   }
}

It depends what the requirement is. If simply never to output the same number twice in a row then comparing the new one with the current one works, but if a range of numbers none of which are repeated is required then that won't work

Do we know what the exact requirement is ?

Well, never to output the same number twice in a row, but if that wouldn't work, I don't know anything else

So 3,1,3,1,3,1... would be ok?

No, numbers from 1 to 4, but never output 2 same numbers.

Then the "compare with the previous number and try again if is the same until a different number is generated" solution is what you want

Yes, exactly.

Never is a long time, especially when you have only four numbers.