Nested switch/case statements not operating as expected

For practice I put together a working game mimicking Milton Bradley’s Simon. My coding experience is minimal, but I wanted to revise my code to make it more elegant as further practice. I’m adding more arrays and loops and I’m replacing some if statements with switch/case statements. In this example, my interior nested switch/case statements work fine, but the exterior ones are causing me problems. I cannot get any case to register outside of case 0. In other words, I never see Serial.println(“gameStatus case 1”); take effect.

For simplicity if limited the cases to 0 and 1 in the example below. Would someone mind helping point out where this is breaking down?

#include "pitches.h"

int buttonSelect = 29;
int buttonStart = 28;
int selectState = 1;
int startState = 0;
int blueLed = 5;
int yellowLed = 4;
int redLed = 3;
int greenLed = 2;
int buttonGreen = 33;
int buttonRed = 32;
int buttonYellow = 31;
int buttonBlue = 30;
int blueState = 0;
int yellowState = 0;
int redState = 0;
int greenState = 0;
int ledStates[4] = {blueState, yellowState, redState, greenState};
int gameStatus = 0;
unsigned long blueTimer = 0;
unsigned long yellowTimer = 0;
unsigned long redTimer = 0;
unsigned long greenTimer = 0;
int timers[4] = {blueTimer, yellowTimer, redTimer, greenTimer};
unsigned long selectTimer = 0;
unsigned long startTimer = 0;
unsigned long debounce = 200;
unsigned long seed = 0;

void setup() {
  // put your setup code here, to run once:
    Serial.begin(9600);
  pinMode(greenLed, OUTPUT);
  pinMode(yellowLed, OUTPUT);
  pinMode(redLed, OUTPUT);
  pinMode(blueLed, OUTPUT);
  pinMode(buttonGreen, INPUT);
  pinMode(buttonRed, INPUT);
  pinMode(buttonYellow, INPUT);
  pinMode(buttonBlue, INPUT);
  pinMode(buttonSelect, INPUT);
  pinMode(buttonStart, INPUT);
  digitalWrite(greenLed, LOW);
  digitalWrite(yellowLed, LOW);
  digitalWrite(redLed, LOW);
  digitalWrite(blueLed, HIGH);
  randomSeed(analogRead(0));
}

void loop() {
  // put your main code here, to run repeatedly:
  switch(gameStatus) {
    case 0:
      int selectPress = digitalRead(buttonSelect);
      int startPress = digitalRead(buttonStart);
      if (selectPress == 0 && millis() - selectTimer > debounce) {
        if (selectState == 4) {
          selectState = 0;
        }
        selectTimer = millis();  
        selectState++;
        switch(selectState) {
          case 1:
          Serial.println("in case 1");
            digitalWrite(greenLed, LOW);
            digitalWrite(blueLed, HIGH);
            tone(12, NOTE_E4, 320);
            delay(320);
            noTone(12);
            break;
          
          case 2:
          Serial.println("in case 2");
            digitalWrite(blueLed, LOW);
            digitalWrite(yellowLed, HIGH);
            tone(12, NOTE_CS4, 320);
            delay(320);
            noTone(12);
            break;

          case 3:
          Serial.println("in case 3");
            digitalWrite(yellowLed, LOW);
            digitalWrite(redLed, HIGH);
            tone(12, NOTE_A3, 320);
            delay(320);
            noTone(12);
            break;

          case 4:
          Serial.println("in case 4");
            digitalWrite(redLed, LOW);
            digitalWrite(greenLed, HIGH);
            tone(12, NOTE_E3, 320);
            delay(320);
            noTone(12);
            break;

          default:
          Serial.println("error");  
        }
      }
      if (startPress == 0 && startState == 0 && millis() - startTimer > debounce) {
        seed = millis();
        tone(12, NOTE_E5, 650);
        delay(650);
        Serial.println("Game should be starting");
        gameStatus = 1;
        Serial.print("gameStatus = ");
        Serial.println(gameStatus);
      }
      break;

    case 1:
      Serial.println("gameStatus case 1");
      break;
  }
}

There’s an associated file called pitches.h with the following info.

#define NOTE_B0  31
#define NOTE_C1  33
#define NOTE_CS1 35
#define NOTE_D1  37
#define NOTE_DS1 39
#define NOTE_E1  41
#define NOTE_F1  44
#define NOTE_FS1 46
#define NOTE_G1  49
#define NOTE_GS1 52
#define NOTE_A1  55
#define NOTE_AS1 58
#define NOTE_B1  62
#define NOTE_C2  65
#define NOTE_CS2 69
#define NOTE_D2  73
#define NOTE_DS2 78
#define NOTE_E2  82
#define NOTE_F2  87
#define NOTE_FS2 93
#define NOTE_G2  98
#define NOTE_GS2 104
#define NOTE_A2  110
#define NOTE_AS2 117
#define NOTE_B2  123
#define NOTE_C3  131
#define NOTE_CS3 139
#define NOTE_D3  147
#define NOTE_DS3 156
#define NOTE_E3  165
#define NOTE_F3  175
#define NOTE_FS3 185
#define NOTE_G3  196
#define NOTE_GS3 208
#define NOTE_A3  220
#define NOTE_AS3 233
#define NOTE_B3  247
#define NOTE_C4  262
#define NOTE_CS4 277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4 370
#define NOTE_G4  392
#define NOTE_GS4 415
#define NOTE_A4  440
#define NOTE_AS4 466
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_CS5 554
#define NOTE_D5  587
#define NOTE_DS5 622
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_FS5 740
#define NOTE_G5  784
#define NOTE_GS5 831
#define NOTE_A5  880
#define NOTE_AS5 932
#define NOTE_B5  988
#define NOTE_C6  1047
#define NOTE_CS6 1109
#define NOTE_D6  1175
#define NOTE_DS6 1245
#define NOTE_E6  1319
#define NOTE_F6  1397
#define NOTE_FS6 1480
#define NOTE_G6  1568
#define NOTE_GS6 1661
#define NOTE_A6  1760
#define NOTE_AS6 1865
#define NOTE_B6  1976
#define NOTE_C7  2093
#define NOTE_CS7 2217
#define NOTE_D7  2349
#define NOTE_DS7 2489
#define NOTE_E7  2637
#define NOTE_F7  2794
#define NOTE_FS7 2960
#define NOTE_G7  3136
#define NOTE_GS7 3322
#define NOTE_A7  3520
#define NOTE_AS7 3729
#define NOTE_B7  3951
#define NOTE_C8  4186
#define NOTE_CS8 4435
#define NOTE_D8  4699
#define NOTE_DS8 4978

Try:

case 0: { int selectPress = digitalRead(buttonSelect) ; int star . . . . . . }

etc. Also switch on the compiler warnings in preferences.

Thanks! That seems to have worked. Is there a rule of thumb as to when to include brackets and when not to? The examples I saw didn't have those.

The difference is that in case 0 you defining variables in the expectation that these are local to case 0, however a case statement does not create a block so you need the brackets. Your case 1 , for example, has no variable definitions so does not need extra brackets.