How do I structure a logic to store the pin number in an array?

0

I'm developing a memory game. The code is written in .C and will run on an arduino. Within the code, randomized numbers from 8 to 14 must be generated. The number of rounds will determine the number needed to randomize the number. For example, in round 1: randomize 1 number and store it in the variable correct_order[] = {number_random_1}. round 2: randomize 2 numbers and store them in the variable correct_order[] = {number_random_1, number_random_2}. Between the intervals, wait for the user to press one of the buttons and store it in the variable selected_order[] = [number_pin]. The number of times the user has to press will also depend on the number of which round they are in. If the values in a loop, selected_order[index] == correct_order[index], are true, it should go to the next round. Otherwise, the program should warn that the game is over, perhaps in a Serial.println("message").

I managed to do the randomization process by rounds, however, I can't do the checks on the two variables (array), correct_order and selected_order.

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd_1(32,16,2);

const int ledPins[] = {13, 12, 11, 10, 9, 8};
const int buttonsPins[] = {2, 3, 4, 5, 6, 7};
const int numLeds = 6;

void setup() {
    lcd_1.init();
    lcd_1.setCursor(0,0);
    lcd_1.backlight();
    lcd_1.display();
    Serial.begin(9600);
    for (int i = 0; i < numLeds; i++) {
        pinMode(ledPins[i], OUTPUT);
        pinMode(buttonsPins[i], INPUT); // Enables the internal pull-up resistor on the button pins
    }
}
int correct_order[6];
int selected_order[6];
bool button_pressed_0 = false; // Variable to track whether button 1 has been pressed
bool button_pressed_1 = false; // Variable to track whether button 2 has been pressed
bool button_pressed_2 = false;
bool button_pressed_3 = false;
bool button_pressed_4 = false;
bool button_pressed_5 = false;

void reset(bool* button[], int quantity) {
  // sets the initial conditions only for the specified buttons
  for (int i = 0; i < quantity; i++) {
    *(button[i]) = false;
  }
}

int rounds = 1;
void loop() {
    Serial.print("\n START GAME \n");
    for(int i = 0; i<rounds;i++){
        correct_order[i] = random(8, 14);
        lcd_1.setCursor(0, 0);
        lcd_1.print("rounds: ");
        lcd_1.setCursor(0, 1);
        lcd_1.print(rounds);
        delay(1000);
        lcd_1.clear();
        Serial.print("\n variable rounds: ");
        Serial.print(rounds);
        for (int led = 0; led < rounds; led++) {
            Serial.print("\n variable led (indice): ");
            Serial.print(led);
            Serial.print("\n pin: ");
            Serial.print(correct_order[led]);
            digitalWrite(correct_order[led],HIGH);
            delay(1000);
            digitalWrite(correct_order[led],LOW);
            delay(1000);
          }
        int x = 0;
        // do(rounds++;)while{x<rounds};
        
        
      
    }
    Serial.println("\n ------- THE GAME IS OVER -----------");
  // correct_order - selected_order 
  // pin (led)     - pin (button)   +  cts(normalizacao)
  // 13            - 2              +  11     = 13
  // 12            - 3              +   9     = 12
  // 11            - 4              +   7     = 11
  // 10            - 5              +   5     = 10
  //  9            - 6              +   3     =  9
  //  8            - 7              +   2     =  8
  rounds = 1;
  bool* button[] = {&button_pressed_0, &button_pressed_1, &button_pressed_2, &button_pressed_3, &button_pressed_4, &button_pressed_5};
  reset(button, 6); // This will reset only the first 6 buttons
}

In the comment // do(rounds++;)while{x<rounds}; , I tried to do a Do While to wait for the user to press the buttons and store the pin number + constant (to be equal to the pin number in the correct order), but it's giving me a problem, because it has 5 if(){} conditions, and it's like a check for each round, i.e. in round 3, it only stores one value.

do {
    if(digitalRead(buttonsPins[0]) == HIGH && !button_pressed_0) {
      Serial.println("\n pressed");
      Serial.print("index: ");
      Serial.print(x);
      Serial.print("\n Pin: ");
      Serial.print(buttonsPins[0]);
      selected_order[x] = buttonsPins[0] + 11;
      button_pressed_0= true;
      x++;
    } 
    if(digitalRead(botoesPinos[1]) == HIGH && !button_pressed_1) {
      Serial.println("\n pressed");
      Serial.print("index: ");
      Serial.print(x);
      Serial.print("\n Pin: ");
      Serial.print(buttonsPins[1]);
      selected_order[x] = buttonsPins[1] + 9;
      button_pressed_1= true;
      x++;
    } 
    if(digitalRead(botoesPinos[2]) == HIGH && !button_pressed_2) {
      Serial.println("\n pressed");
      Serial.print("index: ");
      Serial.print(x);
      Serial.print("\n Pin: ");
      Serial.print(buttonsPins[2]);
      selected_order[x] = buttonsPins[2] + 7;
      button_pressed_2= true;
      x++;
    } 
    if(digitalRead(botoesPinos[3]) == HIGH && !button_pressed_3) {
      Serial.println("\n pressed");
      Serial.print("index: ");
      Serial.print(x);
      Serial.print("\n Pin: ");
      Serial.print(buttonsPins[3]);
      selected_order[x] = buttonsPins[3] + 5;
      button_pressed_3= true;
      x++;
    } 
    if(digitalRead(buttonsPins[4]) == HIGH && !button_pressed_4) {
      Serial.println("\n pressed");
      Serial.print("index: ");
      Serial.print(x);
      Serial.print("\n Pin: ");
      Serial.print(buttonsPins[4]);
      selected_order[x] = buttonsPins[4] + 3;
      button_pressed_4= true;
      x++;
    }  
    if(digitalRead(buttonsPins[5]) == HIGH && !button_pressed_5) {
      Serial.println("\n pressed");
      Serial.print("index: ");
      Serial.print(x);
      Serial.print("\n Pin: ");
      Serial.print(buttonsPins[5]);
      selected_order[x] = buttonsPins[5] + 1;
      button_pressed_5= true;
      x++;
    }  
    
  } while (x < rounds);

OUTPUT

START GAME 

 variavel rodadas: 1
 variavel led (index): 0
 pine: 9
 pressionado
index: 0
 pine: 6
 variavel rodadas: 2
 variavel led (index): 0
 pine: 9
 variavel led (index): 1
 pine: 9
 variavel rodadas: 3
 variavel led (index): 0
 pine: 9
 variavel led (index): 1
 pine: 9

link to tinkcard: Login | Tinkercad

is this some kind of Simon game?

You are adding a level of complexity by using the actual pin numbers. Instead, use the index of the pin array, that way 0 can refer to the first LED and the first button, 1 refers to the 2nd LED and the corresponding 2nd button, etc.

I'm unable to see anything but this block

    if(digitalRead(botoesPinos[2]) == HIGH && !button_pressed_2) {
      Serial.println("\n pressed");
      Serial.print("index: ");
      Serial.print(x);
      Serial.print("\n Pin: ");
      Serial.print(buttonsPins[2]);
      selected_order[x] = buttonsPins[2] + 7;
      button_pressed_2= true;
      x++;
    } 

besides botoes, it looks like the same code has been copy/paste/edited to accomplish what might better be a function with parameters.

Also, typical Arduino code lets the loop() do all the looping.

You might look at the IPO model for process control, and consider using a state machine approach to managing rounds and such.

I'm in transit, I'll try to show you what I mean L8R if others haven't already.

+1 on making even what you have more abstract- separate logic from hardware details.

a7

tl;dr: This is a request a drawing or description of the device, LEDs and buzzers and stuff, the rules and how game play ensues. Like one might pull out of the box the device comes in.


Ok, it looks like each round makes a new set of random choices, presents them to the player and then will wait for the player to enter the same number of choices, after which the round is evaluated for correctness.

In this way it differs from Simon, where each round grows the sequence, and progress depends on repeating the already seen and one hopes learned part, then the player has to add the next element.

What this means to me:

I'm developing a memory game.

is that I can't even remember what's on the clipboard. Let me try again. What this means to me:

    for(int i = 0; i<rounds;i++){
        correct_order[i] = random(8, 14);

is that each sequence of length N can have elements from 8..13, with no code to avoid repeated elements, which makes me ask about the flags and logic which suppress a button if it has been used.

Is getting it wrong in, say, round three mean you repeat round three, or go back a level or just lose?

I assume winning is getting it right 6 times in a row for sequences of length 1, 2, 3 and so forth.

Do you mean to have a new sequence of the length dictated by the round each round?

Are you thinking (button pressed flags and stuff) of having a shuffle of the elements rather than each element being allowed to take on possibly already chosen values?

And while I'm thinking about it, even if the puzzle had no repeats, why help the player by making the buttons incapable of repeating? It would just be another mistake of memory, seems fair to me to allow the player to make dumb moves.

Did you consider any kind of instant losing as some puzzles have, where the first wrong move is the end of the player input phase, Bzzzt?

I'd suggest you use one of the numerous button library such as Button in easyRun or OneButton or Toggle or EasyButton or Bounce2, ... to handle your button presses and build a state machine as the code structure (here is a small introduction to the topic: Yet another Finite State Machine introduction)

can you confirm each round drives a whole new set of leds or do you want to keep the same n-1 leds and just add a new one ?

look this over

const byte LedPins    [] = { 13, 12, 11, 10, 9, 8}; // Capitalize constants
const byte ButtonPins [] = {  2,  3,  4,  5, 6, 7};

const int Nled = sizeof(LedPins);

byte butState [Nled];

const int MaxLevel = 20;
byte sequence [MaxLevel];
int  seqIdx;
int  butIdx;

enum { Off = HIGH, On = LOW };

int level;

// -----------------------------------------------------------------------------
const int NoBut = -1;
int
chkButtons ()
{
    for (unsigned n = 0; n < Nled; n++)  {
        byte but = digitalRead (ButtonPins [n]);

        if (butState [n] != but)  {
            butState [n] = but;

            delay (10);     // debounce

            if (On == but)
                return n;
        }
    }
    return NoBut;
}

// -----------------------------------------------------------------------------
void flashLeds ()
{
    Serial.println (" flashLeds");
    for (int i = 0; i < level; i++)  {
        int pin = sequence [i];
        digitalWrite (LedPins [pin], On);
        delay (500);
        digitalWrite (LedPins [pin], Off);
        delay (500);
    }
}

// -------------------------------------
void nextLevel ()
{
    sequence [level] = random (0, Nled);
    level ++;
    seqIdx = 0;

    Serial.print   ("next level ");
    Serial.println (level);

    delay (1000);
    flashLeds ();
}

// -------------------------------------
void reset ()
{
    Serial.println ("reset");
    butIdx = 0;
    seqIdx = 0;
    level  = 0;
    nextLevel ();
}

// -------------------------------------
void loop ()
{
    int but = chkButtons ();
    if (NoBut == but)
        return;

    Serial.println (but);
    if (sequence [seqIdx++] != but)  {
        Serial.println (" wrong");
        reset ();
    }
    else
        Serial.println (" match");

    if (level == seqIdx)  {
        Serial.println (" win - next level");
        nextLevel ();
    }
}

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

    for (int i = 0; i < Nled; i++) {
        pinMode      (LedPins[i], OUTPUT);
        digitalWrite (LedPins[i], Off);

        pinMode (ButtonPins[i], INPUT_PULLUP);
        butState [i] = digitalRead (ButtonPins[i]);
    }

    reset ();
}

Hi guys, sorry I've been away. I've been working on this project. I've managed to formulate my proposal.

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd_1(32,16,2);

const int ledPins[] = {13, 12, 11, 10, 9, 8};
const int button_order[] = {2, 3, 4, 5, 6, 7};
const int numLeds = 6;

void setup() {
    lcd_1.init();
    lcd_1.setCursor(0,0);
    lcd_1.backlight();
    lcd_1.display();
    Serial.begin(9600);
    for (int i = 0; i < numLeds; i++) {
        pinMode(ledPins[i], OUTPUT);
        pinMode(button_order[i], INPUT); // Enables the internal pull-up resistor on the button pins
    }
}


bool button_pressed_one = false; // Variable to track whether button 2 has been pressed
bool button_pressed_two = false;
bool button_pressed_three = false;
bool button_pressed_four = false;
bool button_pressed_five = false;
bool button_pressed_six = false;
bool button_pressed[6];
void reset(bool* button[], int quantity) {
  // sets the initial conditions only for the specified buttons
  for (int i = 0; i < quantity; i++) {
    *(button[i]) = false;
  }
}
void on_led(int pin){
    digitalWrite(pin, HIGH);
    delay(1000);
    digitalWrite(pin, LOW);
    delay(200);
}

bool state = true;
int rounds = 1;
void loop() {
  	 lcd_1.setCursor(0, 0);
  	 lcd_1.print("START GAME");
     delay(1000);
     lcd_1.clear();
    for(int i = 0; i<rounds;i++){
        int correct_order[rounds];
      	int selected_order[rounds];
        correct_order[i] = random(8, 14);
        lcd_1.setCursor(0, 0);
        lcd_1.print("ROUNDS: " +String(rounds));
        lcd_1.setCursor(0, 1);
        delay(1000);
        lcd_1.clear();
        for (int led = 0; led < rounds; led++) {
            Serial.print(correct_order[led]);
            digitalWrite(correct_order[led],HIGH);
            delay(1000);
            digitalWrite(correct_order[led],LOW);
            delay(1000);
          }
        int x = 0;
      	lcd_1.setCursor(0, 0);
        lcd_1.print("TRY TO REMEMBER");
        delay(1000);
      	lcd_1.clear();
      	do{
          delay(150);
          if(digitalRead(button_order[0]) == HIGH && !button_pressed_one){
            selected_order[x] = 13;
              if(selected_order[x] == correct_order[x]){
                on_led(selected_order[x]);
                bool* button[] = {&button_pressed_one};
  				reset(button, 1);
                x++;
              }
              else{
                  state = false; // to do The game over
                  break;
        	    }
          }
          if(digitalRead(button_order[1]) == HIGH && !button_pressed_two){
            selected_order[x] = 12;
            if(selected_order[x] == correct_order[x]){
                on_led(selected_order[x]);
                bool* button[] = {&button_pressed_two};
  				      reset(button, 1);
                x++;
            }else{
                state = false; // to do The game over
                break;
            }
          }
          if(digitalRead(button_order[2]) == HIGH && !button_pressed_three){
            selected_order[x] = 11;
            if(selected_order[x] == correct_order[x]){
                on_led(selected_order[x]);
                bool* button[] = {&button_pressed_three};
                reset(button, 1);
                x++;
            }else{
              state = false; // to do The game over
              break;
            }
          }
          if(digitalRead(button_order[3]) == HIGH && !button_pressed_four){
            selected_order[x] = 10;
            if(selected_order[x] == correct_order[x]){
                on_led(selected_order[x]);
              bool* button[] = {&button_pressed_four};
  			      reset(button, 1);
              x++;
            }else{
              state = false; // to do The game over
              break;
            }
          }
          if(digitalRead(button_order[4]) == HIGH && !button_pressed_five){
            selected_order[x] = 9;
            if(selected_order[x] == correct_order[x]){
              digitalWrite(selected_order[x], HIGH);
                on_led(selected_order[x]);
              bool* button[] = {&button_pressed_five};
              reset(button, 1);
              x++;
            }else{
              state = false; // to do The game over
              break;
            }
          }
          if(digitalRead(button_order[5]) == HIGH && !button_pressed_six){
            selected_order[x] = 8;
            if(selected_order[x] == correct_order[x]){
              on_led(selected_order[x]);
              bool* button[] = {&button_pressed_six};
  			  reset(button, 1);
              x++;
            }else{
              state = false; // to do The game over
              break;
            }
          }
        }while(x<rounds);
        if(state == true){
          	lcd_1.setCursor(0, 0);
            lcd_1.print("YOU SELECTED: "+(String)selected_order[x]);
            delay(1400);
            lcd_1.setCursor(0, 1);
            lcd_1.print("BUT IT WAS: " + String(correct_order[x]));
            delay(1400);
            lcd_1.clear();
            lcd_1.setCursor(0, 0);
            lcd_1.print("CONGRATULATIONS!");
            delay(1000);
            lcd_1.clear();
          	rounds++;

        }else{
            lcd_1.setCursor(0, 0);
            lcd_1.print("YOU LOSS :<");
          	lcd_1.setCursor(0, 1);
            lcd_1.print("YOU SELECTED: "+(String)selected_order[x]);
            delay(2000);
          	lcd_1.clear();
        	lcd_1.setCursor(0, 0);
          	lcd_1.print("BUT IT WAS: " + String(correct_order[x]));
          	delay(2000);
         	lcd_1.clear();
            rounds = 1;
            // to do any treading for this situation
        }
    }
    Serial.println("\n ------- THE GAME IS OVER -----------");
  bool* button[] = {&button_pressed_one, &button_pressed_two, &button_pressed_three, &button_pressed_four, &button_pressed_five, &button_pressed_six};
  reset(button, 6); // This will reset only the first 6 buttons
}

How could I simplify the question of ifs structures and use bits to store perhaps some variables?

i think you're asking about "how" to do things without make clear "what" you want to do.