Logical OR does not work properly in the while loop - java

The problem is that, the first condition in the while loop does not get executed at all even if its true. If i remove the Logical OR from the while loop and just write the first condition (selection.compareToIgnoreCase("O") >0) it works fine. But if there are two conditions with Logical OR, it does not work.
I've tried using equals(), I've also tried to negate the logic using
while(!selection.equals("O") || !selection.equals("E")). The second condition works fine but the first does not work at all.
public class OddsOrEvens {
public static Scanner sc = new Scanner(System.in);
public static void main(String[] args){
System.out.println("Let’s play a game called \"Odds and Evens\"");
System.out.println("Whats your name ? ");
String name = sc.nextLine();
System.out.println("Hi "+ name +", which do you choose? (O)dds or (E)vens?");
String selection = sc.nextLine();
System.out.println("selection: " + selection);
while (selection.compareToIgnoreCase("O") >0 || selection.compareToIgnoreCase("E") >0){
System.out.println("Please enter the correct choice. Select 'O' for odds or 'E' for evens");
selection = sc.next();
}
if(selection.equalsIgnoreCase("O")){
System.out.println(name + " has picked Odds! The computer will be evens.");
}else if (selection.equalsIgnoreCase("E")){
System.out.println(name + " has picked Evens! The computer will be Odds.");
}
}
}

Your string comparison is not correct. Compareto returns -1/0/1 for less/equal/greater.
A clearer way to do this is to use toUppercase().equals(....
while (!selection.toUpperCase().equals("O") && !selection.toUpperCase().equals("E")){

That is for not to hold for two cases, one needs !... && ! ... An OR || would have the effect of being always true, as at least one of the cases is false. Alternatively !(... || ...).
while (!selection.equalsIgnoreCase("O") && !selection.equalsIgnoreCase("E")) {
Let's simplify:
!(n == 1) || !(n == 2) // WRONG
n != 1 || n != 2 // WRONG
will always be true, as either n == 1 is false or n == 2 is false: at most one choice can be true, falsifying the others. So on at least on side is !false, true, so the entire expression is true.
!(n == 1) && !(n == 2) // GOOD
n != 1 && n != 2 // GOOD
The mental mistake is that the linguistic OR mostly means EXCLUSIVE OR.
Possible would have been the equivalent:
!(n == 1 || n == 2) <=> n != 1 && n != 2 [De Morgan's law]

Related

While loop not working according to the condition in Java

I am trying to build a Number guessing game which has a while loop with 2 conditions in it. However even after 1 of those 2 conditions become false then also the loop keeps going on even though I have || operator between those conditions. Also if I clear out the first condition of while loop then the second one works just perfectly as I want it to but if it is present then idk why it doesn't stop. Here is my code:
import java.util.Random;
import java.util.Scanner;
public class NumberGuess {
public static void main(String args[]) {
Random num = new Random();
int number = 1 + num.nextInt(10);
Scanner inp = new Scanner(System.in);
boolean guessed = false;
System.out.println("Welcome to Number guess!");
int guess_count = 5;
while(guessed == false || guess_count > 0 ) {
System.out.print("Enter your guess: ");
int input = inp.nextInt();
if(input == number) {
System.out.println("You guessed it right!");
guessed = true;
}
else {
System.out.println("Nope!");
guessed = false;
guess_count--;
System.out.println("Guesses left: " + guess_count);
}
}
}
}
When counter goes below 0 then also the loop keeps going on but I don't want it to.
Please tell me where am I wrong.
You don't need an OR operator. What you need is an AND operator. Means your condition should be (guessed == false && guess_count > 0 ).
WHY?
Because the OR conditional operator works if either the condition is true, in your case if the user unable to guess 5 times then your guessed variable is still false while your guess_count is less than zero, so your one condition is true. The AND operator checks for both the condition.
The condition of your while loop should be changed from an OR || to an AND &&. Currently, the || will allow execution if either guessed == false OR guess_count > 0. Only one of these conditions must be true for the while loop to continue executing.
while(guessed == false && guess_count > 0 ) {
Change to an AND && means that if the number is guessed correctly, guessed will now be true and the while loop will halt after that iteration. I was not getting any errors for when the guess_counter dropped below zero. Try it again to be sure.
Consider modifying your loop like this:
while(guess_count > 0 ) {
System.out.print("Enter your guess: ");
int input = inp.nextInt();
if(input == number) {
System.out.println("You guessed it right!");
break;
}
else {
System.out.println("Nope!");
guessed = false;
guess_count--;
System.out.println("Guesses left: " + guess_count);
}
}
OR just modify you condition like this:
while(!guessed && guess_count > 0 ) {
You can correct your code by replacing || with &&. Why use an extra flag variable when you have guess_count decrementing to check for number of guesses. The program will terminate after guessed number is equal to the input. Here is simple implementation:
while(guess_count-->0) {
System.out.print("Enter your guess: ");
int input = inp.nextInt();
if(input == number) {
System.out.println("You guessed it right!");
guessed = true;
break; // The user has already guessed the number no need to guess more
}
else
System.out.println("Nope!\nGuesses left: " + guess_count);

When I enter A, B, C, or D, it still says That is not a valid answer. Why?

This is my project for school. We were asked to make a little quiz and I want to make sure when the user enters something outside of the options, they will get an error message saying that is not a valid answer, but whatever I enter it still says that is not valid. Why?
import java.util.Scanner;
class Main {
public static void main(String[] args) {
String answer;
int score = 0;
Scanner input = new Scanner(System.in);
System.out.println("ALL SUBJECT QUIZ Starting now, please enter the correct option (Letters or T or F) for the next 10 questions");
System.out.println("Question 1 (Maths): What is the vertex of the equation y=2(x-2)^2+5");
System.out.println("A. (-2,5)" + "\n" + "B. (2, 5)" + "\n" + "C. (-2,-5)" + "\n" + "D. (2, -5)");
answer = input.nextLine();
answer = answer.toUpperCase();
while (!answer.equals("A") || !answer.equals("B") || !answer.equals("C") || !answer.equals("D")) {
System.out.println("That is not a valid response");
answer = input.nextLine();
answer = answer.toUpperCase();
}
if (answer.equals("A")) {
System.out.println("Incorrect, the answer is B");
} else if (answer.equals("B")){
System.out.println("Correct");
score += 1;
} else if (answer.equals("C")){
System.out.println("Incorrect, the answer is B");
} else if (answer.equals("D")){
System.out.println("Incorrect, the answer is B");
}
}
}
Any help would be appreciated!
Let's evaluate your following condition:
!answer.equals("A") || !answer.equals("B") || !answer.equals("C") || !answer.equals("D")
Assume, answer = E
Now, your condition will be evaluated as
true || !answer.equals("B") || !answer.equals("C") || !answer.equals("D") => true
Note that when multiple conditions are joined with ||, the evaluation stops as soon as a true condition is found.
Assume, answer = B
Now, your condition will be evaluated as
true || !answer.equals("B") || !answer.equals("C") || !answer.equals("D") => true
Assume, answer = A
Now, your condition will be evaluated as
false || true || !answer.equals("C") || !answer.equals("D") => true
Thus, you see that irrespective of the answer, the condition always evaluates to true.
Solution:
Change it to
while (!(answer.equals("A") || answer.equals("B") || answer.equals("C") || answer.equals("D")))
which means the answer is not (A, or B, or C, or D)
Alternatively, you can change it to
while (!answer.equals("A") && !answer.equals("B") && !answer.equals("C") && !answer.equals("D"))
which means the answer is not A and the answer is not B and the answer is not C and the answer is not D.
However, for the sake of simplicity, my taste is the first one.
If you look at your while loop condition, you will notice that it will always evaluate to true because the user input can't equal A, B, C, and D all at once.
So the solution here is to change the or's (||) in the condition to and's (&&) since you want the user input to be only one of the following: A, B, C, or D.
while (!answer.equals("A") && !answer.equals("B") && !answer.equals("C") && !answer.equals("D")) {
System.out.println("That is not a valid response");
answer = input.nextLine();
answer = answer.toUpperCase();
}

Why is my program entering a while loop when the condition is false?

When I input a string operator whether it be addition(+), subtraction(-), multiplication(*), division(/) or module(%), it still enters the while loop even when I enter a valid input. I don't know what the problem could be because the while loop is working fine where I have to enter an int-value for variable num2.
import java.util.Scanner;
public class PolishNotationCalc {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int num1;
int num2;
String operator;
System.out.println("Polish notation calculator");
System.out.print("Please enter an operation(+, -, *, /, %) ");
operator = input.nextLine();
while (!operator.equals("+") || !operator.equals("-") || !operator.equals("*") || !operator.equals("/") || !operator.equals("%")) {
System.out.println("Please enter a valid operation ");
operator = input.nextLine();
if (operator.equals("+") || operator.equals("-") || operator.equals("*") || operator.equals("/") || operator.equals("%"))
break;
}
System.out.print("");
System.out.print("Please enter the first number ");
num1 = input.nextInt();
System.out.print("Please enter the second number ");
num2 = input.nextInt();
while (num2 == 0 && operator.equals("/")) {
System.out.println("Please pick a non zero number: ");
num2 = input.nextInt();
}
while (num2 == 0 && operator.equals("%")) {
System.out.println("Please pick a non zero number: ");
num2 = input.nextInt();
}
if (operator.equals("+"))
System.out.println(num1 + " + " + num2 + " = " + (num1 + num2));
else if (operator.equals("-"))
System.out.println(num1 + " - " + num2 + " = " + (num1 - num2));
else if (operator.equals("*"))
System.out.println(num1 + " * " + +num2 + " = " + (num1 * num2));
else if (operator.equals("/"))
System.out.println(num1 + " / " + num2 + " = " + (num1 / num2));
else if (operator.equals("%"))
System.out.println(num1 + " % " + num2 + " = " + (num1 % num2));
}
}
if you write your boolean selection in english it reads "While the operator does not equal "+" or it does not equal "-" or it does not equal "/" or it does not equal "*" or it does not equal "%" do the loop.
You need it to say "While the operator does not equal "+" AND it does not equal "-" AND it does not equal "/" AND it does not equal "*" AND it does not equal "%" do the loop.
Change || to && and it should work
For a while loop to be enacted all the parameters need to be true. So if one of the parameters is false, the while loop does not activate.
operator is always not equal to at least one of these strings: e.g. if it is equal to +, then it's not equal to -. If you combine one or more true conditions with ||, the overall result will be true.
You need to use && instead of ||, so that the loop breaks if any one of the conditions match:
while (!operator.equals("+") && !operator.equals("-") && ... ) {
You then don't need to check the value of operator again inside the loop; just let the new loop guard check it and break.
A more syntactically concise alternative would be to use a collection:
List<String> allowedOperators = Arrays.asList("+", "-", "*", "/", "%");
while (!allowedOperators.contains(operator)) {
System.out.println("Please enter a valid operation ");
operator = input.nextLine();
}
Similarly, when you are checking for num2 == 0:
List<String> zeroDenominatorOps = Arrays.asList("/", "%");
if (zeroDenominatorOps.contains(operator)) {
while (num2 == 0) {
// ...
}
}
while (!operator.equals("+") || !operator.equals("-") || !operator.equals("*") || !operator.equals("/") || !operator.equals("%")) {
System.out.println("Please enter a valid operation ");
operator = input.nextLine();
if (operator.equals("+") || operator.equals("-") || operator.equals("*") || operator.equals("/") || operator.equals("%"))
break;
}
For example when you enter "+" it becomes while(false || true|| true || true). so it always goes into while loop
You should substitute the || (or) with && (and)
SO
while (!operator.equals("+") || !operator.equals("-") || !operator.equals("*") || !operator.equals("/") || !operator.equals("%")) {
Becames
while (!operator.equals("+") && !operator.equals("-") && !operator.equals("*") && !operator.equals("/") && !operator.equals("%")) {
EDIT
You need an AND not an OR.
Lets say you input "+",which is a valid operator.
You'll enter the while because "+" NOT EQUALS "-", your second condition. This because the while conditions are in OR.
If you put these conditions in AND (&&), the "+" does not enter the while because one of the conditions is not true ( !operator.equals("+") )
Try this by changing ! to the whole parameters inside the while loop,It will start working
while (!(operator.equals("+") || operator.equals("-") || operator.equals("*") || operator.equals("/") || operator.equals("%"))) {
System.out.println("Please enter a valid operation ");
operator = input.nextLine();
if ((operator.equals("+") || operator.equals("-") || operator.equals("*") || operator.equals("/") || operator.equals("%")))
break;
}
It's simple math that sometimes people just forgets.
Lets simplify the cases.
1 OR x = 1;
1 AND x = x;
Lets be more concrete. Let we have some variable, A, B and C.
In the first case, OR, we have:
Which means that if at least one is true, the all expression is true. In you case having one operation that does not appear means that the loop must be true. Therefore, you should put something like this:
Which means not A AND not B AND not C.
I hope I have helped.
Have a nice day. :)
The loop condition has a different meaning than you thought. It's always true for any input string. It's the kind of condition that you will never have to write (hopefully).
To understand this better, let's first define when an operator can be accepted, in English:
An operator is accepted if it's one of the five operators: +, -, *, /, %
"One of" basically means "or". Therefore the corresponding code is
operator.equals("+") ||
operator.equals("-") ||
operator.equals("*") ||
operator.equals("/") ||
operator.equals("%")
And we can wrap it in a method:
private static boolean acceptable(String operator) {
return operator.equals("+") ||
operator.equals("-") ||
operator.equals("*") ||
operator.equals("/") ||
operator.equals("%");
}
Now the read-check-loop logic is very simple:
String operator;
do {
System.out.println("Please enter a valid operation ");
operator = input.nextLine();
} while (!acceptable(operator));
#SaclyrBarlonium, this is what I'm talking about. :P
Side Note
IMHO, every programmer should know De Morgan's laws so well that they can instinctively detect logical inconsistencies in the code. The inconsistency in this case is between the loop condition and the if statement in the loop body. If we put them side-by-side, we know that they are not equivalent, according to De Morgan's Law:
!operator.equals("+") || !operator.equals("-") || !operator.equals("*") || !operator.equals("/") || !operator.equals("%")
operator.equals("+") || operator.equals("-") || operator.equals("*") || operator.equals("/") || operator.equals("%")
But they should be equivalent, because the intent are the same: to continue the loop when the user entered a invalid operator and to terminate otherwise.

While loop one condition always returning true?

I am trying to make a conditional statement with two "ifs", and it works when I input the correct thing, but when I input an incorrect pokemon and a correct level it still works. I am pretty sure that one of the conditions in my while statement is always true (the first part). Here is the code (sorry about the formatting, just know that it is all formatted correctly in the Java environment):
while ((!(Pokemon.equalsIgnoreCase(Pikachu)) || !(Pokemon.equalsIgnoreCase(Charmander)) || !(Pokemon.equalsIgnoreCase(Squirtle)) || !(Pokemon.equalsIgnoreCase(Bulbasaur))) && !((Level <= 15)&&(Level >= 1 ))) {
System.out.println();
System.out.println("Which one would you like? What level should it be?\n1 to 15 would be best, I think.");
Pokemon = sc.next();
Level = sc.nextInt();
if ((Level <= 15) && (Level >= 1)) {
if ((Pokemon.equalsIgnoreCase(Pikachu)) || (Pokemon.equalsIgnoreCase(Charmander)) || (Pokemon.equalsIgnoreCase(Squirtle)) || (Pokemon.equalsIgnoreCase(Bulbasaur))) {
System.out.print("Added level " + Level + " " + Pokemon + " for " + Trainer + ".");
}
else {
System.out.println("Invalid Pokemon!");
}
}
else {
System.out.println("Invalid Level!");
}
}
Pokeman will always be either not X or not Y, it's basic logic since if it's X, then not-Y is true. If it's Y, then not-X is true. If it's neither then both will be true.
Change || to && and think through your logic on paper.
Should be:
while ((!(Pokemon.equalsIgnoreCase(Pikachu)) &&
!(Pokemon.equalsIgnoreCase(Charmander)) &&
!(Pokemon.equalsIgnoreCase(Squirtle)) &&
!(Pokemon.equalsIgnoreCase(Bulbasaur))) &&
!((Level <= 15)&&(Level >= 1 )))

Java while loop and other

I need help I am new to Java programming and I don't know how to fix my code.
I am trying to make a 007 game. I have created the if statements and it isn't looping around. If I add a ! in front of the each statement in the do-while loop it causes a infinity loop.
How can I fix my programming.
import java.util.Scanner;
import java.util.Random;
public class DoubleOSeven {
public static void main(String[] args) {
System.out.println("Let's Play a game of 007 ");
System.out.println("You can SHOOT, BLOCK, AND RELOAD");
System.out.println("Both you and I start with one bullet");
Scanner input = new Scanner(System.in);
System.out.println("Let's Start, Enter (shoot, reload , or block) ");
String INput = input.nextLine();
//User and Computer ammo
int Userammo = 1;
int ammo = 1;
//Creates a random number between 1 and 3
Random rand = new Random();
int output = rand.nextInt(3) + 1;
do{
//User chooses shoot
if(INput.equals("shoot")){
Userammo --;
System.out.println("You took a shot, Your ammo count is at: " + Userammo);
//User chooses reload
}else if (INput.equals("reload")){
Userammo ++;
System.out.println("You reloaded, Your ammo count is at: " + Userammo);
//User chooses block
}else if(INput.equals("block")){
System.out.println("You blocked, Your ammo count is at: " + Userammo);
//If random is 1 shoot
}if(output == 1){
ammo ++;
System.out.println("I took a shot at you, My ammo count is at: " + ammo);
//If random is 2 block
}else if(output == 2){
System.out.println("I blocked, My ammo count is at: " + ammo);
//If random is 3 reload
}else if(output == 3){
ammo ++;
System.out.println("I reloaded, My ammo count is at: " + ammo);
//If both User and Computer shoot
}if(output == 1 && INput == "shoot"){
System.out.println("It's a tie you we both die");
}
}while((output == 3 && INput == "shoot") && (output == 1 && INput == "reload") && (output == 1 && INput == "shoot"));
}
}
while((output == 3 && INput == "shoot") && (output == 1 && INput == "reload") && (output == 1 && INput == "shoot"));
should be
while((output == 3 && INput.equals("shoot")) || (output == 1 && INput.equals("reload")) || (output == 1 && INput.equals("shoot")));
First of all: In order for the loop to work well, the question to the user and the computer random decision have to be inside the loop. In this way each loop has a new set of values for the variables.
// Declare variables
String INput = "";
Random rand = new Random();
int output = 0;
do{
// Ask user
System.out.println("Enter (shoot, reload , or block) ");
INput = input.nextLine();
// Computer decision
output = rand.nextInt(3) + 1;
...
Second: You need to have an explicit decision when to terminate the loop (ie the game). This can be done with one of the following
the user wants to end the game (that needs one more option quit in the user choices)
the computer wants to end the game (that needs a forth random number that means quit).
some condition from the combination of user/computer ammo and user/computer shoot. That is you can end the game if some player is shot and has zero ammo.
In all these cases you need to
declare a variable for the end of the game before the loop
decide what to do in the loop
continue the loop if not end of game
This is snippet for this:
boolean endOfGame = false;
...
do {
...
if ( INput.equals("quit")
|| (INput.equals("shoot") && ammo == 0)
|| (Userammo == 0 && output == 1) ) {
endOfGame = true;
}
...
} while (!endOfGame);
You could have the same efect if you put the decision in the while,
but in this way the decision for the end of game is more clear.
It is also possible to set the endOfGame to true in many different places in the loop.
Edit: Some notes on coding style etc
It is a common good practice the names of the variables to start with low case letters (eg instead of Userammo use userAmmo). Names starting with capital letters denote classes.
It makes the code easier to read if the names have some meaning. For example I would suggest the following changes for some of your variables
INput → userAction
Userammo → userAmmo
output → compAction
ammo → compAmmo
Use final constants to give meaning to numbers or strings that appear in your code repeatedly.
Start the if statement on a new line. (else if on the same line is ok)
Using these you could have written (and some comments are not needed)
public class DoubleOSeven {
public static final String S_SHOOT = "shoot";
public static final String S_BLOCK = "block";
public static final String S_RELOAD = "reload";
public static final int I_SHOOT = 1;
public static final int I_BLOCK = 2;
public static final int I_RELOAD = 3;
...
System.out.println("Enter ("+ S_SHOOT + ", " + S_RELOAD + " or " + S_BLOCK + ") ");
...
} else if(userAction.equals(S_BLOCK)){
System.out.println("You blocked, Your ammo count is at: " + userAmmo);
}
if(compAction == I_SHOOT){
compAmmo--; // I changed ++ to -- in order to be a fair game
System.out.println("I took a shot at you, My ammo count is at: " + compAmmo);
} else if(compAction == I_BLOCK){
System.out.println("I blocked, My ammo count is at: " + compAmmo);
...
As per your condition as below
while((output == 3 && INput == "shoot") && (output == 1 && INput == "reload") && (output == 1 && INput == "shoot"));
the loop will be executed only if the 3 conditions are true.
You need to make some changes in your condition
All your && cases that are evaluated for this loop result in a false.
Let's say, T for all true cases and F for all F cases
If T&&T&&T then yes we = T (the case for adding !)
If T&&F&&F then F
IF F&&T&&F then F
...
IF F&&F&&F then F
So you need to re-evaluate what condition you want to cause to loop.
Are we looking for
(output==3 && Input=="shoot") || (output==1 && input=="reload") || (output==1 && input=="shoot")
to cause the next iteration?
This would make the case, where any of them are T, we get T. If all of them are F, then we get F.

Categories

Resources