Jamie Bull
Jamie Bull

Reputation: 13529

Why are the variables in my object being reset to the default?

I'm trying to write a chess clock on an Arduino with an LCD keypad shield. I'm almost completely new to C++ and I think I'm having trouble with how it handles class objects.

In my code I have a menu which should allow players to change the amount of time available to them by pressing the right and left buttons on the keypad. This seems to work at first, but when I switch to the other player and back again using the up and down buttons the minutes variable gets reset to the default value of 5 minutes.

What am I missing about how my Player objects are being handled?

boolean menuActive = true;

class Player {
  // Represents a player.
  public:
    int minutes;              // number of minutes allowed
    void IncrementMinutes();   
    void DecrementMinutes();   
};

void Player::IncrementMinutes() {
  this->minutes += 1;
}

void Player::DecrementMinutes() {
  if (this->minutes > 1) {
    this->minutes -= 1;
  }
}

Player p1 = {5, false, 1, "P1 mins: ", 0};
Player p2 = {5, false, 2, "P2 mins: ", 0};

Player menuPlayer = p1;

void setup()
{
 lcd.begin(16, 2);  
 lcd.setCursor(0,0);
 lcd.print("ChessClock");
}

// Main loop
void loop()
{
 lcd_key = read_LCD_buttons();  
 if (menuActive) {
   switch (lcd_key)               
   {
     case btnRIGHT:
       {
        // increase minutes
        menuPlayer.IncrementMinutes();        
        delay(250);        
        break;
       }  
     case btnLEFT:
       {
        // decrease minutes        
        menuPlayer.DecrementMinutes();        
        delay(250);        
        break;
       }  
     case btnUP:
       {
        // select player 1
        menuPlayer = p1;
        break;
       }  
     case btnDOWN:
       {
        // select player 2
        menuPlayer = p2;
        break;
       }  
     case btnNONE:
       {
       // display the current value for minutes
       lcd.print(menuPlayer.minutes);
       break;       
       }
     }
 } else {
   // Main timer code
   }
}

Upvotes: 0

Views: 106

Answers (1)

Tas
Tas

Reputation: 7111

You're making a copy of your Players:

// The actual players
Player p1 = {5, false, 1, "P1 mins: ", 0};
Player p2 = {5, false, 2, "P2 mins: ", 0};

// A COPY of player 1
Player menuPlayer = p1;

When you make calls like

menuPlayer.IncrementMinutes(); 

You are simply changing menuPlayer, not p1 or p2. So when you do the following

menuPlayer = p2;

All the changes made to menuPlayer are lost, and you make a new copy.

You could fix this by copying menuPlayer into p1 before swapping:

p1 = menuPlayer;
menuPlayer = p2;

Or by making menuPlayer a Player*:

// Point to p1:
Player* menuPlayer = &p1;

// Changes p1
menuPlayer->IncrementMinutes();

Upvotes: 1

Related Questions