I'm having an issue with booleans apparently, textbased game - java

Scanner sc = new Scanner (System.in);
String enter = new String ("Enter your name brave soul: ");
System.out.println (enter);
String name = sc.next();
System.out.println ("Your name is: " + name + "? Y/N");
boolean y = true;
boolean n = false;
String yesorno = sc.next();
String intro1 = new String ("Welcome to Urieka! The objective of this game is quite simple, just find the key to escape.");
if (true) {System.out.println (intro1);} //here
else if (false) {System.out.println (enter);} //here
I'm having a problem, I want to print intro1 if the user inputs y and I want the prompt to enter the name if they input it incorrectly. Its currently ONLY printing intro1 regardless if I input y or no.
Furthermore, is there a way for me to run that scanner again because I assume that if I DO get this working and the user inputs n/false, then it would just print "Enter your name brave soul" and nothing else. Would I somehow have to add a scanner into the statement on the else if line?

if (true) {System.out.println (intro1);} //here
this is always true and will always run. The else will likewise never run.
You want instead
if ("y".equalsIgnoreCase(yesorno)) {
//...
}

Well... true is always true so
if (true) { ... }
will always be executed. You should do something like :
System.out.println("y".equalsIgnoreCase(yesorno) ? intro1 : enter);

You never change these booleans:
boolean y = true;
boolean n = false;
Also try to avoid usage of if(true), as mentioned in previous post:
if (true) {System.out.println (intro1);} //here
It is not mandatory to use a constructor when instantiating a String object:
String enter = new String("Enter your name brave soul: ");
// IS THE SAME AS <=>
String enter = "Enter your name brave soul: ";
Here is my solution of your problem:
Scanner scanner = new Scanner(System.in);
boolean correctName = false;
String name = "";
while(!correctName){ //== Will run as long "correctName" is false.
System.out.println("Enter your name brave soul: ");
name = scanner.next();
System.out.println("Your name is: " + name + "? Y/N");
String yesorno = scanner.next();
correctName = "Y".equalsIgnoreCase(yesorno); //== changes the boolean depending on the answer
}
System.out.println("Welcome to Urieka" + name + "! The objective of this game is quite simple, just find the key to escape.");

If (true) means that it will always enter the if condition and it will always print intro01 as it's doing.
The else condition will never be reached.
your condition should be something like:
if("y".equalsIgnoreCase(yesorno))
System.out.println (intro1);
else
System.out.println (enter);

Related

Java duplicate local variable. Stumped

I am brand new to coding and trying to get my second program working. It is pretty straight forward as to what it does, but it is throwing an error on line 24 "Duplicate local variable confirm". Can't quite work out why it doesn't like what I'm doing.
Scanner userInput = new Scanner(System.in);
char confirm;
do{
System.out.println("Welcome to the story teller");
System.out.println("What is your name?");
String name = userInput.nextLine();
System.out.println("How old are you?");
int age = userInput.nextInt();
System.out.println("What country would you like to visit?");
String country = userInput.nextLine();
System.out.println("Great! So your name is" + name + ", you are" + age + "years old and you would like to visit" + country + "?");
System.out.println("Press Y to continue or N to start over");
char confirm = userInput.next().charAt(0);
if (confirm !='y' || confirm !='n'){
System.out.println("Sorry that input is not valid, please try again");
}
else {
System.out.println(name + "landed in" + country + "at the age of" + age + ".");
}
} while(confirm == 'Y'|| confirm == 'y');
You're declaring confirm twice. Change the second declaration to just assigning to it and you should be OK:
confirm = userInput.next().charAt(0);
// No datatype, so you aren't declaring confirm, just assigning to it
Because your "confirm" variable already defined in the scope (second row). If you want to assign a value, just write confirm = userInput.next().charAt(0);
Another option to fix is to remove the unnecessary declaration char confirm;
And use it only when needed
char confirm = userInput.next().charAt(0);
As #ScaryWombat suggested, you will need to change scope of the variable (currently while is in different scope than do )
It seems apart from re-declaration of the variable confirm there are one or more issue -
Issue 1:
After int age = userInput.nextInt(). It won't prompt for country input and will prompt Press Y to continue or N to start over.
Cause of this issue:
Since you are using int age = userInput.nextInt(); the scanner will only take the integer value from the input and will skip the \n newline character.
Fix
As a workaround, I've added userInput.nextLine(); after int age = userInput.nextInt(); such that it will consume the \n character after nextInt().
Issue 2:
After the 1'st iteration, this line will cause issueconfirm = userInput.next().charAt(0);.
Cause of this issue:
In 2'nd iteration you won't get a prompt to enter the name as the line String name = userInput.nextLine(); will take \n from the last iteration as input and will skip and prompt for age How old are you?.
Fix
As a workaround, I've added userInput.nextLine(); after confirm = userInput.next().charAt(0); such that it will consume the \n character after userInput.next().charAt(0) and the next iteration will go as expected.
Issue 3:
This logic if (confirm !='y' || confirm !='n') expects only y and n in lowercase but here while(confirm == 'Y'|| confirm == 'y') you are expection y and Y both.
Fix - I've added the necessary changes in the code below but would recommend you do change it to a switch case.
NOTE:
It is not recommended to do userInput.nextLine() after every input and you could simply parse it. See here for further information.
I'm not recommending it but this will get you program working
Scanner userInput = new Scanner(System.in);
char confirm;
do {
System.out.println("Welcome to the story teller");
System.out.println("What is your name?");
String name = userInput.nextLine();
System.out.println("How old are you?");
int age = userInput.nextInt();
userInput.nextLine(); //adding this to retrieve the \n from nextint()
System.out.println("What country would you like to visit?");
String country = userInput.nextLine();
System.out.println("Great! So your name is " + name + ", you are " + age
+ "years old and you would like to visit " + country + " ?");
System.out.println("Press Y to continue or N to start over");
confirm = userInput.next().charAt(0);
userInput.nextLine(); //adding this to retrieve the \n this will help in next iteration
System.out.println(name + " landed in " + country + " at the age of " + age + ".");
if (confirm == 'y' || confirm == 'Y') {
continue; // keep executing, won't break the loop
} else if (confirm == 'n' || confirm == 'N') {
break; // breaks the loop and program exits.
} else {
System.out.println("Sorry that input is not valid, please try again");
// the program will exit
}
} while (confirm == 'Y' || confirm == 'y');
}
Recommending that you use switch case instead of if comparasion of confirmation and parse the character and integer input and remove the arbitary userInput.nextLine() added as workaround.

How to add an EFFICIENT loop that will allow this program to loop or terminate?

So I am creating simple program for my Java class and one of the last requirements is to have the program loop. I've done this before, but it was horribly inefficient and convoluted.
Basically, I used a switch case named start with values 0 and 1. If the user typed 0 a do-while loop would begin and if they typed 1, the program would terminate. The only problem with this is the user would have to type 0 for the program to even begin, and if they typed 1, I had to have a fail-safe changing the value of start to 3 or else an infinite loop would begin. Can someone help me find a better way of doing this? (Also, before anyone says anything about the way it is written, one of the requirements was that it HAD to be done within one executable class.)
(Also, Also: Could someone tell me the rules of indentation? I'm really horrible at it.)
Here is my code below:
/*
* Simple Java Survey Program
*/
import java.util.Scanner;
public class J2Strings {
public static void main(String[] args) {
// TODO Auto-generated method stub
// variables
String fName;
String lName;
String mName;
int age;
String say;
String fFood;
String fTV;
Scanner userInput = new Scanner(System.in);
System.out.println("Today you are going to take a small personal survey");
System.out.println("");
System.out.println("Begin by entering your first name: ");
fName = userInput.next();
System.out.println("Enter your last name:");
lName = userInput.next();
System.out.println("Enter your middle name:");
mName = userInput.next();
System.out.println("Enter your age:");
age = userInput.nextInt();
System.out.println("Enter your favorite saying:");
say = userInput.next();
System.out.println("Enter your favorite food:");
fFood = userInput.next();
System.out.println("Finally, enter your favorite TV show:");
fTV = userInput.next();
char f = fName.charAt(0);
char l = lName.charAt(0);
char m = mName.charAt(0);
System.out.println("Based on the information you entered, here are your initials: " + f + "." + m + "." + l);
System.out.println("This is how old you will be in 50 years: " + (age + 50));
}
}
Something like this
bool test = true;
while(test)
{
/*Your code here */
/*At the end you ask them if they want to try again*/
/*Then switch the boolean based on their answer*/
}

Simulating multiple user input junit

I am trying to write a junit test to test a method that takes multiple user input.
The method takes a person object and sets a rating for them, the first user input is a double value for the rating, the second input is a string with the value "Y" to confirm the change.
I am trying to use ByteArrayInputStream but it is not getting the second input, the error I am getting when i run the test is No line found.
I have identified the problem as I am using different methods to validate user input I have to create a new scanner each time so the second line is not being accepted
Is there a way to set the Scanner again for the second input?
This is my test code
Person p = new Person();
double input1 = 54.3;
String input2 = "Y";
String simulatedUserInput = input1 +
System.getProperty("line.separator")
+ input2 + System.getProperty("line.separator");
System.setIn(new ByteArrayInputStream(simulatedUserInput.getBytes(StandardCharsets.UTF_8)));
addRating(p);
assertEquals(54.3, p.getMyRating(),0);
The method for adding the rating looks like this
public static void addRating(Person p)
{
double rating = Validation.validateRating("Please enter a rating for " + p.getName()); // validate input of double
boolean confirmed = Validation.validateYesNo("Are you sure you wish to set " + p.getName() + "'s rating to " + rating + " Y/N");// confirm yes no
if (confirmed)
{
p.setMyRating(rating);
}
}
Then I have a validation class to ensure correct user input,
This is for the rating
public static double validateRating(String str)
{
Scanner in = new Scanner(System.in);
double d = 0;
boolean valid = false;
while (!valid)
{
System.out.println(str);
if (!in.hasNextDouble())
{
System.out.println("Not a valid number");
in.nextLine();
} else
{
d = in.nextDouble();
if(d>=0 && d<=100)
{
valid = true;
}
else
{
System.out.println("Rating must be between 0 and 100");
}
}
}
return d;
}
this is for confirming Y/N input
public static boolean validateYesNo(String str)
{
Scanner in = new Scanner(System.in);
boolean YesNo = false;
boolean valid = false;
while (!valid)
{
System.out.println(str);
String choice = in.next();
if (choice.equalsIgnoreCase("Y"))
{
valid = true;
YesNo = true;
} else if (choice.equalsIgnoreCase("N"))
{
valid = true;
YesNo = false;
} else
{
System.out.println("Invalid input");
}
}
return YesNo;
}
You get unit testing wrong. You don't write your production code first; to later discover: this is really hard to test.
Instead: right from the beginning, you strive to write code that is as easy as possible. Ideally, you even write testcases before you write production code.
Because that helps you discovering the abstractions you need. In your case: in order to validate input values within your Person class, it should not be important, where those values are coming from.
In other words: you do not never ne jamais put System.in read calls into your production classes. You might have a test main method that reads values from the console; but you always pass such values into a method as parameter. If at all, you pass an instance Reader into your classes. You do not turn to System.in inside your methods!

What am I missing here? Looping with dialog boxes

I am not sure why this code is not working.
I am suppose to have another dialog box appear after the user selects yes or no, but whenever I run the program, it asks for y or no and then nothing happens after.
Any ideas on what I need to do?
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int max = 0;
int min = Integer.MAX_VALUE;
String number;
boolean yn = true;
do {
number = JOptionPane.showInputDialog("Please enter a number");
int num = Integer.parseInt(number);
if (num > max) {
max = num;
}
if (num < min) {
min = num;
}
System.out.println(min + " " + max);
JOptionPane.showInputDialog("Would you like to enter another number? (y/n)");
String ny = in.nextLine();
if (ny.equals("n")) {
yn = false;
}
JOptionPane.showInputDialog(ny);
} while (yn == true);
JOptionPane.showMessageDialog(null, "The max number is " + max + " and the mininum number is " + min);
}
}
The program stops on
String ny = in.nextLine();
waiting for input from System.in based on the Scanner defined on the first line.
If you enter 'n' on the console and press enter then the program carries on and shows the next dialog box.
I guess you meant to say:
String ny = JOptionPane.showInputDialog("Would you like to enter another number? (y/n)");
The issue you are having is that you are not accepting the input from the panel, and are instead taking it from the console. To solve this, set ny to be equal to the input from the JPane, like so:
String ny = JOptionPane.showInputDialog("Would you like to enter another number? (y/n)");
However, there is another issue, which is this line:
JOptionPane.showInputDialog(ny);
It creates a pane that you don't need that displays y or n, and doesn't accept input. This line doesn't need to be there, so you should remove it. Your code works fine otherwise.

Java code not running as planned

This isn't the entire code, just the problem area. (Full code below)
if (passLength > 4) {
System.out.println("Signup alost complete.");
Random rand = new Random();
int randm = rand.nextInt(100000) + 1;
System.out.println(
"To confirm you are not a robot, please enter this code: "
+ randm);
String code = userInput.next();
if (code.equals(randm)) {
System.out.println("Thank you, " + userName);
System.out.println(
"You may now login. Begin by entering your username");
if (userInput.equals(userName)) {
System.out.println("Now please enter you password");
}
// Where the rest of the program will go
}
else {
System.out.println("The code entered is incorrect.");
}
}
else {
System.out.println("Invalid Password");
}
I am making a program where the user makes an account, then later signs in. The part I am having trouble with is a verification to ensure the user is human (they obviously are, but still). After creating their username and password, I generate and print a random int, and they have to type it back.
My problem is that the program always skips to the else statement, and prints "The code entered is incorrect." Even when I enter it perfectly.
Can anyone tell me what I'm doing wrong?
Below is the entire code, just in case.
public static void main(String[] args) {
System.out.println("Hi! To begin please choose your username.");
System.out.println("To do this, please enter your username below. ");
System.out.println("This name must be at least three characters.");
Scanner userInput = new Scanner(System.in);
String userName = userInput.next();
int nameLength = userName.length();
if (nameLength > 2) {
System.out.println("Now please enter your password.");
System.out
.println("This password must be at lease five characters");
String passWord = userInput.next();
int passLength = passWord.length();
if (passLength > 4) {
System.out.println("Signup alost complete.");
Random rand = new Random();
int randm = rand.nextInt(100000) + 1;
System.out.println(
"To confirm you are not a robot, please enter this code: "
+ randm);
String code = userInput.next();
if (code.equals(randm)) {
System.out.println("Thank you, " + userName);
System.out.println(
"You may now login. Begin by entering your username");
if (userInput.equals(userName)) {
System.out.println("Now please enter you password");
}
// Where the rest of the program will go
}
else {
System.out.println("The code entered is incorrect.");
}
}
else {
System.out.println("Invalid Password");
}
}
else {
System.out.println("Invalid Username");
}
}
You are comparing a String with an integer, which can't be the same obviously.
int randm = rand.nextInt(100000) + 1;
...
String code = userInput.next();
if (code.equals(randm))
To solve the problem you could convert the integer to a String and compare the strings (or the other way).
String randm = String.valueOfrand.nextInt(100000) + 1;
...
String code = userInput.next();
if (code.equals(randm)) // Comparing string now
Edit : As #Pshemo pointed out, int code = userInput.nextInt(); will do the work given that you compare the integers with ==.
It's because randm is int and code is String. So the code if (code.equals(randm)) always results to false.
You cannot compare a string and an integer.
Trying taking the input as an integer instead of a String.
String code = userInput.next();
Instead use:
int code= userInput.nextInt();
if(code==randm)
Or you could convert the integer to a String as well

Categories