[SOLVED] Arduino Reaction Game, Can't find Mistake!

Hey!
I decided to make a simple Arduino reaction game a while ago, and decided to upgrade it. I'm trying to make it so that you can choose the number of games you want to play, and choose a game type; either whoever has the best average over the certain number of games, or whoever has won the most number of games. it works almost perfectly, except for a few major problems;

  1. In the Overall Time game, the blue players' average jumps randomly, and I have no clue why. I can't figure out what is causing it to do so
  2. It seems that the blue player is stopped from winning sometime. It is almost always either a tie, and even if I press the blue button, wait, and then press the red one, there is a smaller time difference in favour of blue, then I would've expected. I don't think it is to do with wiring, because I wrote code to test the button and it seemed fine. I'm not 100% sure this is actually a problem
  3. I tried making unique way to deal with a player just holding the button, or pressing it too early. Basically, in the overall average game, I wanted it to divide your overall time by the number of games you played fairly and add a ten millisecond penalty for every time you forfeit. To do this I added a forfeit counter for each time you forfeited. However this doesn't seem to work. Is my math wrong??? (line 320 and 321)

I know that my code is probably extremely sloppy, and constructive criticism is more than appreciated. My code is pretty long, and I will be very, very grateful for anyone who can help. Thanks in advance!

// include the library code:
#include <LiquidCrystal.h>

//setting button pins
const int rButtonPin = A3;
const int bButtonPin = A2;
const int sButtonPin = A1;
const int LightPin = A0;

//setting button states
int rButtonState = 0;
int bButtonState = 0;
int sButtonState = 0;

//seeing if the player is done or forfeited
int rDone = 0;
int bDone = 0;

int rForfeit = 0;
int bForfeit = 0;
int rForfeitCounter = 0;
int bForfeitCounter = 0;

//counting time
int time = 0;
int timeDone = 0;
int rTime = 0;
int bTime = 0;
int rOvrTime = 0;
int bOvrTime = 0;
int rAvg = 0;
int bAvg = 0;
int rWins = 0;
int bWins = 0;


//command to start the game, and other self explanatory variables
String command;
int game = 0;
int gtype = 0;
int stopPrint = 0;
int numgames = 0;
int Delay = 0;
int gnum = 1;

//setting up the lcd with the pin #'s
  const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
  LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {
  // declaring pins and starting the serial print
  pinMode(rButtonPin, INPUT);
  pinMode(bButtonPin, INPUT);
  pinMode(sButtonPin, INPUT);

  Serial.begin(9600);
  pinMode(LightPin, OUTPUT);

  //for generating a random number
  randomSeed(analogRead(0));

  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);


}

void loop() {
  // put your main code here, to run repeatedly:
  //checking the if the button's are on or off
  rButtonState = digitalRead(rButtonPin);
  bButtonState = digitalRead(bButtonPin);
  sButtonState = digitalRead(sButtonPin);

  //for the new buttons
  digitalWrite(rButtonPin, HIGH);
  digitalWrite(bButtonPin, HIGH);
  digitalWrite(sButtonPin, HIGH);

  switch (game) {
    case 0:
      GetGame();
      break;
    
    case 1:
      GetNumGames();
      break;
    
    case 2:
      PreGame();
      break;

    case 3:
      MainGame();
      break;

    case 4:
      OVRGAME();
      break;

    case 5:
      NUMOFWINSGAME();
      break;
    
    case 6:
      OVRResults();
      break;
    
    case 7:
      Restart();
  }
}
      


void GetGame () {
  if (stopPrint == 0) {
    gtype = 0;
    lcd.clear();
    lcd.print("Choose Game Red");
    Serial.print("Press Red Button to change game type\n");
  }
  stopPrint = 1;
  if (rButtonState == LOW) {
    if(gtype == 2) {
      gtype = 1;
      lcd.clear();
      lcd.print("OVR GAME");
      delay(300);
    } else {
      gtype = 2;
      lcd.clear();
      lcd.print("# OF WINS GAME");
      delay(300);   
    }
  }
  if(sButtonState == LOW && gtype > 0) {
    game++;
    stopPrint = 0;
    Serial.print("Game type got: ");
    Serial.print(gtype);
  }
}



void GetNumGames () {
  if (stopPrint == 0){
    lcd.setCursor(0,1);
    lcd.print("Choose Game #: ");
  }
  stopPrint = 1;
  if (rButtonState == LOW) {
    numgames ++;       
    if (numgames > 9){
      numgames = 9;
    } 
    lcd.setCursor(14,1);
    lcd.print(numgames);
    delay(300);   
  }
  if (bButtonState == LOW) {
    numgames --;
    if (numgames < 1){
      numgames = 1;
    }
    lcd.setCursor(14,1);
    lcd.print(numgames);
    delay(300);
  }
  if (sButtonState == LOW && numgames > 0) {
    game++;
    Serial.print("Next step");
    Serial.print(numgames);
    Serial.print(sButtonState);
    stopPrint = 0;
    Serial.print("numgames = ");
    Serial.print(numgames);
    Serial.print("gnum = ");
    Serial.print(gnum);
  }
}



void PreGame() {
  if (stopPrint == 0){
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(".");
    delay(300);
    lcd.print(".");
    delay(300);
    lcd.print(".");
    delay(300);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("PressBlackButton");
    lcd.setCursor(0,1);
    lcd.print("To Start Game ");
    lcd.print(gnum);
    stopPrint = 1;
  } 
  delay(300);
  sButtonState = digitalRead(sButtonPin);

  if (sButtonState == LOW) {
    //delaying until button pressed
    Serial.print("pregame pressed");
    game++;
    lcd.clear();
    lcd.setCursor(0,0);
    stopPrint = 0;
  }
}



void MainGame() {
    delay(500);
    Serial.print("Get Ready!\n");
    lcd.print("Get Ready!");
    Delay = random(100, 300);
    //delaying a random time
    delay(Delay*10);
    //Checking for False Start
    rButtonState = digitalRead(rButtonPin);  
    bButtonState = digitalRead(bButtonPin);  

    if (rButtonState == LOW) {
      rForfeit = 1;
      rDone = 1;
      rForfeitCounter++;
    }

    if (bButtonState == LOW) {
      bForfeit = 1;
      bDone = 1;    
      bForfeitCounter++;  
    }    
    //STARTING!!!
    digitalWrite(LightPin, HIGH);
    game = game + gtype;         
}



void OVRGAME() {
  //counting time
    if (timeDone == 0) {
      delay(1);
      time ++;
    }

    //checking if they're done!
    if(rButtonState == LOW && rForfeit == 0 && rDone == 0) {
      rDone = 1;
      rTime = time;
      rOvrTime = rOvrTime + rTime;
    }

    if(bButtonState == LOW && bForfeit == 0) {
      bDone = 1;
      bTime = time;
      bOvrTime = bOvrTime + bTime;
    }

    //annoying processing thingy
    if (rDone == 1 && bDone == 1) {
      timeDone = 1;
      
      if (stopPrint == 0) {
        Serial.print(time);
        lcd.clear();
        digitalWrite(LightPin, LOW);
        Serial.print("processing.");
        lcd.print("processing.");
        delay(500);
        Serial.print(".");
        lcd.print(".");
        delay(500);
        Serial.print(".\n");
        lcd.print(".");     
        delay(500);
      
        lcd.clear();            
        //writing the time, or if they forfeited
        if (rTime == 0) {
          Serial.print("Red went too early\n");
          lcd.print("R Forf ");
        }
        else {
          Serial.print("Red time is: ");
          lcd.print("R ");
          Serial.print(rTime);
          lcd.print(rTime); 
          Serial.print("ms\n");   
          lcd.print("ms ");
        }

        if (bTime == 0) {
          Serial.print("Blue went too early\n");
          lcd.print(" B Forf ");        
        }
        else {
          Serial.print("Blue time is: ");
          lcd.print("B ");
          Serial.print(bTime); 
          lcd.print(bTime);
          Serial.print("ms\n");
          lcd.print("ms");
        }
      
        delay(300);

      //set cursor to second row
        lcd.setCursor(0, 1);
        lcd.print("RA ");
        rAvg = rOvrTime/(gnum - rForfeitCounter) + rForfeitCounter * 10;
        bAvg = bOvrTime/(gnum - bForfeitCounter) + bForfeitCounter * 10;
        lcd.print(rAvg);
        lcd.print("m BA ");
        lcd.print(bAvg);
        lcd.print("m");
        }
      
        stopPrint = 1;
        delay(300);

      if (sButtonState == LOW) {
        game = game + 2;
        stopPrint = 0;
      }      
    }
}



void NUMOFWINSGAME() {
  //counting time
    if (timeDone == 0) {
      delay(1);
      time ++;
    }

    //checking if they're done!
    if(rButtonState == LOW && rForfeit == 0 && rDone == 0) {
      rDone = 1;
      rTime = time;
      rOvrTime = rOvrTime + time;
    }

    if(bButtonState == LOW && bForfeit == 0) {
      bDone = 1;
      bTime = time;
      bOvrTime = bOvrTime + time;
    }

    //annoying processing thingy
    if (rDone == 1 && bDone == 1) {
      timeDone = 1;

      if(stopPrint == 0) {
        Serial.print(time);
        lcd.clear();
        digitalWrite(LightPin, LOW);
        Serial.print("processing.");
        lcd.print("processing.");
        delay(500);
        Serial.print(".");
        lcd.print(".");
        delay(500);
        Serial.print(".\n");
        lcd.print(".");     
        delay(500);
      
        lcd.clear();            
        //writing the time, or if they forfeited
        if (rTime == 0) {
          Serial.print("Red went too early\n");
          lcd.print("R Forf ");
        }
        else {
          Serial.print("Red time is: ");
          lcd.print("R ");
          Serial.print(rTime);
          lcd.print(rTime); 
          Serial.print("ms\n");   
          lcd.print("ms ");
        }

        if (bTime == 0) {
          Serial.print("Blue went too early\n");
          lcd.print(" B Forf ");        
        }
        else {
          Serial.print("Blue time is: ");
          lcd.print("B ");
          Serial.print(bTime); 
          lcd.print(bTime);
          Serial.print("ms\n");
          lcd.print("ms");
        }
      
        delay(300);

        //set cursor to second row
        lcd.setCursor(0, 1);

        //seeing who wins!
        if (rTime == bTime && rForfeit == 0){
          Serial.print("TIE\n");
          lcd.print("TIE");
          bWins++;
          rWins++;
        } 
        if (rTime == bTime && rForfeit == 1){
          Serial.print("No-one wins\n");
          lcd.print("Both Forfeited");
        } 
        if (rTime < bTime && rForfeit == 0) {
          Serial.print("RED WINS!!!\n");
          lcd.print("RED WINS");
          rWins++;
        } 
        if(rTime < bTime && rForfeit == 1){
          Serial.print("BLUE WINS!!!\n");
          lcd.print("BLUE WINS");
          bWins++;  
        }
        if (bTime < rTime && bForfeit == 0) {
          Serial.print("BLUE WINS!!!\n");
          lcd.print("BLUE WINS");
          bWins++;        
        } 
        if(bTime < rTime && bForfeit == 1){
          Serial.print("RED WINS!!!\n");
          lcd.print("RED WINS");
          rWins++;
        }

        stopPrint = 1;
      }  
        
      delay(300);
      
      if (sButtonState == LOW) {
        game ++;
        stopPrint = 0;       
      }        
    }
}



void OVRResults() {
  if (stopPrint == 0 && gtype == 1) {
    lcd.clear();
    lcd.setCursor(0,0);
    if(rAvg > bAvg) {
      lcd.print("rA = +");
      lcd.print(rAvg - bAvg);
      lcd.print("ms");
    } else if(bAvg > rAvg) {
      lcd.print("bA = +");
      lcd.print(bAvg - rAvg);
      lcd.print("ms");
    }  else {
      lcd.print("r = b");
    }  
    lcd.setCursor(0,1);
    lcd.print("PressBlackButton");
    stopPrint = 1;
  }

  if (stopPrint == 0 && gtype == 2) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("RW = ");
    lcd.print(rWins);
    lcd.print(" BW = ");
    lcd.print(bWins);
    lcd.setCursor(0,1);
    lcd.print("PressBlackButton");
    stopPrint = 1;
  } 
  
  if (sButtonState == LOW) {
    game++;
    gnum++;
    stopPrint = 0;
    Serial.print(game);
  } 
}



void Restart() {
  Serial.print("numgames = ");
  Serial.print(numgames);
  Serial.print("\ngnum = ");
  Serial.print(gnum);
  if (gnum > numgames) {
    if(stopPrint == 0) {
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Results");
        delay(500);
        lcd.clear();
        if (gtype == 1) {
          if (rAvg == bAvg){
            Serial.print("TIE\n");
            lcd.print("TIE");
          } 
          if (rAvg < bAvg) {
            Serial.print("RED WINS!!!\n");
            lcd.print("RED WINS");
          } 
          if (bAvg < rAvg){
            Serial.print("BLUE WINS!!!\n");
            lcd.print("BLUE WINS");
          }
          lcd.setCursor(0,1);
          lcd.print("r:");
          lcd.print(rAvg);
          lcd.print("ms b:");
          lcd.print(bAvg);
          lcd.print("ms");
        }

        if (gtype == 2) {
          if (rWins == bWins){
            Serial.print("TIE\n");
            lcd.print("TIE");
          } 
          if (rWins < bWins) {
            Serial.print("RED WINS!!!\n");
            lcd.print("RED WINS");
          } 
          if (bWins < rWins){
            Serial.print("BLUE WINS!!!\n");
            lcd.print("BLUE WINS");
          }
          lcd.setCursor(0,1);
          lcd.print("rWins:");
          lcd.print(rWins);
          lcd.print(" bWins:");
          lcd.print(bWins);
          stopPrint = 1;
        } 
      }
      delay(300);
      sButtonState = digitalRead(sButtonPin);

      if(sButtonState == LOW){
        stopPrint = 0;
        bWins = 0;
        rWins = 0;
        rOvrTime = 0;
        bOvrTime = 0;
        gnum = 1;
        numgames = 0; 
        rForfeitCounter = 0;
        bForfeitCounter = 0; 
        game = 0;
        gtype = 0;
        rDone = 0;
        bDone = 0;

        rForfeit = 0;
        bForfeit = 0;
        time = 0;
      }  
  } else {

      rDone = 0;
      bDone = 0;

      rForfeit = 0;
      bForfeit = 0;

      time = 0;
      timeDone = 0;
      rTime = 0;
      bTime = 0;
      stopPrint = 0;
      game = 2;      
    }

}

Can you make a block diagram showing how all parts are connected and powered?

You're checking 'rDone' but not 'bDone'. Could that cause the problem?

Sure! Just a heads up that it's my first time making one, and I'm not sure whether there's another way to represent a button, as my button is push to break the circuit, not push to complete it

YESSS!!!! Thank you soooo much. I can't believe I didn't see this. I know how it fixes problem 1 and 2, but even problem 3 seems to be fixed now. Thanks again!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.