Timer & Exiting Loop & Randomization

int contGame;
int ledArray[3];
int buttonArray[10];
int loopCounter;
int ledCounter;
int inputCounter;
int amountMatch;
int buttonState=0;       
int lastButtonState=0;   
int amoutOutput;
int game;


              
void ledPrompt()//waiting for input
{digitalWrite(10, HIGH);
  delay(1000);
  digitalWrite(10, LOW);
 delay(50);}

void blinkGreen()
 {digitalWrite(5, HIGH);
  delay(250);
  digitalWrite(5, LOW);
  delay(250);
  digitalWrite(5, HIGH);
  delay(250);
  digitalWrite(5, LOW);
   delay(500);}

void blinkOrange()
 {digitalWrite(13, HIGH);
  delay(250);
  digitalWrite(13, LOW);
  delay(250);
  digitalWrite(13, HIGH);
  delay(250);
  digitalWrite(13, LOW);
   delay(500);}

void waitToStart() //cycle through LEDs while awaiting 1st input
  {digitalWrite(2, HIGH);
  delay(250);
  digitalWrite(2, LOW);
  delay(250);
  digitalWrite(3, HIGH);
  delay(250);
  digitalWrite(3, LOW);
  delay(250);
  digitalWrite(4, HIGH);
  delay(250);
  digitalWrite(4, LOW);
  delay(250);
  digitalWrite(5, HIGH);
  delay(250);
  digitalWrite(5, LOW);
  delay(250);}

const int orangeLed = 13;
const int buttonRed = 6;
const int buttonYellow = 7;
const int buttonGreen = 9;
const int buttonBlue = 8;
const int r = 2;
const int y = 3;
const int b = 4;
const int g = 5;
const int gameStart = 12;
const int x = 10;
int count = 0;
int randLedNumber=random(2,5);
int array_Cmp;

void gameHasStarted ()
{digitalWrite(10, HIGH);
  delay(1000);
 digitalWrite(10, LOW);
  delay(1000);}


  


void setup ()
{ 
 Serial.begin(9600);
 pinMode (r, OUTPUT);
 pinMode (y, OUTPUT);
 pinMode (b, OUTPUT);
 pinMode (g, OUTPUT);
  pinMode (buttonRed, INPUT);
 pinMode (buttonYellow, INPUT);
 pinMode (buttonGreen, INPUT);
 pinMode (buttonBlue, INPUT);
 pinMode (gameStart, INPUT);
 pinMode (x, OUTPUT);
loopCounter=1;
ledCounter=0;
  game;
   do{
     if (digitalRead(buttonRed)==LOW)
     {game=2;
     gameHasStarted();}
     if (digitalRead(buttonGreen)==LOW)
      {game=2;
     gameHasStarted();}
     if (digitalRead(buttonBlue)==LOW)
      {game=2;
     gameHasStarted();}
     if (digitalRead(buttonYellow)==LOW)
      {game=2;
     gameHasStarted();}
    else {waitToStart();}
  }
  while(game <= 1);
    delay(1000);
}
void loop (){
   do{  
  randLedNumber=random(2,6);
  digitalWrite(randLedNumber, HIGH);
  delay(250);
  digitalWrite(randLedNumber, LOW);
  delay(250);
  if (randLedNumber==2)
   {ledArray[loopCounter]=0;
    ledCounter++;
  delay(500);}
   if(randLedNumber==3)
   {ledArray[loopCounter]=1;
    ledCounter++;
  delay(500);}
   if(randLedNumber==4)
   {ledArray[loopCounter]=2;
  ledCounter++;
  delay(500);}
   if(randLedNumber==5)
  {ledArray[loopCounter]=3;
  ledCounter++;
  delay(500);}
   }
  while (ledCounter < loopCounter);
   ledPrompt();
 //(buttons)::G(9), Y(7), R(6), B(8)
  //(LEDs):: G(5), Y(3), R(2), B(4)
    do
   {     
      if (digitalRead(buttonRed)==LOW)
     {digitalWrite(r, HIGH);
      inputCounter++;
      delay(100);
      digitalWrite(r,LOW);
      delay(100);
      buttonArray[loopCounter]=0;
      delay(100);} 
    if (digitalRead(buttonYellow)==LOW)
    {digitalWrite(y, HIGH);
      inputCounter++;
      delay(100);
      digitalWrite(y,LOW);
      delay(100);
      buttonArray[loopCounter]=1;
     delay(100);} 
    if (digitalRead(buttonBlue)==LOW)
    {digitalWrite(b, HIGH);
      inputCounter++;
      delay(100);
      digitalWrite(b,LOW);
      delay(100);
      buttonArray[loopCounter]=2;
     delay(100);} 
    if (digitalRead(buttonGreen)==LOW)
    {digitalWrite(g, HIGH);
     inputCounter++;
     delay(100);
     digitalWrite(g, LOW);
     delay(100);
     buttonArray[loopCounter]=3;}
    
 } 
 while (inputCounter < loopCounter);
  delay(1000);
    if (memcmp(ledArray, buttonArray, sizeof(ledArray)) == 0)
       {
      Serial.print("RIGHT");
      delay(1000);
      loopCounter++;
      ledCounter=0;
      inputCounter=0;
      game++;}
      
    else
    {
     Serial.print("WRONG");
     blinkOrange();
      delay(5000);
      loopCounter=0;
      ledCounter=0;
      inputCounter=0;
      waitToStart();
    }
  Serial.print(loopCounter);
  }

HI! I really want to extend sincere gratitude to those who have helped with tips and pointers through this project since I started it. I've now gotten things to a pretty great place and I'm so relieved.

This is a Simon Says game.
I need to add 3 minor components to the project then it'll be perfect.

  1. When the board is on, it'll display the LEDs in a cycle until any of the 4 buttons are pressed, then it'll start the game. It's supposed to choose the first LED to light up and this is supposed to be random but my issue is it keeps setting up the same LEDs through all of the rounds. So it's very easy to learn the cycle. How do I achieve true randomization?
  2. I want to be able to put a time limit on how long to wait for input. I was hoping to wait a certain length of time for the first input and then expand the time with each input but I have no clue how to go about this.
  3. Lastly, I need to be able to end the game at the 10th round and run the code again to have it go through Void Setup and then back to void loop but haven't found anything on the internet regarding this. I also need to do this for when the match is wrong.

I made this new thread because the other has gotten pretty far and I feel this is a good place to start a new one. Mods are welcome to lock the other one though I wouldn't delete it because perhaps others may learn from it. Thank you!!

premobowei:
I made this new thread because the other has gotten pretty far and I feel this is a good place to start a new one. Mods are welcome to lock the other one though I wouldn't delete it because perhaps others may learn from it. Thank you!!

I haven't looked at the other thread, but I think the best thing to do would be to add a note to that thread to explain that you've started a new one and provide a link to this one. That should help to avoid wasting time due to having parallel discussions between the two threads.

I'm reluctant to lock the thread because there may be legitimate cause for ongoing discussion in the future on subjects that are specific to that thread. And of course we would never delete the thread for the reason you mentioned. In addition to being a place for people to ask questions, the Arduino forum is a collection of knowledge that acts (and will continue to act for years to come) as a resource for many people who have never posted here, but find existing threads while searching for information.

True randomization would come from random numbers coming from a truly random source. The next best thing is to use a random seed from a random source. Doing an analogRead(...) of a disconnected A0 is sometimes used for the random source.

The least significant bit is likely to be random. Each more significant bit may be less random but may be helpful for your situation.

Note that a repeatable sequence is good for testing and debugging. Truly random numbers should be avoided until most testing and debugging is complete.

OK...thank you so so much guys. I've resolved the part about exiting the game and restarting once it gets to round 10.

Now for the timer and randomization.

I've read this link but I can't find any examples. My numbers are limited between 2 and 5 (2 and 6) so I have to specify a min and max so Idk how to do that with the random seed. Thanks

The problem is that any computer, micro-controller or otherwise, is a deterministic machine, making getting true randomness (as opposed to something pseudo-random) out of it based purely on its internal operation somewhere between very difficult and impossible. You have one good suggestion, here is a different one. One source of randomness is that the machine does not know when someone is going to press a button, and you can exploit this. For example, if you increment a counter on every cycle through loop and read the counter when someone presses the button then the number you read will be random as there is no link between when the person presses the button and what number happens to be in the counter when they do. If you then save that number in EEPROM or FLASH you can read it when you next power up the machine and it will be a random number, at least, sufficiently random for what you are doing.

at Perry, great idea but I still haven't figured out how to even time the wait for input yet and also that seems like it'll complicate my code which I don't want to do cause I finally got it to a place where it's working for the basic requirements. I do want to explore the randomSeed or using the A0 but not sure how to do that and can't find any tutorials.

In order to initialize a random sequence, you could store a seed in eeprom and upon each reset, generate a new seed. Something like this would go into "setup()":

eeprom.get(address, seed)
randomseed(seed)
seed = random(seed_max_value)
eeprom.put(address, seed)

Your game seems to be constructed of different states, you should try to create a state machine instead of your current approach. Having parts of the functionality inside "setup()" is a bad idea if you need to re-use it during operation.

@Danois, yes I fixed that by creating the initiating process as a different function and calling it in setup as well as calling it when the person fails to match, or when the game reaches its max level.

int contGame;
int ledArray[3];
int buttonArray[10];
int loopCounter;
int ledCounter;
int inputCounter;
int amountMatch;
int buttonState=0;       
int lastButtonState=0;   
int amoutOutput;
int game;


              
void ledPrompt()//waiting for input
{digitalWrite(10, HIGH);
  delay(1000);
  digitalWrite(10, LOW);
 delay(50);}

void blinkGreen()
 {digitalWrite(5, HIGH);
  delay(250);
  digitalWrite(5, LOW);
  delay(250);
  digitalWrite(5, HIGH);
  delay(250);
  digitalWrite(5, LOW);
   delay(500);}

void blinkOrange()
 {digitalWrite(13, HIGH);
  delay(250);
  digitalWrite(13, LOW);
  delay(250);
  digitalWrite(13, HIGH);
  delay(250);
  digitalWrite(13, LOW);
   delay(500);}

void waitToStart() //cycle through LEDs while awaiting 1st input
  {digitalWrite(2, HIGH);
  delay(250);
  digitalWrite(2, LOW);
  delay(250);
  digitalWrite(3, HIGH);
  delay(250);
  digitalWrite(3, LOW);
  delay(250);
  digitalWrite(4, HIGH);
  delay(250);
  digitalWrite(4, LOW);
  delay(250);
  digitalWrite(5, HIGH);
  delay(250);
  digitalWrite(5, LOW);
  delay(250);}

const int orangeLed = 13;
const int buttonRed = 6;
const int buttonYellow = 7;
const int buttonGreen = 9;
const int buttonBlue = 8;
const int r = 2;
const int y = 3;
const int b = 4;
const int g = 5;
const int gameStart = 12;
const int x = 10;
int count = 0;
int randLedNumber=random(2,5);
int array_Cmp;

void gameHasStarted ()
{digitalWrite(10, HIGH);
  delay(1000);
 digitalWrite(10, LOW);
  delay(1000);}

void initiate(){
 game=0;
   do{
     if (digitalRead(buttonRed)==LOW)
     {game=2;
     gameHasStarted();}
     if (digitalRead(buttonGreen)==LOW)
      {game=2;
     gameHasStarted();}
     if (digitalRead(buttonBlue)==LOW)
      {game=2;
     gameHasStarted();}
     if (digitalRead(buttonYellow)==LOW)
      {game=2;
     gameHasStarted();}
    else {waitToStart();}
  }
  while(game <= 1);
    delay(1000);  
}

void setup ()
{ 
 Serial.begin(9600);
 pinMode (r, OUTPUT);
 pinMode (y, OUTPUT);
 pinMode (b, OUTPUT);
 pinMode (g, OUTPUT);
  pinMode (buttonRed, INPUT);
 pinMode (buttonYellow, INPUT);
 pinMode (buttonGreen, INPUT);
 pinMode (buttonBlue, INPUT);
 pinMode (gameStart, INPUT);
 pinMode (x, OUTPUT);
loopCounter=1;
ledCounter=0;
 initiate();
}
void loop (){
   do{  
  randLedNumber=random(2,6);
  digitalWrite(randLedNumber, HIGH);
  delay(250);
  digitalWrite(randLedNumber, LOW);
  delay(250);
  if (randLedNumber==2)
   {ledArray[loopCounter]=0;
    ledCounter++;
  delay(500);}
   if(randLedNumber==3)
   {ledArray[loopCounter]=1;
    ledCounter++;
  delay(500);}
   if(randLedNumber==4)
   {ledArray[loopCounter]=2;
  ledCounter++;
  delay(500);}
   if(randLedNumber==5)
  {ledArray[loopCounter]=3;
  ledCounter++;
  delay(500);}
   }
  while (ledCounter < loopCounter);
   ledPrompt();
 //(buttons)::G(9), Y(7), R(6), B(8)
  //(LEDs):: G(5), Y(3), R(2), B(4)
    do
   {     
      if (digitalRead(buttonRed)==LOW)
     {digitalWrite(r, HIGH);
      inputCounter++;
      delay(100);
      digitalWrite(r,LOW);
      delay(100);
      buttonArray[loopCounter]=0;
      delay(100);} 
    if (digitalRead(buttonYellow)==LOW)
    {digitalWrite(y, HIGH);
      inputCounter++;
      delay(100);
      digitalWrite(y,LOW);
      delay(100);
      buttonArray[loopCounter]=1;
     delay(100);} 
    if (digitalRead(buttonBlue)==LOW)
    {digitalWrite(b, HIGH);
      inputCounter++;
      delay(100);
      digitalWrite(b,LOW);
      delay(100);
      buttonArray[loopCounter]=2;
     delay(100);} 
    if (digitalRead(buttonGreen)==LOW)
    {digitalWrite(g, HIGH);
     inputCounter++;
     delay(100);
     digitalWrite(g, LOW);
     delay(100);
     buttonArray[loopCounter]=3;}
    
 } 
 while (inputCounter < loopCounter);
  delay(1000);
  do{
    if (memcmp(ledArray, buttonArray, sizeof(ledArray)) == 0)
       {
      Serial.print("RIGHT");
      delay(1000);
      loopCounter++;
      ledCounter=0;
      randLedNumber=0;
      inputCounter=0;
      game++;}
      
    else
    {
     Serial.print("WRONG");
     blinkOrange();
      game=0;
      initiate();
    }
    } 
  while (loopCounter < 10); 
  Serial.print("YOU WIN, I GIVE UP");
  delay(1000);
  initiate();
  Serial.print(loopCounter);
  }

For the eeprom thing, how would that work? I need it to pick one out of 4 LEDs to light up in the first round and then in the second round it'll pick 2 and so forth but both numbers need to be random and this would take place inside void loop.

premobowei:
random() - Arduino Reference

I've read this link but I can't find any examples. My numbers are limited between 2 and 5 (2 and 6) so I have to specify a min and max so Idk how to do that with the random seed. Thanks

Did you read that page's sibling, linked from that page?

My suggestion is only relevant for initializing a random sequence which differs each time the device is powered on. How you pick the LED's using random numbers is entirely up to you :slight_smile:

for the eeprom, how would I call it in the void loop?

premobowei:
for the eeprom, how would I call it in the void loop?

You would not do that at all. As I wrote in my post, the pseudo-code should be called ONCE inside setup() to INITIALIZE a random sequence. After this, you can call "random()" as you already do.

@Dan yeah it messed up my code for some reason. I'll just have to accept that it'll use the same LEDs even though it shouldn't. Maybe I can tweak it later.

Guess that leaves the timer issue.

The cited link has an example with this line:

randomSeed(analogRead(0));

No range limitation of the seed is needed. It doesn't get much simpler than this.

??? I know no range limitation is needed but it can only choose a number between 2 and 4. No limitiation is needed for the code but for what I'm trying to do it is needed. But already moved past that.
What I need to figure out now is a way to control the time it waits for input.

So, I've successfully achieved everything I needed to and after about a week of work, I've created my Simon says with all of the functions I was looking for.

The only thing i didn't achieve was true randomization but I'll take that loss.
Also, I'm not sure about my buttons but they work and I don't seem to have any floating going on so that's great. I've also attached my wiring and setup which will copy onto the actual game (the extra button will be taken off). .

THANK YOU SO SO SO MUCH TO EVERYONE WHO GUIDED ME THROUGH THIS. I ACTUALLY NOW HAVE SOME RESPECT AND UNDERSTANDING OF CODING. THIS WAS GREAT!!!

This is the final product.

int contGame;
int ledArray[3];
int buttonArray[10];
int loopCounter;
int ledCounter;
int inputCounter;
int amountMatch;
int buttonState=0;       
int lastButtonState=0;   
int amoutOutput;
int game;
int waiting;

             
void ledPrompt()//waiting for input
{digitalWrite(10, HIGH);
  delay(1000);
  digitalWrite(10, LOW);
 delay(50);}

void blinkGreen()
 {digitalWrite(5, HIGH);
  delay(250);
  digitalWrite(5, LOW);
  delay(250);
  digitalWrite(5, HIGH);
  delay(250);
  digitalWrite(5, LOW);
   delay(500);}

void blinkOrange()
 {digitalWrite(13, HIGH);
  delay(250);
  digitalWrite(13, LOW);
  delay(250);
  digitalWrite(13, HIGH);
  delay(250);
  digitalWrite(13, LOW);
   delay(500);}

void waitToStart() //cycle through LEDs while awaiting 1st input
  {digitalWrite(2, HIGH);
  delay(250);
  digitalWrite(2, LOW);
  delay(250);
  digitalWrite(3, HIGH);
  delay(250);
  digitalWrite(3, LOW);
  delay(250);
  digitalWrite(4, HIGH);
  delay(250);
  digitalWrite(4, LOW);
  delay(250);
  digitalWrite(5, HIGH);
  delay(250);
  digitalWrite(5, LOW);
  delay(250);}

const int orangeLed = 13;
const int buttonRed = 6;
const int buttonYellow = 7;
const int buttonGreen = 9;
const int buttonBlue = 8;
const int r = 2;
const int y = 3;
const int b = 4;
const int g = 5;
const int gameStart = 12;
const int x = 10;
int count = 0;
int randLedNumber=random(2,5);
int array_Cmp;

void gameHasStarted ()
{digitalWrite(10, HIGH);
  delay(1000);
 digitalWrite(10, LOW);
  delay(1000);}

void initiate(){

game=0;
waiting=0;
loopCounter=1;
randLedNumber=0;
ledCounter=0;
game=0;
   do{
     if (digitalRead(buttonRed)==LOW)
     {game=2;
     gameHasStarted();}
     if (digitalRead(buttonGreen)==LOW)
      {game=2;
     gameHasStarted();}
     if (digitalRead(buttonBlue)==LOW)
      {game=2;
     gameHasStarted();}
     if (digitalRead(buttonYellow)==LOW)
      {game=2;
     gameHasStarted();}
    else {waitToStart();}
  }
  while(game <= 1);
    delay(1000); 
}

void setup ()
{
 Serial.begin(9600);
 pinMode (r, OUTPUT);
 pinMode (y, OUTPUT);
 pinMode (b, OUTPUT);
 pinMode (g, OUTPUT);
  pinMode (buttonRed, INPUT);
 pinMode (buttonYellow, INPUT);
 pinMode (buttonGreen, INPUT);
 pinMode (buttonBlue, INPUT);
 pinMode (gameStart, INPUT);
 pinMode (x, OUTPUT);
loopCounter=1;
  randLedNumber=0;
ledCounter=0;
 initiate();
}
void loop (){
   do{ 
  randLedNumber=random(2,6);
  digitalWrite(randLedNumber, HIGH);
  delay(250);
  digitalWrite(randLedNumber, LOW);
  delay(250);
  if (randLedNumber==2)
   {ledArray[loopCounter]=0;
    ledCounter++;
  delay(500);}
   if(randLedNumber==3)
   {ledArray[loopCounter]=1;
    ledCounter++;
  delay(500);}
   if(randLedNumber==4)
   {ledArray[loopCounter]=2;
  ledCounter++;
  delay(500);}
   if(randLedNumber==5)
  {ledArray[loopCounter]=3;
  ledCounter++;
  delay(500);}
   }
  while (ledCounter < loopCounter);
   ledPrompt();
 //(buttons)::G(9), Y(7), R(6), B(8)
  //(LEDs):: G(5), Y(3), R(2), B(4)
    do
   {     
      if (digitalRead(buttonRed)==LOW)
     {digitalWrite(r, HIGH);
      inputCounter++;
      delay(150);
      digitalWrite(r,LOW);
      delay(150);
      buttonArray[loopCounter]=0;}
    if (digitalRead(buttonYellow)==LOW)
    {digitalWrite(y, HIGH);
      inputCounter++;
      delay(150);
      digitalWrite(y,LOW);
      delay(150);
      buttonArray[loopCounter]=1;}
      if (digitalRead(buttonBlue)==LOW)
    {digitalWrite(b, HIGH);
      inputCounter++;
      delay(150);
      digitalWrite(b,LOW);
      delay(150);
     buttonArray[loopCounter]=2;}
    if (digitalRead(buttonGreen)==LOW)
    {digitalWrite(g, HIGH);
     inputCounter++;
     delay(150);
     digitalWrite(g, LOW);
     delay(150);
     buttonArray[loopCounter]=3;}
      else {waiting++;
           Serial.print(waiting);
           delay(500);
           }
      if (waiting>=20)
      {initiate();}
 }
 while (inputCounter < loopCounter);//WAIT FOR INPUT
  
    if (memcmp(ledArray, buttonArray, sizeof(ledArray)) == 0)
    {
      Serial.print("RIGHT");
      delay(1000);
      loopCounter++;
      ledCounter=0;
      randLedNumber=0;
      inputCounter=0;
      game++;
     Serial.print(loopCounter);}
     
     
    else
    {
     Serial.print("WRONG");
     blinkOrange();
      game=0;
      initiate();
    }
  if (loopCounter > 9)
  {
  Serial.print("YOU WIN, I GIVE UP");
  delay(1000);
  initiate();
  }
  }

The example shows how to achieve randomization. The example shows how to get random integers in a range but you already know how to do that.

One line in the setup() function would get you the desired randomization but you have to insert the line yourself.

pert:
I haven't looked at the other thread, but I think the best thing to do would be to add a note to that thread to explain that you've started a new one and provide a link to this one. That should help to avoid wasting time due to having parallel discussions between the two threads.

I asked you nicely to do something and explained why I wanted you to do it. So why didn't you?

You definitely want to use randomSeed() I don't understand why you wouldn't do that after it was explained so clearly to you.

For this purpose, the analog reading as a seed to the PRNG should be fine (assuming the pin is floating), but that is really not an ideal solution when you want good randomization. When it matters, and when you don't have TRNG hardware available, the best solution is to use timer jitter, as is done in the Entropy library: