1st Arduino Project: A Simulated Baseball Batter's Running Time

The code below will...

start at 4.3 seconds, countdown to zero, wait 3 seconds, reset and wait for new input (sound detection).

.... except I don't have a sound detector so I used a button, and I don't have a display so that would need to be added:

//  https://forum.arduino.cc/index.php?topic=631679
//  16 august 2019 meltDown

// OP asked for "start at 4.3 seconds, countdown to zero, wait 3 seconds,
//     reset and wait for new input (sound detection)."

//meltDown has no sound detector, so just using a button
//also display stuff needs to be added

//has a proofOfLife pulse on 13 to prove there's no blocking

enum {ST_WAITING, ST_COUNTING_DOWN, ST_RESETTING} currentState = ST_WAITING;
// enum just allocates integers from the left so ST_WAITING=0, ST_ST_COUNTING_DOWN =1
//    just makes it easier to have human relatable names in the switch..case later

unsigned long previousPulseMillis;
int pulseInterval = 500;
bool pulseLedState = LOW;
byte pulseLedPin = 13;

byte soundDetector = 12; //actually just a button
int countdownPeriod = 4300;
int resetPeriod = 3000;
unsigned long weStartedTimingAt;
unsigned long weStartedResetAt;
bool messageDisplayedOnce = false;

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(soundDetector, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println("Forum thread 631679");
  Serial.println("Setup done...");
}//setup

void loop()
{
  proofOfLife();
  doStates();
}//loop

void proofOfLife()
{
  if (millis() - previousPulseMillis >= pulseInterval)
  {
    pulseLedState = !pulseLedState;
    digitalWrite(pulseLedPin, pulseLedState);
    previousPulseMillis = millis();;
  }
}

void doStates()
{
  switch (currentState)
  {
    case ST_WAITING:

      if (!messageDisplayedOnce)
      {
        Serial.println("\nWaiting for hit... (actually a button press)");
        messageDisplayedOnce = true;
      }
      if (!digitalRead(soundDetector))  //ie, button is pressed
      {
        weStartedTimingAt = millis();
        messageDisplayedOnce = false;
        currentState = ST_COUNTING_DOWN;
      }

      break;

    case ST_COUNTING_DOWN:

      if (!messageDisplayedOnce)
      {
        Serial.print("Counting down from ");
        Serial.print(countdownPeriod);
        Serial.println(" (add display stuff)");
        messageDisplayedOnce = true;
      }

      if (millis() - weStartedTimingAt >= countdownPeriod)
      {
        weStartedResetAt = millis();
        messageDisplayedOnce = false;
        currentState = ST_RESETTING;
      }
      break;

    case ST_RESETTING:

      if (!messageDisplayedOnce)
      {
        Serial.print("Waiting for ");
        Serial.print(resetPeriod);
        Serial.println(" (add display stuff)");
        messageDisplayedOnce = true;
      }
      if (millis() - weStartedResetAt >= resetPeriod)
      {
        messageDisplayedOnce = false;
        currentState = ST_WAITING;
      }
      break;

  }//switch
}//doStates

In my mind, it should be pretty simple

It is....

But I already know that's not how code works!

It's exactly how code works (or it's how a programmer makes it work, anyway)