Problem with code for arduino game

Hello, I am trying to make a game that five leds alternate randomly and when a button is pressed, the last light that was on stays on. Each led has 5 questions and chooses one of its five questions and displays it on the lcd when it is the led that stays on. But right now the code is only working for one led and the questions aren't displaying for the other leds.(using three leds just for this)

#include <Adafruit_LiquidCrystal.h>
Adafruit_LiquidCrystal lcd(0);
int Button = 6;
int button_state;
int White = 11;
int White_state;
const char* wq1 = "what is WAR";
const char* wq2 = "what is WBR";
const char* wq3 = "what is WCR";
const char* wq4 = "what is WDR";
const char* wq5 = "what is WER";
int Yellow = 9;
int Yellow_state;
const char* yq1 = "what is YAR";
const char* yq2 = "what is YBR";
const char* yq3 = "what is YCR";
const char* yq4 = "what is YDR";
const char* yq5 = "what is YER";
int Green = 10;
int Green_state;
const char* gq1 = "what is GAR";
const char* gq2 = "what is GBR";
const char* gq3 = "what is GCR";
const char* gq4 = "what is GDR";
const char* gq5 = "what is GER";
int lights[] = {White, Green, Yellow};
int numLights = sizeof(lights) / sizeof(lights[0]);
long random_question;

void setup() {
  Serial.begin(9600);
  pinMode(Button, INPUT);
  lcd.begin(16, 2);
  lcd.clear();
  lcd.print("  Button Press");
  delay(1000);
  // Set each pin as an output
    pinMode(White, OUTPUT);
    pinMode(Green, OUTPUT);
    pinMode(Yellow, OUTPUT);
    pinMode(Button, INPUT);
    
  
}

void loop() {
  random_question = random(1, 5);
  // Turn off all lights
  turnOffAllLights();
  lcd.setCursor(0,0);
  lcd.print("COMP SCI GAME");

  // Turn on a random light
  int randomIndex = random(numLights);
  digitalWrite(lights[randomIndex], HIGH);

  delay(1000); // Adjust delay as needed
  button_state = digitalRead(Button);
  White_state = digitalRead(White);
  Yellow_state = digitalRead(Yellow);
  Green_state = digitalRead(Green);
  
  while(button_state == HIGH)
  {
   lcd.clear();
   button_state = digitalRead(Button);
   White_state = digitalRead(White);
   Yellow_state = digitalRead(Yellow);
   Green_state = digitalRead(Green);
    
    while(White_state == HIGH)
    {
     button_state = digitalRead(Button);
      if(button_state == LOW){
        break;}
        while(button_state == HIGH)
        {White_state = digitalRead(White);
        Serial.println(random_question);
          if(random_question == 1){lcd.setCursor(0,0); lcd.print(wq1);}
          if(random_question == 2){lcd.setCursor(0,0); lcd.print(wq2);}
          if(random_question == 3){lcd.setCursor(0,0); lcd.print(wq3);}
          if(random_question == 4){lcd.setCursor(0,0); lcd.print(wq4);}
          if(random_question == 5){lcd.setCursor(0,0); lcd.print(wq5);}
        button_state = digitalRead(Button);
    }
    while(Yellow_state == HIGH)
    {
      button_state = digitalRead(Button);
      if(button_state == LOW){
        break;}
        while(button_state == HIGH)
        {Yellow_state = digitalRead(Yellow);
        Serial.println(random_question);
          if(random_question == 1){lcd.setCursor(0,0); lcd.print(yq1);}
          if(random_question == 2){lcd.setCursor(0,0); lcd.print(yq2);}
          if(random_question == 3){lcd.setCursor(0,0); lcd.print(yq3);}
          if(random_question == 4){lcd.setCursor(0,0); lcd.print(yq4);}
          if(random_question == 5){lcd.setCursor(0,0); lcd.print(yq5);}
        button_state = digitalRead(Button);
    }
    while(Green_state == HIGH)
    {

      button_state = digitalRead(Button);
      if(button_state == LOW){
        break;}
        while(button_state == HIGH)
        {Green_state = digitalRead(Green);
        Serial.println(random_question);
          if(random_question == 1){lcd.setCursor(0,0); lcd.print(gq1);}
          if(random_question == 2){lcd.setCursor(0,0); lcd.print(gq2);}
          if(random_question == 3){lcd.setCursor(0,0); lcd.print(gq3);}
          if(random_question == 4){lcd.setCursor(0,0); lcd.print(gq4);}
          if(random_question == 5){lcd.setCursor(0,0); lcd.print(gq5);}
        button_state = digitalRead(Button);
        }
       }
    }
    }}
  
}

    void turnOffAllLights() {

  // Turn off all lights
  for (int i = 0; i < numLights; i++) {
    digitalWrite(lights[i], LOW);
    lcd.clear();
  }
  }



Why is pinMode(Button,INPUT); done twice...?

accident

Hi @l4v3r

I suggest that you rebuild the simulation of this project in the WOKWI-Simulator.

This enables easy collaboration without the need for registering at autodesk

The lcd in the WOKWI-Simulator isn't working, and I think it's more of a code problem than a simulator problem

try this

click to see the code
// using https://www.arduino.cc/reference/en/libraries/hd44780 for the LCD

#include <Wire.h>
#include <hd44780.h>                       // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header

//using https://github.com/Dlloydev/Toggle for the button
#include <Toggle.h>

hd44780_I2Cexp lcd;
const int LCD_COLS = 16;
const int LCD_ROWS = 2;

const byte buttonPin = 2;
Toggle button;

unsigned long lastTick;
const unsigned long tickPeriod = 100; // ms

enum {PAUSED, RUNNING, ASKING} state = PAUSED;

class Led {
    const char ** questions;
    const size_t questionCount;
    const byte ledPin;
  public:
    Led (const byte pin, const char ** q, const size_t n) :
      ledPin(pin), questions(q),  questionCount(n) {}

    void begin() {
      pinMode(ledPin, OUTPUT);
    }

    void flip() {
      digitalWrite(ledPin, digitalRead(ledPin) == LOW ? HIGH : LOW);
    }
    void on() {
      digitalWrite(ledPin, HIGH);
    }
    void off() {
      digitalWrite(ledPin, LOW);
    }
    const char* getRandomQuestion() {
      if (questions == nullptr || questionCount == 0) return nullptr;
      return questions[random(questionCount)];
    }
};

// the questions
const char * QLed0[] = {"led0 Q0", "led0 Q1", "led0 Q2", "led0 Q3", "led0 Q4"};
const char * QLed1[] = {"led1 Q0", "led1 Q1", "led1 Q2", "led1 Q3"};
const char * QLed2[] = {"led2 Q0", "led2 Q1", "led2 Q2"};
const char * QLed3[] = {"led3 Q0", "led3 Q1"};
const char * QLed4[] = {"led4 Q0", "led4 Q1", "led4 Q2", "led4 Q3", "led4 Q4"};

Led leds[] = {
  { 9, QLed0, sizeof QLed0 / sizeof * QLed0 },
  {10, QLed1, sizeof QLed1 / sizeof * QLed1 },
  {11, QLed2, sizeof QLed2 / sizeof * QLed2},
  {12, QLed3, sizeof QLed3 / sizeof * QLed3 },
  {13, QLed4, sizeof QLed4 / sizeof * QLed4 },
};
const size_t ledsCount = sizeof leds / sizeof * leds;
size_t currentLed;


void setup() {
  button.begin(buttonPin);
  for (auto&l : leds) l.begin();

  int result = lcd.begin(LCD_COLS, LCD_ROWS);
  if (result) {
    Serial.print("LCD initialization failed: ");
    Serial.println(result);
    hd44780::fatalError(result);
  }

  randomSeed(analogRead(A0)); // randomize

  lcd.clear();
  lcd.print("PRESS TO START");
}

void loop() {
  switch (state) {
    case PAUSED: // a click on the button starts the led danse
      button.poll();
      if (button.onPress()) {
        lcd.clear();
        lcd.print("Game on!");
        lastTick = millis();
        // turn off all leds
        for (auto&l : leds) l.off();
        // turn on first led
        currentLed = 0;
        leds[currentLed].on();
        state = RUNNING;
      }
      break;

    case RUNNING:
      button.poll();
      if (button.onPress()) {
        // we stop the led danse and ask a question from the current Led
        lcd.clear();
        lcd.print(leds[currentLed].getRandomQuestion());
        state = ASKING;
      } else {
        // check if it's time to go to next led, do that
        if (millis() - lastTick >= tickPeriod) {
          leds[currentLed++].off();
          if (currentLed >= ledsCount) currentLed = 0;
          leds[currentLed].on();
          lastTick = millis();
        }
      }
      break;

    case ASKING:
      // a click on the button starts the led danse again
      button.poll();
      if (button.onPress()) {
        // turn off all leds (this is not necessary unless you messed up the leds in other part of the code, whilst asking the question)
        for (auto&l : leds) l.off();
        // turn on the current led
        leds[currentLed].on();
        lcd.clear();
        lcd.print("Try again!");
        state = RUNNING;
      }
      break;
  }

}

I created a small class for the Leds to embed everything together. The number of questions associated to one Led is made arbitrary. (you just pass an array of questions and number of questions in the array for a given Led).

the game is managed by a very simple state machine. (if you don't know what it is, you might benefit from reading this small introduction to the topic: Yet another Finite State Machine introduction )

don't understand how you expect these multiple button presses to occur?

presumably the button pins are pulled LOW and pressing a button makes it HIGH. the while (button_state == HIGH) condition is true when the Button pin is pressed, but then the other inputs are read immediately afterwards.

do you expect multiple button to be pressed at the same time?

this approach is repeated, so i don't see how this code is expected to work

i also don't see how the buttons are used to provide an answer.

and also don't understand how if the while (White_state == HIGH) condition is true, how the whiel (Yellow_state == HIGH) condition can also be true

you hold the button to keep most recent light on. then it reads the leds and sees which is on and provides question based on it

why not sequence thru each set of questions and wait for a button to be pressed?

I think that would be too complicated

how is a question answered? does a specific button need to be pressed? what if it isn't?

Basically the lights are flashed randomly and when button pressed and held, light stops and pick one of its 5 questions and displays on lcd till button is released. Each led has a diff value of points because of difficulty of question it has. There is only one button. If button isn't pressed lights continue alternating till button is held

is this how you want it to work or how it is partially working now?

how many buttons do you have? i just see one, Button. the other pins (e.g. White) are configured as output

and how are your buttons wired? does pressing the button make it LOW or HIGH?

I want it to work like that, I only have one button, the others are the LEDs, when button pressed it becomes HIGH

look this over

# include <Adafruit_LiquidCrystal.h>

const byte PinBut     =   6;
const byte PinLeds [] = { 10, 11, 12 };

Adafruit_LiquidCrystal lcd (0);

const int  Nlevel = 3;
const char *quest [Nlevel][5] = {
    { "WAR", "WBR", "WCR", "WDR", "WER" },
    { "YAR", "YBR", "YCR", "YDR", "YER" },
    { "GAR", "GBR", "GCR", "GDR", "GER" }
};

int random_question;
int idx;

// -----------------------------------------------------------------------------
void loop ()
{
    digitalWrite (PinLeds [idx], LOW);

    random_question = random (0, 5);
    if (Nlevel <= ++idx)
        idx = 0;

    digitalWrite (PinLeds [idx], HIGH);
    Serial.println (quest [idx][random_question]);

    if (LOW == digitalRead (PinBut))  {
        Serial.println (" ???");
        idx = 0;
    }

    delay (1000);
}

void setup ()
{
    Serial.begin (9600);

    pinMode (PinBut, INPUT_PULLUP);

    for (unsigned i = 0; i < sizeof(PinLeds); i++)
        pinMode (PinLeds [i], OUTPUT);
}

@l4v3r would be better served if the code provided could be fixed.

I used @StefanL38's hardware (THX!) and changed the LCD so it works.

I noticed a few while statements that I thought made more sense as if statements, and changed the pinMode of the button to INPUT_PULLUP.

Now it stumbles along, at least. I cannot spend time time now to untnagle the logic - for one example, did @l4v3r mean for a button press to read HIGH or LOW.

I would make this less ambiguous by using PRESST and NOTPRESST, viz:

# define PRESST     LOW      // HIGH?
# define NOTPRESST  HIGH     // LOW?

Drop it in, fix it. Help @l4v3r/

//#include <Adafruit_LiquidCrystal.h>
//Adafruit_LiquidCrystal lcd(0);

#include <LiquidCrystal_I2C.h>

#define I2C_ADDR    0x27
#define LCD_COLUMNS 20
#define LCD_LINES   4

LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);

int Button = 6;
int button_state;
int White = 11;
int White_state;
const char* wq1 = "what is WAR";
const char* wq2 = "what is WBR";
const char* wq3 = "what is WCR";
const char* wq4 = "what is WDR";
const char* wq5 = "what is WER";
int Yellow = 9;
int Yellow_state;
const char* yq1 = "what is YAR";
const char* yq2 = "what is YBR";
const char* yq3 = "what is YCR";
const char* yq4 = "what is YDR";
const char* yq5 = "what is YER";
int Green = 10;
int Green_state;
const char* gq1 = "what is GAR";
const char* gq2 = "what is GBR";
const char* gq3 = "what is GCR";
const char* gq4 = "what is GDR";
const char* gq5 = "what is GER";
int lights[] = {White, Green, Yellow};
int numLights = sizeof(lights) / sizeof(lights[0]);
long random_question;

void setup() {
  Serial.begin(9600);
  Serial.println("hello");

  pinMode(Button, INPUT_PULLUP);
  lcd.begin(16, 2);
  lcd.clear();
  lcd.print("  Button Press");

  delay(777);

  // Set each pin as an output
    pinMode(White, OUTPUT);
    pinMode(Green, OUTPUT);
    pinMode(Yellow, OUTPUT);
    pinMode(Button, INPUT_PULLUP);
    
  
}

void loop() {
  random_question = random(1, 5);
  // Turn off all lights
  turnOffAllLights();
  lcd.setCursor(0,0);
  lcd.print("COMP SCI GAME");

  // Turn on a random light
  int randomIndex = random(numLights);
  digitalWrite(lights[randomIndex], HIGH);

  delay(1000); // Adjust delay as needed
  button_state = digitalRead(Button);
  White_state = digitalRead(White);
  Yellow_state = digitalRead(Yellow);
  Green_state = digitalRead(Green);
  
  while(button_state == HIGH)
  {
   lcd.clear();
   button_state = digitalRead(Button);
   White_state = digitalRead(White);
   Yellow_state = digitalRead(Yellow);
   Green_state = digitalRead(Green);
    
    if (White_state == HIGH)
    {
     button_state = digitalRead(Button);
      if(button_state == LOW){
        break;}
        while(button_state == HIGH)
        {White_state = digitalRead(White);
        Serial.println(random_question);
          if(random_question == 1){lcd.setCursor(0,0); lcd.print(wq1);}
          if(random_question == 2){lcd.setCursor(0,0); lcd.print(wq2);}
          if(random_question == 3){lcd.setCursor(0,0); lcd.print(wq3);}
          if(random_question == 4){lcd.setCursor(0,0); lcd.print(wq4);}
          if(random_question == 5){lcd.setCursor(0,0); lcd.print(wq5);}
        button_state = digitalRead(Button);
    }
    if (Yellow_state == HIGH)
    {
      button_state = digitalRead(Button);
      if(button_state == LOW){
        break;}
        while(button_state == HIGH)
        {Yellow_state = digitalRead(Yellow);
        Serial.println(random_question);
          if(random_question == 1){lcd.setCursor(0,0); lcd.print(yq1);}
          if(random_question == 2){lcd.setCursor(0,0); lcd.print(yq2);}
          if(random_question == 3){lcd.setCursor(0,0); lcd.print(yq3);}
          if(random_question == 4){lcd.setCursor(0,0); lcd.print(yq4);}
          if(random_question == 5){lcd.setCursor(0,0); lcd.print(yq5);}
        button_state = digitalRead(Button);
    }
    if (Green_state == HIGH)
    {

      button_state = digitalRead(Button);
      if(button_state == LOW){
        break;}
        while(button_state == HIGH)
        {Green_state = digitalRead(Green);
        Serial.println(random_question);
          if(random_question == 1){lcd.setCursor(0,0); lcd.print(gq1);}
          if(random_question == 2){lcd.setCursor(0,0); lcd.print(gq2);}
          if(random_question == 3){lcd.setCursor(0,0); lcd.print(gq3);}
          if(random_question == 4){lcd.setCursor(0,0); lcd.print(gq4);}
          if(random_question == 5){lcd.setCursor(0,0); lcd.print(gq5);}
        button_state = digitalRead(Button);
        }
       }
    }
    }}
  
}

    void turnOffAllLights() {

  // Turn off all lights
  for (int i = 0; i < numLights; i++) {
    digitalWrite(lights[i], LOW);
    lcd.clear();
  }
  }

Is the Chemistry or History/Political Science or what? The only question I can answer is
const char* wq1 = "what is WAR";

War is a waste of everything it lays waste to.

a7

have you checked my code ?

seems you are all set with that

:drooling_face::drooling_face:ur code is so good

thank u

glad if it helped.

Make sure you understand state machines. This is a very common construct for such code.

if you want the score to vary with the selected LED, you can use currentLed as the index of the led that is selected when you ask the question.