Problem with score in higher lower game

int led1 = 2;
int led2 = 3;
int led3 = 4;
int led4 = 5;
int led5 = 6;
int led6 = 7;
int led7 = 8;
int led8 = 9;

int pins[8] = {2, 3, 4, 5, 6, 7, 8, 9};

int buzzer = 10;
int buttonLower = A2;
bool stateButtonL;
bool previousStateButtonL;
int buttonHigher = A1;
bool stateButtonH;
bool previousStateButtonH;
int previousRandNr;
int randNr;
int score;
String message;

void setup() {
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led7, OUTPUT);
  pinMode(led8, OUTPUT);
  pinMode(buzzer, OUTPUT);
  pinMode(buttonLower, INPUT_PULLUP);
  pinMode(buttonHigher, INPUT_PULLUP);
  previousStateButtonL = digitalRead(buttonLower);
  previousStateButtonH = digitalRead(buttonHigher);
  randomSeed(analogRead(A0));
  Serial.begin(9600);
}

void loop() {
  makeRandNr(previousRandNr);
  turnon(randNr);
  while(message == ""){
    buttonPressed(previousStateButtonL, previousStateButtonH);
  }
  higherLower(message, previousRandNr, randNr);
  Serial.println("Your score is " + String(score));
  previousRandNr = randNr;
  message = "";
}

int makeRandNr(int previousRandNr){
  randNr = random(9);
  while (randNr == previousRandNr){
    randNr = random(9);
  }
  Serial.println(randNr);
  return randNr;
}

void buttonPressed(bool previousStateButtonL, bool previousStateButtonH){
  stateButtonL = digitalRead(buttonLower);
  stateButtonH = digitalRead(buttonHigher);  
  if (stateButtonL != previousStateButtonL){
    Serial.println("lower pressed");
    message = "loweron";
  }
  else if(stateButtonH != previousStateButtonH){
    Serial.println("higher pressed");
    message = "higheron";
  }
  delay(200);
  previousStateButtonL = stateButtonL;
  previousStateButtonH = stateButtonH;
}

void higherLower(String message, int previousRandNr, int randNr){
  Serial.println(message);
  Serial.println(previousRandNr);
  Serial.println(randNr);
  if (message == "loweron" && randNr < previousRandNr){
    score ++;
  }
  else if (message == "higheron" && randNr > previousRandNr){
    score ++;
  }
  else{
    score --;
  }
}

void turnon(int number) {
  for (int i = 0; i < 8; i++) {
    if (i < number) {
      Serial.println("The following led is turned on: " + String(i));
      digitalWrite(pins[i], HIGH);
    }
    else {
      digitalWrite(pins[i], LOW);
    }
  }
}

All the things work except for the score counter, sometimes it takes a point of even when i push the right button, does anyone know what i can do?

You print the values of all the relevant variables, have you put your finger on your if/else statement(s) to see why they takes the branches they do?

  Serial.println(message);
  Serial.println(previousRandNr);
  Serial.println(randNr);

Maybe tell us how your game is supposed to be played, what it would be like to play.

a7

so my game works like this:
there are 8 LED's and 2 buttons' one that means higher and the other one means lower. I let random generate a number, after that all the led that are lower than this number go on. After that you choose between the 2 buttons, when you think the next number is going to be higher you choose the higher button, and when you think the next number is going to be lower you choose the lower button. When you have the correct answer you get a point, but when it's the wrong answer you lose a point. But the problem is that it doesn't always give you a point when you have the right answer...

This will not change the global variables previousStateButtonL and previousStateButtonH. These variables should either be passed by reference, or not at all (since they are global anyway).

that's true, but that doesn't fix my problem with the score counter...

add some debounce to make sure the button is released and not double counted.

I think @madmark2150 is correct to mention debouncing, also it looks like your code responds to button "unpresses" as well as presses.

  if (stateButtonL != previousStateButtonL){
    Serial.println("lower pressed");
    message = "loweron";
  }

You set the message if the current state is merely different to the previous state.

Your sketch has a few other problems, but one thing I think you've got very wrong makes playing the game kinda annoying.

Try this loop() function:

void loop() {
  makeRandNr(previousRandNr);
  turnon(previousRandNr);     // <-----------

  Serial.print("            cheat - the new number is ");
  Serial.print(randNr);
  Serial.println(randNr > previousRandNr ? " HIGHER!" : " LOWER!");

  while(message == ""){
    buttonPressed();
  }

  higherLower(message, previousRandNr, randNr);

  Serial.println("                      Your score is " + String(score));

  previousRandNr = randNr;
  message = "";
}

You want to turn on the previous number of LEDs, and have randNr be the secret that is either higher or lower.

That is one of the many changes I had to make before I started enjoying your game.

I'm not sure your scoring logic will work. By the time I found the show-stopper, I had rewritten that section because I have trouble with complicated if conditions. I usually am only testing one thing at a time in an if statement, and further conditions are if statements within that.

if... the new number is larger 
   if... the user guessed right, score up
   else score down

if... the new number is smaller
   if... the user guessed right, score up
   else score down

Like I say, your logic may work, TBH I never tried it, I just junked it thinking it was problematic.

But I have to say, for a dumb game it is fun when you get it working, especially if you leave the printing that lets you cheat.

You use a String variable to carry a simple "message"... usually ppl use an integer, and use numbers as code for messages. Like 0 would mean nothing pressed, 1 would mean she pressed lower and 2 would mean she pressed higher. Ask your teacher why.

a7

i think it works now, after using your changes, thank you so much!!!

What? You think it works?

I know mine works. I should think you would be able to test yours and know it works, or doesn't.

Put you code into this empty vessel:

wokwi guessing game hardware


Note that I put the switches on different I/O pins, A1 and A2 - make two small changes to your code, and play the game you wrote.

Please also post your code here, not for me, my game is finished. But because others have been following along, or will find this discussion, and wnat to see how you solved the problems.

Or if you did. :expressionless:

That's sorta the deal on these fora, you don't run off once you are happy! And leave us to wonder...

TIA

a7

It works, I tested it a few times with the changes you recommended, here is the code now:

int led1 = 2;
int led2 = 3;
int led3 = 4;
int led4 = 5;
int led5 = 6;
int led6 = 7;
int led7 = 8;
int led8 = 9;

int pins[8] = {2, 3, 4, 5, 6, 7, 8, 9};

int buzzer = 10;
int buttonLower = A2;
bool stateButtonL;
bool previousStateButtonL;
int buttonHigher = A1;
bool stateButtonH;
bool previousStateButtonH;
int previousRandNr;
int randNr;
int score;
String message;
long lastDebounceTime = 0;
long debounceDelay = 50;

void setup() {
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led7, OUTPUT);
  pinMode(led8, OUTPUT);
  pinMode(buzzer, OUTPUT);
  pinMode(buttonLower, INPUT_PULLUP);
  pinMode(buttonHigher, INPUT_PULLUP);
  previousStateButtonL = digitalRead(buttonLower);
  previousStateButtonH = digitalRead(buttonHigher);
  randomSeed(analogRead(A0));
  Serial.begin(9600);
}

void loop() {
  while (score < 9){
    makeRandNr(previousRandNr);
    turnon(previousRandNr);
    while(message == ""){
      buttonPressed(previousStateButtonL, previousStateButtonH);
    }
    higherLower(message, previousRandNr, randNr);
    Serial.println("Your score is " + String(score));
    previousRandNr = randNr;
    message = "";
  }
    Serial.println("You won!");
    turnon(10);
    turnon(0);
}

int makeRandNr(int previousRandNr){
  randNr = random(9);
  while (randNr == previousRandNr){
    randNr = random(9);
  }
  return randNr;
}

void buttonPressed(bool previousStateButtonL, bool previousStateButtonH){
  stateButtonL = digitalRead(buttonLower);
  stateButtonH = digitalRead(buttonHigher); 
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (stateButtonL != previousStateButtonL){
      Serial.println("lower pressed");
      message = "loweron";
    }
    else if(stateButtonH != previousStateButtonH){
      Serial.println("higher pressed");
      message = "higheron";
    }
    delay(150);
    previousStateButtonL = stateButtonL;
    previousStateButtonH = stateButtonH;
    lastDebounceTime = millis();
  }
}

void higherLower(String message, int previousRandNr, int randNr){
  if (randNr < previousRandNr){
    if (message == "loweron"){
      score ++;
    }
    else {
      score --;
    }
  }
  else if (randNr > previousRandNr){
    if (message == "higheron") {
      score ++;
    }
    else {
      score --;
    }
  }

}

void turnon(int number) {
  for (int i = 0; i < 9; i++) {
    if (i < number) {
      Serial.println("The following led is turned on: " + String(i));
      digitalWrite(pins[i], HIGH);
    }
    else {
      digitalWrite(pins[i], LOW);
    }
  }
}

THX!

When I get back to the lab I will try it out.

a7

I played your game using your latest code.

I think you should add

  previousRandNr = 4;

at the end of your setup(), so the game will not appear dead when you power it on. That would put 4 into play as the number to predict against instead of zero.

I think you should drop 0 as a number, so that there is always at least one LED illuminated to predict against. It just seems dead when 0 is the number.

Your button handler has what appears to be a debouncing algorithm. That algorithm is incorrectly implemented. Its various flaws are fixed masked by your insertion of

    delay(150);

which also totally defeats or obviates any need for debouncing.

All the flaws I found in your sketch have been previously exposed by the contributors to this thread. If you want to have a game that will work for all and not need any special instructions to the player, work through this thread and try to undestand what you have been told.

Your game may be playable, but anyone looking to find fault will. :expressionless:

Like "don't hold down the button too long" kinda instructions.

a7

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