Hello, OnlineGDB Q&A section lets you put your programming query to fellow community users. Asking a solution for whole assignment is strictly not allowed. You may ask for help where you are stuck. Try to add as much information as possible so that fellow users can know about your problem statement easily.

Why don't my while statements terminate even when the output shows that the conditions become false?

+5 votes
asked Oct 27, 2022 by Caleb Weigt (170 points)

#include <iostream>
#include <time.h>
using namespace std;

int roll(int sides);
int coinToss();
int rollD20();
int playerOneTurn(int twoHp, int twoArmor);
int playerTwoTurn(int oneHp, int oneArmor);
    
int theRoll;
int playerDamage;
int cumulativeDMGTwo;
int cumulativeDMGOne;

int main() {
    srand (time(NULL));
    
    
    int playerOneHp = ((rand() % 15) + 10);
    int playerOneArmor = (rand() % 9) + 8;
    int playerTwoHp = ((rand() % 15) + 10);
    int playerTwoArmor = (rand() % 9) + 8;
    
    cout<<"Player one begins with " << playerOneHp << " hitpoints." << endl;
    cout<<"Player one begins with " << playerOneArmor << " armor points." << endl;
    cout<<"Player two begins with " << playerTwoHp << " hitpoints." << endl;
    cout<<"Player two begins with " << playerTwoArmor << " armor points." << endl;
    
     
    if(coinToss() == 1) {
        cout<<"Player one starts."<<endl;
        while(playerOneHp > 0 && playerTwoHp > 0) {         //This while statement 
            playerOneTurn(playerTwoHp, playerTwoArmor);
            playerTwoTurn(playerOneHp, playerOneArmor);
            
        }      
    } else {
        cout<<"Player two starts."<<endl;
        while(playerOneHp > 0 && playerTwoHp > 0) {             //This while statement
            playerTwoTurn(playerOneHp, playerOneArmor);
            playerOneTurn(playerTwoHp, playerTwoArmor);
            
        }      
    }
    
} //for int main   

int playerOneTurn(int twoHp, int twoArmor) {
    theRoll = rollD20();
    
    if(theRoll > twoArmor) {
        playerDamage = (roll((6) - 1) + 1) + playerDamage;
        cout<<"Player one deals " << playerDamage << " total damage to player two!"<<endl;
        twoHp = twoHp - playerDamage;
        cout<<"Player two has " << twoHp << " hitpoints left!"<<endl;
        if(twoHp <= 0){
            cout<<"Player One wins!!"<<endl;
        } return twoHp;
    } else {
        cout<<"Player one missed!"<<endl;
    }
}

int playerTwoTurn(int oneHp, int oneArmor) {
    theRoll = rollD20();
    
    if(theRoll > oneArmor) {
        playerDamage = (roll((6) - 1) + 1) + playerDamage;
        cout<<"Player two deals " << playerDamage << " total damage to player one!"<<endl;
        oneHp = oneHp - playerDamage;
        cout<<"Player one has " << oneHp << " hitpoints left!"<<endl;
        if(oneHp <= 0){
            cout<<"Player Two wins!!"<<endl;
        } return oneHp;
    } else {
        cout<<"Player two missed!"<<endl;
    }
}

int rollD20() {
    return (rand() % 20) + 1;
}

int roll(int sides) {
    return (rand() % (sides)) + 1;
}

int coinToss() {
    return (rand() % 2) + 1;
}

2 Answers

0 votes
answered Oct 29, 2022 by Anon (180 points)

When you pass health variable into the player function, it creates a copy of that variable and is an instance variable that only exists in that function. You need to pass the variable into the function by reference to update with the original variable. Try this:

#include <iostream>
#include <time.h>
using namespace std;

int roll(int sides);
int coinToss();
int rollD20();
void playerOneTurn(int &twoHp, int &twoArmor);    //changed to void and pass by reference parameter
void playerTwoTurn(int &oneHp, int &oneArmor);    //changed to void and pass by reference parameter
    
int theRoll;
int playerDamage;
int cumulativeDMGTwo;
int cumulativeDMGOne;

int main() {
    srand (time(NULL));
    
    
    int playerOneHp = ((rand() % 15) + 10);
    int playerOneArmor = (rand() % 9) + 8;
    int playerTwoHp = ((rand() % 15) + 10);
    int playerTwoArmor = (rand() % 9) + 8;
    
    cout<<"Player one begins with " << playerOneHp << " hitpoints." << endl;
    cout<<"Player one begins with " << playerOneArmor << " armor points." << endl;
    cout<<"Player two begins with " << playerTwoHp << " hitpoints." << endl;
    cout<<"Player two begins with " << playerTwoArmor << " armor points." << endl;
    
     
    if(coinToss() == 1) {
        cout<<"Player one starts."<<endl;
        while(playerOneHp > 0 && playerTwoHp > 0) {         //This while statement 
            playerOneTurn(playerTwoHp, playerTwoArmor);
            playerTwoTurn(playerOneHp, playerOneArmor);
            
        }      
    } else {
        cout<<"Player two starts."<<endl;
        while(playerOneHp > 0 && playerTwoHp > 0) {             //This while statement
            playerTwoTurn(playerOneHp, playerOneArmor);
            playerOneTurn(playerTwoHp, playerTwoArmor);
            
        }      
    }
    
} //for int main   

void playerOneTurn(int &twoHp, int &twoArmor) { //changed parameter into pass by reference
    theRoll = rollD20();
    
    if(theRoll > twoArmor) {
        playerDamage = (roll((6) - 1) + 1) + playerDamage;
        cout<<"Player one deals " << playerDamage << " total damage to player two!"<<endl;
        twoHp = twoHp - playerDamage;
        cout<<"Player two has " << twoHp << " hitpoints left!"<<endl;
        if(twoHp <= 0){
            cout<<"Player One wins!!"<<endl;
        }
    } else {
        cout<<"Player one missed!"<<endl;
    }
}

void playerTwoTurn(int &oneHp, int &oneArmor) { //changed parameter into pass by reference
    theRoll = rollD20();
    
    if(theRoll > oneArmor) {
        playerDamage = (roll((6) - 1) + 1) + playerDamage;
        cout<<"Player two deals " << playerDamage << " total damage to player one!"<<endl;
        oneHp = oneHp - playerDamage;
        cout<<"Player one has " << oneHp << " hitpoints left!"<<endl;
        if(oneHp <= 0){
            cout<<"Player Two wins!!"<<endl;
        }
    } else {
        cout<<"Player two missed!"<<endl;
    }
}

int rollD20() {
    return (rand() % 20) + 1;
}

int roll(int sides) {
    return (rand() % (sides)) + 1;
}

int coinToss() {
    return (rand() % 2) + 1;
}
0 votes
answered Oct 30, 2022 by Peter Minarik (86,040 points)

It is, because player???Turn(int hp, int armor) takes the parameters by value, not by reference (or pointer). You make a copy of the hp and armor so if you change them inside the function, you change the copies only, not the original values.

Suggestion: pass the values by reference if you want any change inside the function to be reflected back to the caller:

player???Turn(int & hp, int & armor)
Welcome to OnlineGDB Q&A, where you can ask questions related to programming and OnlineGDB IDE and and receive answers from other members of the community.
...