I have to write a Magic 8 ball program that will account for user input errors and I have to use a loop to do that.
boolean okay;
do {
System.out.printf("What is your question?\n");
questionStr = keyboard.nextLine();
int length = questionStr.length();
if (questionStr.length() == 0) {
System.out.println("Not allowed.");
okay = false;
} else if (!(questionStr.charAt(length - 1) == '?')) {
System.out.println("Add question mark.");
okay = false;
} else if (questionStr.length() > 60) {
okay = false;
}
okay = true;
} while (!okay);
When I run the code and make it an empty string, it does print out not allowed however it still runs the rest of the code and does not loop back and ask "What is your question?" The same happens with the question mark; it prints out "Add question mark" but does not loop back like it is supposed to. If I make a question longer than 60 characters, the code still executes and does not loop back and continue asking the user "What is your question?" until the code is less than 60 characters. I am trying to figure out what I am doing wrong here.
Move okay = true; before your if statements that negate it,
okay = true;
if (questionStr.length() == 0) {
System.out.println("Not allowed.");
okay = false;
} else if (!(questionStr.charAt(length - 1) == '?')) {
System.out.println("Add question mark.");
okay = false;
} else if (questionStr.length() > 60) {
okay = false;
}
As posted, you unconditionally set okay to true before your condition while (!okay); and thus the loop always ends.
Related
So i am trying to make a text based rpg game and what is supposed to happen here is when you activate a hunt by typing hunt it asks you yes or no. However even when i input yes, the you killed the boar message does not pop up. I am fairly new to java so sorry if the code is bad.
//Branches
if (ins.equals("branches") && loc.equals("forest")) {
System.out.println("You got a branch");
ib++;
} else if (ins.equals("branches") && !"forest".equals(loc)) {
System.out.println("You need to be in the forest to cut branches");
} else if (ins.equals("bcount")) {
System.out.println(ib);
}
//Branches
//Stones
if (ins.equals("stones") && loc.equals("mountains")) {
System.out.println("You got a stone");
is++;
} else if (ins.equals("stones") && !"mountains".equals(loc)) {
System.out.println("You need to be in the mountains to gather stones");
} else if (ins.equals("scount")) {
System.out.println(is);
}
//Stones
//Spears
if (ins.equals("spear") && is >= 1 && ib >= 1) {
System.out.println("+1 spear");
is--;
ib--;
ispear++;
} else if (ins.equals("spear") && is < 1) {
System.out.println("Insufficient resources");
} else if (ins.equals("spear") && ib < 1) {
System.out.println("Insufficient resources");
} else if (ins.equals("spearcount")) {
System.out.println(ispear);
}
//Spears
//Hunt
if (ins.equals("hunt") && ispear >= 1) {
System.out.println("A wild boar comes charging at you! Throw spear? (yes or no)");
if (ins.equals("yes")) {
System.out.println("You killed the boar!");
}
} else if (ins.equals("hunt") && ispear < 1) {
System.out.println("You dont have any spears");
}
}
If the while loop at the top controls the input then it is not possible for the code to get back to that inner if statements because ins cannot equal both "hunt" and "yes" at the same time. You need to do what #Spectric suggested in the comments and read the input again, or you need to use another way.
In the example below, we have used a boolean as a flag Boolean hunting = false;, and an OR condition || to allow us to get back inside the hunting section if (huting == true || ins.equals("hunt")....) then finally we need to make sure we trigger the flag on/off when hunting starts/ends like this hunting = true; or hunting = false;
Then all put together:
//Flag that allows us to trigger hunting
//This needs to be placed outside of the while loop
Boolean hunting = false;
//While loop that gets input and prints the next instruction
while (ins != null)
{
//Your code here to get the input
//...
//ins = scanner.nextLine();
//...
//Hunt
//add an or "||" condition so that if the hunting flag is true then we can get back inside this if statement:
if (hunting == true || ins.equals("hunt") && ispear >= 1)
{
//Set the hunting flag to true, so that we can get back to here in the next loop:
hunting = true;
System.out.println("A wild boar comes charging at you! Throw spear? (yes or no)");
if (ins.equals("yes"))
{
System.out.println("You killed the boar!");
//Reset the hunting flag so future commands don't break:
hunting = false;
}
//Make sure you have an else statement to set the hunting flag back to false
else
{
System.out.println("The boar ran away!");
//Reset the hunting flag so future commands don't break:
hunting = false;
}
}
else if (ins.equals("hunt") && ispear < 1)
{
System.out.println("You dont have any spears");
}
}
This question already has answers here:
How is if/while condition evaluated when we use assignments instead of comparison?
(4 answers)
How do I compare strings in Java?
(23 answers)
Closed 1 year ago.
This is my code.
import java.util.Scanner;
public class passwordProgram {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String correctPassword = "WooHoo";
int tries = 0;
boolean keepGoing = true;
while(keepGoing = true) {
tries = tries + 1;
System.out.println("try #" + tries);
String password;
System.out.println("Please enter the password: ");
password = scan.next();
if(password == correctPassword) {
System.out.println("This is the correct result:" + password);
keepGoing = false;
if(tries >= 3) {
System.out.println("Too many wrong tries. Exiting program");
keepGoing = false;
break;
}
}
}
}
}
The while loop doesn't end when the right password is entered, and it keeps repeating after the allowed number of attempts has been reached and I want to know why.
Is it because of the condition statement in the while loop or is there something else wrong with the code?
while (keepGoing = true)
this doesn't verify whether keepGoing is true, it sets it to true, so it remains true.
You should change it to:
while (keepGoing == true)
or, shorter:
while (keepGoing)
EDIT:
Another problem you have, is the way you compare your String values.
if(password == correctPassword)
The == operator is used to compare references of Objects, or primitive values, not the values of Objects.
What you want here, is:
if ( correctPassword.equals(password))
Here's a good read about that:
How do I compare strings in Java?
EDIT 2:
Your conditional statements shouldn't be nested. If they are, that means the second one will only execute if the first one evaluates to true:
if(correctPassword.equals(password)) { // already corrected
System.out.println("This is the correct result:" + password);
keepGoing = false;
if(tries >= 3) {
System.out.println("Too many wrong tries. Exiting program");
keepGoing = false;
break;
}
}
should be rewritten as:
if(correctPassword.equals(password)) { // already corrected
System.out.println("This is the correct result:" + password);
keepGoing = false;
}
if(tries >= 3) {
System.out.println("Too many wrong tries. Exiting program");
keepGoing = false;
break;
}
Your condition is an assignment, not a check.
Try changing it to while(keepGoing==true).
The '=' operator sets a value to a variable. The '==' operator compares values. A good practice it would be to just write the following statement:
while(keepGoing) {
...
}
You can just parse a boolean inside the 'while' statement and it will go on while the boolean is true.
In order to check a condition you should use "==" instead of "=" so the while statement should look like this:
while(keepGoing == true) {
...
}
I am currently learning java script and attempting new things, for example I wish to see if I can set a boolean expression to end if it detects a starting number through an ending number.
Or in other terms what I'll want is 3 through 8.
I will make it clear I am using netbeans IDE.
Within my last else if statement, I want it to end the asking process. I am hoping it is a simple fix, but I can not think of anything that will accomplish this unless I create a lot more else if statements.
Scanner input = new Scanner(System.in);
int[][] table;
boolean stopasking = true;
while (stopasking = true){
System.out.println("Let's make a magic Square! How big should it be? ");
int size = input.nextInt();
if (size < 0)
{
System.out.println("That would violate the laws of mathematics!");
System.out.println("");
}
else if (size >= 9)
{
System.out.println("That's huge! Please enter a number less than 9.");
System.out.println("");
}
else if (size <= 2)
{
System.out.println("That would violate the laws of mathematics!");
System.out.println("");
}
else if (size == 3)
{
stopasking = false;
}
}
You have used the assignmnent operator =
you should use == instead
also the condition size<=2 holds when size<0 so you can use one if for both
while(stopasking){
if (size <= 2) {
System.out.println("That would violate the laws of mathematics!\n");
} else if (size >= 9){
System.out.println("That's huge! Please enter a number less than 9.\n");
} else if (size == 3){
stopasking = false;
}
}
you can use the boolean expression in this way, as condition to exit from a loop. Some would say it is a more elegant solution than break.
do {
System.out.println("Set the A param: ");
if(input.hasNextDouble() == true) {
A = input.nextDouble();
if(A == 0) {
System.out.println("Param A cannot be a 0!");
}
} else if(input.hasNextDouble() == false) {
System.out.println("Param A must be a number!");
}
} while(A == 0 || input.hasNextDouble() == false);
Hello, I'm really new in Java and I found an obstacle I can't resolve by myself.
Everything is okay until I enter some letter instead of number, then this do..while loop keeps repeating itself.
After some search I suppose this might be a problem with a Scanner buffer becouse I should clear it before every loop with input.nextLine() but I don't really know where in code should I put it.
Thanks for any help.
You only actually consume data from the scanner if input.hasNextDouble() is true.
Currently, if A == 0 and there are non-numeric data in the buffer then you'll indeed loop indefinitely.
You need to consume data from the buffer on all control paths. In particular, if there is something non-numeric in the buffer, then you need to consume and immediately discard it: input.next(); would be adequate.
Seems like you just want to get the value of A which should not be equal to 0 . Read comments
double A=0;
do {
System.out.println("Set the A param: ");
if(input.hasNextDouble() == true) { //check for valid value
A = input.nextDouble();
if(A == 0) {
System.out.println("Param A cannot be a 0!");
}
} else{ // no valid value found , print msg and jump over the previous input
input.nextLine();
System.out.println("Param A must be a number!");
}
} while(A == 0); // just check , if the desired value is received
// previously input.hasNextDouble() had no use cuz we already
// checked no double value found so will be false, don't use it
First, you should not write the opposing check in an else if. Just use else. And you shouldn't check == true, since the value is already a boolean.
Now, for you infinite loop problem, when hasNextDouble() is false, it means that the user entered something wrong (ignoring the potential end-of-stream issue). In that case you need to discard that bad input, which is best done by calling nextLine().
Java naming convention states that variables should start with lowercase letter, so A should be a.
Your code then becomes:
double a = 0;
do {
System.out.println("Set the A param: ");
if (input.hasNextDouble()) {
a = input.nextDouble();
if (a == 0) {
System.out.println("Param A cannot be a 0!");
}
} else {
input.nextLine(); // discard bad input
System.out.println("Param A must be a number!");
}
} while (a == 0);
Thank you for both answers, after first I wrote this:
do
{
System.out.println("Podaj wartość parametru A: ");
if(input.hasNextDouble() == true)
{
A = input.nextDouble();
if(A == 0)
{
System.out.println("Parametr A nie może być zerem!");
}
}
else if(input.hasNextDouble() == false)
{
System.out.println("Parametr A musi być liczbą!");
input.nextLine();
A = 0;
}
} while(A == 0);
And it worked but thanks to the second answer now I know how to do it better. :)
Thanks both of you once again.
I'm trying to use a method to display an error message if the user enters a number other than 1 - 4, but I'm getting a missing return statement error.
public int CheckAnswers () {
boolean incorrectAnswer = true;
do {
playerAnswer = CheckAnswers();
if (playerAnswer < 1 || playerAnswer > 4) {
System.out.println("You have entered an incorrect number.");
System.out.println("Please enter a number between 1 and 4");
} else {
return (playerAnswer); }
} while (incorrectAnswer);
}
The error points to the last bracket. I've done some looking around online and I think the problem is that I don't have a return statement in both parts of the if-else statement. But if they have entered an incorrect number I don't want to return anything. I tried using the below code unsuccessfully.
public int CheckAnswers () {
boolean incorrectAnswer = true;
do {
playerAnswer = CheckAnswers();
if (playerAnswer < 1 || playerAnswer > 4) {
System.out.println("You have entered an incorrect number.");
System.out.println("Please enter a number between 1 and 4");
return (null);
} else {
return (playerAnswer); }
} while (incorrectAnswer);
}
The compiler's analysis does not determine that
do {
playerAnswer = CheckAnswers();
if (playerAnswer < 1 || playerAnswer > 4) {
System.out.println("You have entered an incorrect number.");
System.out.println("Please enter a number between 1 and 4");
} else {
return (playerAnswer); }
} while (incorrectAnswer);
is indeed an infinite loop, and the only way to get out of the loop is the return in the else branch. (Since incorrectAnswer cannot be changed except by cosmic rays flipping bits, it is, but the compiler isn't convinced.)
Thus it wants a return in case the loop is left in a different way.
If you make the loop condition a literal true,
do {
// code
} while(true);
the compiler will know that the loop can only be left via the return in the else branch (you can and should eliminate the boolean incorrectAnswer; then).
As yannis hristofakis observed, calling playerAnswer = CheckAnswers(); immediately in the loop causes an infinite recursion, and that will lead to a stack overflow. You need to call a method that obtains some input from the user instead there.
I'm amazed that 3 answers were posted and none of them mentioned that
It's an eternal procedure since you call recursevly the CheckAnswers method.
You can't return null for primitive return type methods.
I think you should skip the parenthesis.
return playerAnswer;
Just do a return statement of return -1 right after the do while.
You will not ever reach that code, but it will make the compiler happy who is not able to understand the logic of your code and just sees that there are possible execution paths that don't return anything.
public int CheckAnswers () {
boolean incorrectAnswer = true;
do {
playerAnswer = CheckAnswers();
if (playerAnswer < 1 || playerAnswer > 4) {
System.out.println("You have entered an incorrect number.");
System.out.println("Please enter a number between 1 and 4");
}
else {
return (playerAnswer);
}
} while (incorrectAnswer);
return -1; //unreachable statement
}
Try this:
public int CheckAnswers () {
boolean incorrectAnswer = true;
do {
playerAnswer = CheckAnswers();
if (playerAnswer < 1 || playerAnswer > 4) {
System.out.println("You have entered an incorrect number.");
System.out.println("Please enter a number between 1 and 4");
} else {
incorrectAnswer = false;
}
} while (incorrectAnswer);
return playerAnswer;
}