|| operator in while condition not working as expected - c++

So I'm a new programmer and I decided to try and make this game. It is a basic, let's say person v. person game. You enter the amount of each team, in my case Ninjas and Samurai, and then it randomizes the attack chance of each and outputs the winner. Every time I run the program I input the number of each type, and I always get an output of the Ninjas having 0 health, and the Samurai having negative health. How would I be able to have the while loop end when one team gets to 0 health? I've tried using totalNinjaHealth != 0 || totalSamuraiHealth != 0 but the program runs infinitely.
#include <iostream>
#include <random>
#include <string>
#include <ctime>
using namespace std;
int main() {
int ninjas;
int NINJA_HEALTH = 2;
int NINJA_ATTACK = 2;
int samurai;
int SAMURAI_HEALTH = 3;
int SAMURAI_ATTACK = 1;
default_random_engine randomGen(time(NULL));
uniform_real_distribution<float> attackChance(0.0f, 1.0f);
cout << " *** Ninjas V Samurai *** " << endl;
cout << "Input amount of Ninjas" << endl;
cin >> ninjas;
cout << "Input amount of Samurai" << endl;
cin >> samurai;
int totalNinjaHealth = NINJA_HEALTH * ninjas;
int totalSamuraiHealth = SAMURAI_HEALTH * samurai;
cout << totalNinjaHealth << endl;
while (totalNinjaHealth > 0 == true || totalSamuraiHealth > 0 == true)
{
if (attackChance(randomGen) > 0.5f) {
totalSamuraiHealth -= NINJA_ATTACK;
cout << totalSamuraiHealth << endl;
}
else if(attackChance(randomGen) < 0.5f) {
totalNinjaHealth -= SAMURAI_ATTACK;
cout << totalNinjaHealth << endl;
}
}
if (totalNinjaHealth == 0) {
cout << "Ninjas lost all " << ninjas << " Ninjas. Samurai remaining " << totalSamuraiHealth << endl;
}
else if (totalSamuraiHealth == 0)
{
cout << "Samurai lost all " << ninjas << " Samurai. Ninjas that remain " << totalNinjaHealth / 2 << endl;
}
cin.get();
cin.get();
return 0;
}
Screenshot of what happens when ran:ConsoleWhenRan
Am I using the || operator incorrectly? I thought the || operator waits until one condition is true and then stops, but when I run the code It seems to wait until both either pass, or equal 0 giving the negative output.

You need to use the && operator. The || is the "or" operator and will evaluate to true when either one or both of the conditions are true. In your case, the while loop will continue to evaluate as long as one of your teams has health > 0. The "and" operator (&&) requires both conditions to be true for the statement to be evaluated as true.

What happens is:
You run the loop until either of the teams has positive total health. So the total health is for both of the teams is less/equal to zero.
Then you check the healths and you get your answer. It just so happens that in your case one of the teams died with exactly 0 health. In some cases though, the output should show neither the messages.

Related

while loop w/ 2 conditions does not work c++

I'm working on a minigame in C++ lately. The goal is to write a little game where you have to guesse a number. If you do so you'll get a point (I call it hit there) and if you don't you'll get a "miss". Logically speaking I don't want the game to go for ever. So I was trying to use a while loop to define at which scores you can still play. How you will be able to see in the code there are two conditions. Here is why I asked you: As long as there are two conditions it just ignores these so the game turns into an endless game. I don't recive any error-messages from VS2019. When I only try it w/ one condition it works just fine.
Here's the code:
#include <iostream>
#include <cstdlib>
#include <time.h>
using namespace std;
int main()
{
cout << "Welcom to the Hit-or-Miss-minigame. Here are the rules:" << endl;
cout << "You have to guess the same number as the computer. The numbers are within 0 and 10(both are still included)." << endl;
cout << "If you do so, you'll get a 'HIT' but if you don't you'll get a 'MISS'. When you reach 10 'HIT's you win" << endl;
cout << "but if you get a 'MISS' 15 times you'll lose." << endl;
char rep = 'y';
while (rep == 'y')
{
int hits = 0;
int miss = 0;
while ((hits < 3||miss < 15)) //Somehow doesn't work. So why?
{
int input_number;
srand(time(NULL));
int random_number = rand() % 11;
cout << "Your number: ";
cin >> input_number;
if (input_number == random_number)
{
cout << "HIT" << endl;
hits += 1;
}
else if (input_number != random_number)
{
cout << "MISS" << endl;
miss += 1;
}
else if ((input_number > 10) || (input_number < 0))
{
cout << "That was not an option";
}
else
{
cout << "That's not supposed to happen." << endl;
}
}
if (hits == 10)
{
cout << "You've won! Do you want to play another round?(y/n)" << endl;
cin >> rep;
}
else if (miss == 15)
{
cout << "You lose! Do you want to play another round?(y/n)" << endl;
cin >> rep;
}
}
}
I really would appreciate any help. Thanks!
EDIT: Problem solved. THANK YOU GUYS!
if you want the game will end after 3 hits or 15 misses you should use the && operator and not the || operator
it is because the || operator will return true when at least one of the conditions true, the && operator will return true when both of the true
Like the other comment said you should use && in your while loop, because you can have 16 misses and 3 hits before the loop breaks(for example 2 < 3 || 25 < 15 returns true and is only false when you get 3 < 3 || 25 < 15), which won't enter any if below the while, and it will just reset the variables back to 0 (this makes the while infinite). Furthermore if you put && in the while you need to change the if statement for hits to hits == 3 or it will never happen.
Also as a side note your if statement for numbers below zero and bigger than 10 needs to be above the one where you check if the guessed number is a miss (because every number bigger than 10 and smaller than 0 is a miss).
Hope this helps

How do I my Program to stop Replicating if wrong input

My program will repeat output: "You are currently on the 2 floor out of 5
The sum of the codes is: 7 and the product of the codes is: 12
Try again before he catches onto you!"
Based on how many wrong characters are added how can I fix this? I have inserted the cin.clear and cin.ignore but it will repeat the part above.
i.e. if I type wasds it will repeat 5x. Any other notes are also appreciated.
#include <iostream>
#include <ctime>
using namespace std;
int PlayerLevel = 0;
int MaxLevel = 5;
bool GamePlay ()
{
srand(time(NULL));
int PlayerGuessA, PlayerGuessB, PlayerGuessC;
int CodeA = rand() % PlayerLevel + PlayerLevel;
int CodeB = rand() % PlayerLevel + PlayerLevel;
int CodeC = rand() % PlayerLevel + PlayerLevel;
int SumofCodes = CodeA + CodeB + CodeC;
int ProductofCodes = CodeA * CodeB * CodeC;
cout << "You are currently on the " << PlayerLevel << " floor out of 5" << endl;
cout << "The sum of the codes is: " << SumofCodes << " and the product of the codes is: " << ProductofCodes << endl;
cin >> PlayerGuessA >> PlayerGuessB >> PlayerGuessC;
int PlayerProduct = PlayerGuessA * PlayerGuessB * PlayerGuessC;
int PlayerSum = PlayerGuessA + PlayerGuessB + PlayerGuessC;
if (PlayerProduct == ProductofCodes && SumofCodes == PlayerSum) {
cout << "Great Job you got this!!!\n" << endl;
++PlayerLevel;
return true;
}
else
{
cout << "Try again before he catches onto you!\n" << endl;
return false;
}
}
int GameStart()
{
string Introduction = "Welcome to your worst nightmare. You are trapped in a murderer's house. You are on the 5th floor and need to get to the first floor to escape.\n";
string Instructions = "He has each door locked behind a security system that requires a 3 number code to disarm it.\nEnter the codes and move foward. Each level will the code will be harder to figure out.\n";
string PlayerStart;
cout << Introduction << endl;
cout << Instructions << endl;
cout << "Would you like to escape? Yes or No" << endl;
cin >> PlayerStart;
if (!(PlayerStart != "Yes" && PlayerStart != "yes")) {
++PlayerLevel;
}
return 0;
}
int main ()
{
if (PlayerLevel == 0) {
GameStart();
}
while (PlayerLevel <= MaxLevel)
{
bool bLevelComplete = GamePlay();
cin.clear ();
cin.ignore();
}
cout << "You Made it out! Now run before he finds out!" << endl;
return 0;
}
When the type of the input doesn't match the type of the variable that it is being extracted to, cin sets the fail bit. Once this happens, all subsequent reads fail until the stream is reset. The offending characters are still left in the buffer, so that needs to be cleared out as well.
Your usage of cin.clear() and cin.ignore() meant that the fail bit was getting reset, but only one offending character was being removed (cin.ignore() ignores one character by default). This is why you saw the output repeating x times for x erroneous characters.
You could do something like this:
while (PlayerLevel <= MaxLevel)
{
bool bLevelComplete = GamePlay();
if (cin.fail())
{
//Input extraction failed, need to reset stream and clear buffer until newline
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
}
}

C++ simple game using a Loop program

This program will play a game with the user, called Odds and Evens. The computer will play Evens, and the human user will play Odds. For a round of the game, each player picks an integer in the range [1,10]. The players pick their numbers independently: neither player knows the other player's number before choosing its own number. If the sum of the numbers is even, then Evens (the computer) wins that round; if the sum of the numbers is odd, then Odds (the human) wins that round. The game continues for as many rounds as the user want to play; the user ends the game by typing a non-# or a number outside [1,10] for the input. At the end of the game, the program summarizes the score.
I am having trouble properly looping this question. Randomizing the number pc chooses is not working as every round in the game the pc chooses the same number. Also i do not know how I would have the program summarize the score. Help would be much appreciated as I have another problem for homework that is similar to this!
Here is my code:
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <string>
#include <iomanip>
#include <ctime>
using namespace std;
bool die(const string & msg);
int main(){
srand(static_cast<unsigned>(time(0)));
unsigned num1 = 0, num = 0, sum = 0;
bool userTurn = true;
cout << "Welcome to the Odds and Evens game!";
num = rand() % 10 + 1;
while (num){
if (userTurn){
cout << " Your # in [1,10] is ";
cin >> num1;
}
else {
cout << "My number is " << num;
sum = num1 + num;
if (sum % 2 == 0){
cout << " I win!";
}
else {
cout << " You win!";
}
}
userTurn = !userTurn;
}
}
bool die(const string & msg){
cout << "Fatal error: " << msg << endl;
exit(EXIT_FAILURE);
}
Randomizing the number pc chooses is not working as every round in the game the pc chooses the same number.
You don't have code to re-set the value of num when it's the computer's turn.
After the line
userTurn = !userTurn;
add
if ( !userTurn )
{
num = rand() % 10 + 1;
}
Also i do not know how I would have the program summarize the score.
Keep two counters that indicate how many times the human won and how many times the computer won.
int computerWinCount = 0;
int humanWinCount = 0;
and then, update the loop to use:
if (sum % 2 == 0){
cout << " I win!";
++computerWinCount;
}
else {
cout << " You win!";
++humanWinCount;
}
The conditional of the while loop is such that your program will never terminate. Update it to something like below.
while (true) {
if (userTurn){
cout << " Your # in [1,10] is ";
cin >> num1;
// If the user entered a number that is not
// within range or the user did not input a number,
// then break out of the loop.
if ( !cin || num1 < 1 || num1 > 10 )
{
break;
}
}
else {
cout << "My number is " << num;
sum = num1 + num;
if (sum % 2 == 0){
cout << " I win!" << endl;
++computerWinCount;
}
else {
cout << " You win!" << endl;
++humanWinCount;
}
}
userTurn = !userTurn;
if ( !userTurn )
{
num = rand() % 10 + 1;
}
}
To report the summary, add the following lines before the end of the main.
cout << "Number of times I won: " << computerWinCount << endl;
cout << "Number of times you won: " << humanWinCount << endl;
Here:
num = rand() % 10 + 1;
while (num){
... // never change num
}
Do you see the problem? The computer player chooses num randomly, but only once. Just put another num = rand() % 10 + 1; inside the main loop.
(Also, you don't seem to have a way for the user to terminate the game.)
So you want a simple loop that will do the following things.
get the user input.
get the computer input
check to see who win's the current round
update scores.
this happens until the user chooses an option not from 1 to 10
after this you want to display the score.
Here is a complete example.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main(){
int mynum, compNum, myScore(0), compScore(0);
srand(time(NULL));
cout << "Welcome to the Odds and Evens game!" << endl;
cout << "Your # in [1,10] is ";
while ((cin >> mynum) && mynum > 0 && mynum <= 10){
compNum = rand()%10 + 1;
if ((mynum + compNum)%2){
cout << "You win" << endl;
++myScore;
} else {
cout << "Computer Wins" << endl;
++compScore;
}
cout << "Your # in [1,10] is ";
}
cout << "You won " << myScore << " games" << endl;
cout << "The computer won " << compScore << " games" << endl;
return 0;
}
Your problem with the computer's number not changing is due to the fact you do not update its value within the loop.
If you want to keep track of the score, you can simply keep two integers that keep track of how many times the user has won and how many times the computer has won. Then at the end (after the while loop) cout each of their scores.
Overall your code is pretty close.
You just need to make sure you update the computer's guess inside the while loop and when you decide who's won the round increment that person's score.
The whole loop condition in your original code will always evaluate to true. As num will always be to a number 1 to 10. You'll want to use the user's input in the while loop condition.
The while condition in my code will do the following:
get the user's input. cin >> mynum will evaluate to false if cin fails to read a number. If it did read a number the condition will check to see if the number is between 1 and 10 inclusive.

How could I exit from do-while loop?

I have these block of codes that belong to a NIM subtraction game. The thing that I would like to implement is that user is going to be able play the game as long as he/she wants. Simply if user enters 999 program will exit, otherwise user will be playing until he/she enters 999. Here is my block of codes. I am not sure that I make a logical mistake or I need to add some specific exit code. Thanks for your time and attention.
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int total, n;
while(true){
cout << "Welcome to NIM. \nEnter 999 to quit the game!\nPick a starting total: ";
cin >> total;
if(total==999)
break;
while(true){
//pick best response and print results.
if ((total % 3) == 2)
{
total = total - 2;
cout << "I am subtracting 2." << endl;
}
else
{
total--;
cout << "I am subtracting 1." << endl;
}
cout << "New total is " << total << endl;
if (total == 0)
{
cout << "I win!" << endl;
break;
}
// Get user’s response; must be 1 or 2.
cout << "Enter num to subtract (1 or 2): ";
cin >> n;
while (n < 1 || n > 2)
{
cout << "Input must be 1 or 2." << endl;
cout << "Re-enter: ";
cin >> n;
}
total = total - n;
cout << "New total is " << total << endl;
if (total == 0)
{
cout << "You win!" << endl;
break;
}
}
}
return 0;
}
You are modifying total inside the loop. Just test after cin>>total at the beginning if total==999 and break if true, i.e.
if(total==999)
break;
and replace the do-while loop by a while(true){}
In the do-while loop you are trying to compare character literal '999' with variable total that has type int.
}while(total!='999');
Though this code is valid its result can be something else than you are expecting. Values of character literals with more than one symbol are implementation defined.
You have to write
} while ( total != 999 );
Also if the player will enter 999 you start to play with him though you have to exit the game.
So in my opinion it is better to use while loop. For example
while ( true )
{
cout << "Welcome to NIM. \nEnter 999 to quit the game!\nPick a starting total: ";
cin >> total;
if ( total == 999 ) break;
// ...
}
you have to do three corrections in your code to make it right
first you have to check if total is equal to 999, then break in your do loop just after getting the total from user
second - you have to put same condition in your first while loop
and lastly - instead of while(total!='999') u shall write while(total!=999) because it is integer

while loop acting up... not doing what it should for some reason

I have this code for a simple Dice throwing program with betting units and everything... you bet, if you get it right you get the amount u bet times the amount of dice you chose... if you're wrong but by a little (in the range of the number you picked +- the number of dice u picked) you don't lose anything, and if you're really off you lose...
I have a while loop that basically keeps 2 things in mind: as long as the user either has BUs or if they didn't type "no" or "No" for the try again... but for some reason it just doesn't work... lol. any ideas why? the betting system works, it recognizes that betting.currentBU == 0, but the while loop just won't react lol.
#include <iostream>
#include <string>
#include <cstdlib>
#include <time.h>
#include <limits>
using namespace std;
struct Dices{ // structure containing all the dice related integers
int dice;
int total;
int choice;
} Dices = {0,0,0};
struct betting{ // structure containing all the betting integers
int currentBU;
int bettedBU;
} betting = {100, 0};
int DiceThrow(int dicechoice, int totalnum){ // a method for the dice being rolled
for(int i=1; i <= dicechoice;i++){
totalnum = totalnum + (rand() % 6 + 1); //total number, repeated by the loop for every dice
}
return totalnum;
}
int winningbet(int dicea, int cBU, int bBU){ // in case the user guesses it right
std::cout << "Congratulations, you got it right! \n";
cBU = cBU + (dicea * bBU); // give him money...
return(cBU);
}
int losingbet(int dicen, int totaln, int choicen, int cBU2, int bBU2){ //in case the user guesses wrong
if(choicen > (totaln+dicen) || choicen < (totaln+dicen)) // checks how wrong he is, if he's too off, he loses BUs
cBU2 = cBU2-bBU2;
else
std::cout << "you we're so close, you don't lose any BUs! \n"; //if he was really close, just let him know he was close
return(cBU2);
}
int main(){
string decision; // decision if they want to keep playing or not
srand ( (unsigned int)time(NULL) );
while(decision != "no" || decision != "No" || betting.currentBU != 0) // makes sure of the decision AND that he still has BUs
{
Dices.total = 0;
std::cout << "how many dice would you like to use? ";
std::cin >> Dices.dice;
std::cout << "how many How many BUs are you betting?(" << betting.currentBU << " BUs left) ";
std::cin >> betting.bettedBU;
if(betting.bettedBU > betting.currentBU){ // if he doesn't have enough BUs
std::cout << "Sorry, you don't have that many BUs...";
std::cout << "Want to try again with a different amount?(Yes/No) ";
std::cin >> decision;
}
else{
std::cout << "guess what number was thrown: ";
std::cin >> Dices.choice;
Dices.total = DiceThrow(Dices.dice, Dices.total);
if(Dices.choice == Dices.total){
betting.currentBU = winningbet(Dices.dice, betting.currentBU, betting.bettedBU);
std::cout << "Want to try again?(Yes/No) ";
std::cin >> decision;
} else{
std::cout << "Sorry, the number was " << Dices.total << "... better luck next time \n" ;
betting.currentBU = losingbet(Dices.dice, Dices.total, Dices.choice, betting.currentBU, betting.bettedBU);
if(betting.currentBU > 0){
std::cout << "Want to try again?(Yes/No) ";
std::cin >> decision;
}
}
}
}
if(betting.currentBU == 0){
std:cout << "sorry, you ran out of BUs...";
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
}
else{
std::cout << "your final BU count is: " << betting.currentBU << "\n";
std::cout << "Thanks for playing, see you next time! (Press ENTER to terminate...)";
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
}
return 0;
}
isn't it supposed to be:
while(decision != "no" && decision != "No" && betting.currentBU != 0)
We need to check if decision not equal to "no" AND not equal to "No" AND the currentBU not equal to 0
Your test is while (A || B || C), which will loop as long as ANY of those three things are true. Since decision can't be equal to both "no" and "No" at the same time, at least one of those two not-equals tests will always be true, so the loop will loop forever...