help me understand where i went wrong in my program (this is whakamole)

I am trying to make whakamole using a arduino uno.
Im getting misses when code that calls the function that handles the mole timers is commended out.
im getting hits on moles that are that are not poped up.

example of a hits and miss in the Serial monitor
New Game
New Game
moles
4
the new moles
4 val at index 0
6 val at index 1
2 val at index 2
7 val at index 3
0 val at index 4
0 val at index 5
the new popTime
1912 val at index 0
1171 val at index 1
1447 val at index 2
1880 val at index 3
0 val at index 4
0 val at index 5
THE PINS
pin 4 is a 1
pin 6 is a 1
pin 2 is a 1
pin 7 is a 1
start Wave
Scoreboard P 0 M 0 MN 4
THE PINS
pin 4 is a 1
pin 6 is a 1
pin 2 is a 1
pin 7 is a 1
Hit mole 2 AT PIN 2 input 8 went high
Scoreboard P 1 M 0 MN 3
2 IS LOW??? WTF
Hit mole 4 AT PIN 0 input 6 went high
Scoreboard P 2 M 0 MN 2
0 IS LOW??? WTF
Hit mole 5 AT PIN 0 input 6 went high
Scoreboard P 3 M 0 MN 1
0 IS LOW??? WTF
missed mole 4 AT PIN 0
Scoreboard P 3 M 1 MN 0
0 IS LOW
missed mole 5 AT PIN 0
Scoreboard P 3 M 2 MN -1
0 IS LOW
End Wave P 3 M 2 MN -1
new Wave

the first hit was suppose to happen the rest not so much:(

//use to run a function ever interval amount of time when a mole wave has started
unsigned long previousMillis = 0;
const long interval = 10;

//will be used to start a game or to quit
boolean on_off = false;


int moleNumber, minMoles, level = 0, points = 0, missed = 0, startButton = 14;


//holds all the Moles in a wave
int moles[6];

//holds all the moles Timers 
//moles[1] well stay poped up untell popTime[1] is = 0
int popTime[6];





//loop tho a array and looks for val in the elements of that array
//aSize just tells the function the how many many elements it sould check satrting form index 0
//---------------------------------------------------------------------------------------------
bool contains(int val, int *arr, int aSize) {

  for ( int i = 0; i < aSize; i++) {
    if (arr[i] == val)
      return true;
  }
  return false;
}
//---------------------------------------------------------------------------------------------


//print a array and tells you what the values at all indexs are
//s is just a string to print be for a array
//-------------------------------------------------------------
void loopPrint(int arr[], String s) {
  Serial.println(s);
  for (int i = 0; i < 6; i++) {
    Serial.print(arr[i]);
    Serial.print(" val at index ");
    Serial.println(i);
  }
}

//sets all the values in a array to 0
void clearArray(int arr[]) {
  for (int i = 0; i < 6; i++) {
    arr[i] = 0;
  }
}
//-------------------------------------------------------------


//useds to take the moles[] and set the pins at the value in the index to ether a high or low
//in other word makes the molse pop up or down
//--------------------------------------------------- 
void PopupPopdown(uint8_t HL) {
  Serial.println("THE PINS");
  for (int i = 0; i < 6; i++) {
    if(moles[i] != 0){
    Serial.print("pin " );
    Serial.print(moles[i]);
    Serial.print(" is a ");
    Serial.println(HL);
    digitalWrite(moles[i], HL);
    delay(100);
    }
  }
}
//---------------------------------------------------


//decrement the moles timer values in the popTime array
//which gets used to determine if a mole sould pop down
//-----------------------------------------------------
void moleTimers(unsigned long currentMillis) {

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
   // Serial.println("TimePopDown RAN");

    for (int i = 0; i < 6; i++) {

      if (popTime[i] != 0 ) {
        popTime[i] = popTime[i] - 1;
         //Serial.print(i);
          //Serial.print(" ");

      }
      else {
        //Serial.print(popTime[i]);
      };
      // Serial.println("");

    };
    // Serial.println("TimePopDown RAN");
  }
}
//-----------------------------------------------------


//starts to take inputs from the user
//moleTimers start to tick down
//and other things
//-----------------------------------------------------
void startWave() {
  Serial.println("start Wave");
  Serial.print("Scoreboard P ");
  Serial.print(points);
  Serial.print(" M ");
  Serial.print(missed);
  Serial.print(" MN ");
  Serial.println(moleNumber);
  PopupPopdown(HIGH);




  while (points < 40 && missed < 3 && moleNumber >= 1) {
    /* for (int i = 0; i < 6; i++) {
       int tooManyB;
       if (digitalRead(i + 7) == HIGH) {
         tooManyB++;
       };
       if (tooManyB = 2) {
         missed = 3;
         Serial.println("Stop Cheating");
       };
       }*/

    
    //determine if you hit a mole that is up
    //---------------------------------------------------------------------------------------
    for (int i = 0; i < 6;) {
      if (digitalRead(moles[i] + 6) == HIGH && digitalRead(moles[i]) == HIGH) {
        digitalWrite(moles[i], LOW);
        moleNumber--;
        points++;
        Serial.print("Hit mole ");
        Serial.print(i);
        Serial.print(" AT PIN ");
        Serial.print(moles[i]);
        Serial.print(" input ");
        Serial.print(moles[i] + 6);
        Serial.println(" went high ");
        Serial.print("Scoreboard");
        Serial.print(" P ");
        Serial.print(points);
        Serial.print(" M ");
        Serial.print(missed);
        Serial.print(" MN ");
        Serial.println(moleNumber);
        Serial.print(moles[i]);
        Serial.println(" IS LOW??? WTF");
      };
      i++;
    }

   //---------------------------------------------------------------------------------------


   /* unsigned long currentMillis = millis();
    moleTimers(currentMillis);*/



   // determine if you did not hit a mole be for its timer ran down
   //or in other words if you missed
   //---------------------------------------------------------------------
    for (int i = 0; i < 6;) {
      if (digitalRead(moles[i]) == HIGH && popTime[i] == 0) {
        missed++;
        moleNumber--;
        Serial.print("missed mole ");
        Serial.print(i);
        Serial.print(" AT PIN ");
        Serial.println(moles[i]);
        Serial.print("Scoreboard");
        Serial.print(" P ");
        Serial.print(points);
        Serial.print(" M ");
        Serial.print(missed);
        Serial.print(" MN ");
        Serial.println(moleNumber);
        digitalWrite(moles[i], LOW);
        Serial.print(moles[i]);
        Serial.println(" IS LOW ");

      } 
      i++;
      
    }
   //---------------------------------------------------------------------


  }

  Serial.print("End Wave P ");
  Serial.print(points);
  Serial.print(" M ");
  Serial.print(missed);
  Serial.print(" MN ");
  Serial.println(moleNumber);
};
//-----------------------------------------------------



void setup() {
  Serial.begin (9600);
  randomSeed(analogRead(1));
  
  pinMode(2, OUTPUT);
  pinMode(8, INPUT);

  pinMode(3, OUTPUT);
  pinMode(9, INPUT);

  pinMode(4, OUTPUT);
  pinMode(10, INPUT);

  pinMode(5, OUTPUT);
  pinMode(11, INPUT);

  pinMode(6, OUTPUT);
  pinMode(12, INPUT);

  pinMode(7, OUTPUT);
  pinMode(13, INPUT);

}

void loop() {

  if (digitalRead(startButton) == HIGH) {
    on_off = !on_off;
  };

  Serial.println("New Game");
  if (on_off == false) {

    level = points / 10;

    if (level > 1) {
      minMoles = 2;
    }
    else {
      minMoles = 1;
    };
    clearArray(moles);
    clearArray(popTime);
    moleNumber = random(minMoles, 7);
    Serial.println("moles");
    Serial.println(moleNumber);
    delay(1000);

    
    //makes the moles[] and the popTime[]
    for (int i = 0; i < moleNumber;) {
      int num;

      do
      {
        num = random(2, 8);
      } while (contains(num, moles, moleNumber));

      moles[i] = num;

      switch (level) {

        case 2 :
          popTime[i ] = random(800, 1500);
          break;

        case 3  :
          popTime[i ] = random(450, 850);
          break;

        default :
          popTime[i ] = random(1000, 2000);
      }
      i++;
    };
    loopPrint(moles, "the new moles[]");
    loopPrint(popTime, "the new popTime[]");


    //debug
    PopupPopdown(HIGH);
    //debug

    
    startWave();
    Serial.println("new Wave");

    //debug
    delay(20000);
    PopupPopdown(LOW);
    //debug


    //debug
    // delay(20000);
    missed = 0;
     if (points == 40) {
       points = 0;
      };



  };

}

The Circuit

//holds all the Moles in a wave
int moles[6];

That name makes no sense. It is difficult to tell from your code what values will be stored in this array, so it is difficult to suggest a better name, or to see if int is the appropriate type.

  for (int i = 0; i < 6; i++) {
Do you REALLY need an int to count to 6?

    for (int i = 0; i < 6;) {
      if (digitalRead(moles[i]) == HIGH && popTime[i] == 0) {

      }
      i++;
     
    }

The only justification for putting the { on the line with the statement is to save real estate. That argument goes flat in a hurry when

you have

all those blank

lines in your code.

Why is the loop index increment no in the for statement’s parentheses?

Did I miss the switches in the fritzing half-a-schematic?

PaulS wrote (in part):

Did I miss the switches in the fritzing half-a-schematic?

I could be wrong but I think that the substitutes for the switches are the gray wires that connect from Arduino I/O pins to a ground bus, except that one Arduino I/O pin is connected by a gray wire to 5 volts. Fritzing diagrams are cute but can be hard to follow.

I guess that I missed the explanation of this in the original posting by Strings.

I was struggling to discover where you were running into a problem. but I liked the idea and thought it would be great practice to code a wack a mole sketch. I don’t usually completely wright code from scratch but your idea seemed to be fun and enjoyable
so some thoughts as to what could have caused you code to give you problems you don’t have pull up resistors to ensure your switches are either high or low just opening a switch doesn’t grantee success state switch capacitive charge could hold the input high or low. as for the rest it was difficult to tell but I have a gift If you like it please enjoy if not no harm her I enjoyed making it for you

also note that I didn’t use a single delay() statement

#define MoleCount 6
int startButton = 14;
int moles[MoleCount] = {2, 3, 4, 5, 6, 7} ; // Pins attached to moles for popping them up Can be any pin digital or analog
int moleSense[MoleCount] = {8, 9, 10, 11, 12, 13}; // The Pins to sense for changes Can be any pin digital or analog
long  Hit[MoleCount];
long  Miss[MoleCount];
long  DisplayTime = 1000; // How long to display a hit
long  Cooldown = 1000; // Wait 1 second after mole is hit or missed before re-enabling it to be used again
long  popTime[MoleCount];
int points = 0;
int missed = 0;
int ActiveMoles = 0;
int level = 1;
int LevelMinTimes[] = {1000, 800, 450};
int LevelMaxTimes[] = {2000, 1500, 850};
int CountMinMiliseconds = 10;
int CountMaxMiliseconds = 1000;
int GameRun = 0;
void setup() {
  Serial.begin(115200);
  for (int i = 0; i < MoleCount; i++) {
    pinMode(moles[i], OUTPUT);
    pinMode(moleSense[i], INPUT_PULLUP);
    Hit[i] = 0;
    Miss[i] = 0;
  }
  pinMode(startButton, INPUT_PULLUP);
}

void loop() {
  GameControl();
  PrintSerial(); // for Debugging
  Moles();
  Scoring();
  CheckEnd();
}

void GameControl() {
  if (GameRun)return;
  Serial.println("Welcome to Game");
  Serial.println("Press Button to Begin");
  points = 0;
  missed = 0;
  ActiveMoles = 0;
  for (int i = 0; i < MoleCount; i++) {
    digitalWrite(moles[i], LOW);
    popTime[i] = 0;
    Miss[i] = 0;
    Hit[i] = 0;
  }
  while (!GameRun) {
    if (digitalRead(startButton) == LOW)GameRun = 1;
  }
}
void CheckEnd() {
  if (missed >= 10) {
    GameRun = 0;
    Serial.println("Game Over");
    Serial.print("  Score: ");
    Serial.println(points);
    Serial.print("  Misses: ");
    Serial.println(missed);
  }
}

void Scoring() {
  for (int i = 0; i < MoleCount; i++) {
    if ((digitalRead(moles[i]) == HIGH) && (digitalRead (moleSense[i]) == LOW) ) {
      digitalWrite(moles[i], LOW);
      Hit[i] = DisplayTime;
      popTime[i] = 0;
      points++;
      ActiveMoles--;
    }
  }

}
void Moles() {
  ActiveMoles = constrain(ActiveMoles,0,MoleCount);
  static unsigned long PopTimer;
  int PDelay = map(ActiveMoles, 0, MoleCount, CountMinMiliseconds, CountMaxMiliseconds); // makes it less likely to have a mole pop up if other moles are already up
  if ( millis() - PopTimer >= (PDelay)) {
    PopTimer += (PDelay);
    int num = random(0, MoleCount);
    if (digitalRead(moles[num]) == LOW and digitalRead(moleSense[num]) == HIGH ) { // Lets only pop a mole up if both the mole is already down and nothing is triggering the sensor

      if (popTime[num] <= -Cooldown) { // Cooldown prevents the mole from having a chance of popping back up for severl miliseconds
        popTime[num] = random(LevelMinTimes[level - 1], LevelMaxTimes[level - 1]);
        digitalWrite(moles[num], HIGH);
        Miss[num] = 0;
        Hit[num] = 0;
        ActiveMoles++;
      }
    }
  }
  static unsigned long MoleTimer;
  int MoleDelay = 1; // 1000 times a second
  if ( micros() - MoleTimer >= (MoleDelay * 1000)) { // Switched to micros to be extremily accurate
    MoleTimer += (MoleDelay * 1000);
    for (int i = 0; i < MoleCount; i++) {
      if (popTime[i] <= -Cooldown)  popTime[i] = -Cooldown;
      popTime[i]--;
      Hit[i]--;
      Miss[i]--;
      if (popTime[i] == 0) {
        digitalWrite(moles[i], LOW);
        Miss[i] = DisplayTime;
        ActiveMoles--;
        missed++;
      }
    }
  }
}

void PrintSerial() {
  static unsigned long SpamTimer;
  int t = 100;//10 times a second
  if ( (unsigned long)(millis() - SpamTimer) >= (t)) {
    SpamTimer = millis();
    for (int i = 0; i < MoleCount; i++) {
      if (popTime[i] > 0)
        Serial.print("M");
      else if (Hit[i] > 0)
        Serial.print("X");
      else if (Miss[i] > 0)
        Serial.print("O");
      else Serial.print("_");

    }
    Serial.print("  Score: ");
    Serial.print(points);
    Serial.print("  Misses: ");
    Serial.print(missed);
    Serial.print("  Active Moles: ");
    Serial.print(ActiveMoles);
    Serial.println();
  }
}