Hello I am writing a simple program for a user to take a 3 question test. I am trying to validate the user input however if the user enters in a loop to enter the correct data because they previously entered the wrong data they cannot get out of the loop. Even if there next answer is correct. Something is setting one of my flags to false and I cannot figure out what. I tried debugging it to no avail.
import java.util.Scanner;
public class ALittleQuiz {
private static int correct = 0;
public static void main (String[] args){
Scanner keyboard = new Scanner(System.in);
System.out.print("Are you read for the quiz? ");
keyboard.next();
System.out.println("Okay, here it comes!");
questionOne();
questionTwo();
questionThree();
System.out.println("Overall, you got "+correct+" out of 3 correct.");
System.out.println("Thanks for playing!");
}
public static void questionOne(){
System.out.println("Q1) What is the capital of Alaska?");
System.out.println(" 1) Melbourne");
System.out.println(" 2) Anchorage");
System.out.println(" 3) Juneau");
System.out.print("> ");
getUserInputForQuestionOne();
}
public static void questionTwo(){
System.out.println("Q2) Can you store the value 'cat' in a variable of type int? ");
System.out.println(" 1) Yes");
System.out.println(" 2) No");
System.out.print("> ");
getUserInputForQuestionTwo();
}
public static void questionThree(){
System.out.println("Q3) What is the result of 9+6/3?");
System.out.println(" 1) 5");
System.out.println(" 2) 11");
System.out.println(" 3) 15/3");
System.out.print("> ");
getUserInputForQuestionThree();
}
public static void getUserInputForQuestionOne(){
int testvar = 0;
try{
Scanner inputForQuestionOne = new Scanner(System.in);
testvar = inputForQuestionOne.nextInt();
validateUserInputForQuestionOne(testvar);
} catch (Exception e) {
System.out.println("Error: invalid entry please try again");
getUserInputForQuestionOne();
}
}
public static void getUserInputForQuestionTwo(){
int testvar = 0;
try{
Scanner inputForQuestionTwo = new Scanner(System.in);
testvar = inputForQuestionTwo.nextInt();
validateUserInputForQuestionTwo(testvar);
} catch (Exception e) {
System.out.println("Error: invalid entry please try again");
getUserInputForQuestionTwo();
}
}
public static void getUserInputForQuestionThree(){
int testvar = 0;
try{
Scanner inputForQuestionThree = new Scanner(System.in);
testvar = inputForQuestionThree.nextInt();
validateUserInputForQuestionThree(testvar);
} catch (Exception e) {
System.out.println("Error: invalid entry please try again");
getUserInputForQuestionThree();
}
}
public static void validateUserInputForQuestionOne(int choiceOne){
if(choiceOne >= 1 && choiceOne <= 3){
sendResponseForQuestionOneToDetermineIfCorrectOrNot(choiceOne);
}else {
System.out.println("Please enter 1, 2 or 3 for your selection");
getUserInputForQuestionOne();
}
}
public static void validateUserInputForQuestionTwo(int choiceTwo){
if(choiceTwo >= 1 && choiceTwo <= 3){
sendResponseForQuestionTwoToDetermineIfCorrectOrNot(choiceTwo);
}else {
System.out.println("Please enter 1 or 2 for your selection");
getUserInputForQuestionTwo();
}
}
public static void validateUserInputForQuestionThree(int choiceThree){
if(choiceThree >= 1 && choiceThree <= 3){
sendResponseForQuestionThreeToDetermineIfCorrectOrNot(choiceThree);
}else {
System.out.println("Please enter 1, 2 or 3 for your selection");
getUserInputForQuestionThree();
}
}
public static void sendResponseForQuestionOneToDetermineIfCorrectOrNot(int validChoiceOne){
switch (validChoiceOne){
case 1: System.out.println("Sorry, that is not correct\n");
break;
case 2: System.out.println("Sorry, that is not correct\n");
break;
case 3: System.out.println("That's right\n");
correct++;
break;
}
}
public static void sendResponseForQuestionTwoToDetermineIfCorrectOrNot(int validChoiceTwo){
switch (validChoiceTwo){
case 1: System.out.println("Sorry, 'cat' is a string. Ints can only store numbers\n");
break;
case 2: System.out.println("That's right\n");
correct++;
break;
}
}
public static void sendResponseForQuestionThreeToDetermineIfCorrectOrNot(int validChoiceThree){
switch (validChoiceThree){
case 1: System.out.println("Sorry, that is not correct\n");
break;
case 2: System.out.println("That's right\n");
correct++;
break;
case 3: System.out.println("Sorry, that is not correct\n");
break;
}
}
}
Here is what is happening in my terminal:
Are you ready for a quiz? y
Okay, here it comes!
Q1) What is the capital of Alaska?
1) Melbourne
2) Anchorage
3) Juneau
> 456
Please enter 1, 2 or 3 for your selection
Q1) What is the capital of Alaska?
1) Melbourne
2) Anchorage
3) Juneau
> 3
That's right
Please enter 1, 2 or 3 for your selection
Q1) What is the capital of Alaska?
1) Melbourne
2) Anchorage
3) Juneau
> 2
Sorry, that is not correct
Please enter 1, 2 or 3 for your selection
Q1) What is the capital of Alaska?
1) Melbourne
2) Anchorage
3) Juneau
>
Edit: So after reading the article one of you had posted I went back to the drawing board and was able to resolve my issue. I do want to thank those that took the time to help me with this. I updated my code which I believe is a lot more comprehensible and easier to look at. Above is my newly created code. If anyone has any notes on this I would much appreciate it!
Inside of questionOne, you make a call to validateQuestionOneUerInput. In validateQuestionOneUerInput, if the user enters something other than 1, 2, or 3, it sets flagForQuestionOne and then calls questionOne again. Regardless of the result of this call, flagForQuestionOne is false, so you now have an infinite loop.
That method could see if the user's response is valid or not and return true or false, or could throw an exception for invalid input, but should not re-call questionOne.
in the do while loop, instead of using the flag, you are checking the flag equals == false.
Below is incorrect because when you set the flag value to true the while condition evaluates to false.
while (flag == false);
Change it to
while(flag)
Related
I am working on a to do list and am currently stuck making a menu. The menu receives input from the user of the numbers 1-6 and carries out a specific task associated with that number(int). That's the perfect world scenario, so I need the menu to be able to take non integer values and not be bricked as well as display an error message to the user. I think I have created an efficient way of asking the user for integers without bricking the program but I cannot determine what my return statement should be in order to utilize the method in the main. I'll use it in a switch statement like this:
while (true) {
switch (getMenuOption()) {
case 1:
etc
This is the current method that I have for the getMenuOption. What return statement should I use, or is there a more efficient way to carry this out?
package project1_martinez_adriel;
import java.util.Scanner;
public class getMenuOption {
public static int getMenuOption() {
Scanner input = new Scanner(System.in);
System.out.println(" 1. Create a new item \n 2. Mark an item as in progress \n 3. Mark an item as completed \n 4. List all to do items \n 5. Remove completed items \n 6. Exit \n What would you like to do? \n ");
String value = input.nextLine();
int num;
try {
num = Integer.parseInt(value);
if (!(num == 1 || num == 2 || num == 3 || num == 4 || num == 5 || num == 6)) {
System.out.println("ERROR! Invalid choice! \nPlease enter a valid choice BETWEEN 1 & 6: ");
}else if (num == 6){
System.exit(0);
}
} catch (NumberFormatException e) {
System.out.println("ERROR! Please enter a valid INTEGER between 1 & 6.");
}
return //What do I put here!?
}
how about cleaning it up to be
if (num < 1 || num > 6) {
System.out.println("ERROR! Invalid choice!...");
}
then later
return num;
The code in your switch statement should process the options between 1 && 6 including 6 being System.exit (0);
I would even have the error messages in the switch default block
edit
num should also be initialized with a value, something like
int num = -1;
So after some clean up, frustration, & long hours I have come up with this, including the switch statements:
Scanner input = new Scanner(System.in);
boolean validInput = false;
do {
System.out.print("Enter an integer: ");
int num;
try {
num = input.nextInt();
switch (num) {
case 1:
case 2:
case 3:
case 4:
case 5:
case 6: // cascading case statement example
validInput = true;
break;
default:
System.out.println("ERROR! Please enter a valid choice BETWEEN 1 & 6 (inclusive): ");
num = input.nextInt();
break;
}
} catch (Exception e) {
/* input.next() to move the Scanner forward. */
System.out.println(input.next() + " was not valid input.");
System.out.println("ERROR! Please enter a valid INTEGER between 1 & 6.");
}
} while (!validInput);
input.close();
}
}
I want to create a program that gives you three tries to find any given number. It's going to essentially be a guessing game. The problem is, I have to do this without any loops. So far, I'm only able to get input from the user, read that input and tell them if they've won or 'lost' the game. The program only runs once and stops(as expected).
I was told that it could be done without loops, albeit with a lot more code. Can you guys let me know what I'm doing wrong here and give me some pointers on what I should change? If you need clarification let me know.
Thanks.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner ran = new Scanner(System.in);
System.out.println("Enter a number: ");
int x = ran.nextInt();
if (x < 3) {
System.out.println("Too low. Try again.");
System.out.println("Enter a number: ");
} else if (x > 3) {
System.out.println("Too high. Try again");
} else if(x == 3) {
System.out.println("You win. Nice job.");
} else {
System.out.println("You lose");
}
System.out.println("Number Guessing Game (c) 2017 Anna Gibson");
}
}
You can do this using recursion. See this program. Find explanations within comments.
import java.util.Scanner;
public class HelloWorld {
private static Scanner ran = new Scanner(System.in);
//this is number of tries you want to give to user
private static int counter = 5;
//The actual number
private static final int NUM = 3;
public static boolean guessingMachine() {
//counter indicates that number of attempts remaining
if(counter == 0) {
return false;
}
counter--;
System.out.println("Enter a number: ");
int x = ran.nextInt();
if (x < NUM) {
System.out.println("Too low. Try again.");
//try again... call this method again
return guessingMachine();
} else if (x > NUM) {
System.out.println("Too high. Try again");
//try again... call this method again
return guessingMachine();
} else {
//x == NUM success
return true;
}
}
public static void main(String[] args) {
boolean result = guessingMachine();
if(result)
System.out.println("You win. Nice job.");
else
System.out.println("You lose");
System.out.println("Number Guessing Game (c) 2017 Anna Gibson");
}
}
You could next conditions:
get user input
if input is correct, congratulation user and exit
else
get user input //second attempt
if input is correct, congratulation user and exit
...
You can continue from there. The code you provided, where you tell the user if they are too high or low, would have to be included in each of the branches of the pseudocode above.
I think the main purpose of this exercise is intended for you to strengthen your nested if-else concepts.
import java.util.Scanner;
public class HelloWorld{
public static void main(String []args){
int num=3;
int count=1;
Scanner ran = new Scanner(System.in);
System.out.println("Enter a number: ");
int x = ran.nextInt();
if(x>num || x<num)
{
System.out.println("incorrect guess");
count++;
System.out.println("Enter a number: ");
x = ran.nextInt();
if(x>num || x<num)
{
System.out.println("incorrect guess");
count++;
System.out.println("Enter a number: ");
x = ran.nextInt();
if(x>num || x<num)
{
System.out.println("incorrect guess YOU LOSE");
}
else
{
System.out.println("YOU WIN");
}
}
else
{
System.out.println("YOU WIN");
}
}
if(x==num && count==1)
{
System.out.println("YOU WIN");
}
System.out.println("Number Guessing Game (c) 2017 Anna Gibson");
}
}
package javaapplication1;
import java.util.Scanner;
public class JavaApplication1 {
public static void main(String[] args) {
System.out.println("What is the password?");
Scanner new2 = new Scanner(System.in);
int input = 0;
while(input <= 5 )
{
String password = new2.nextLine();
if(!password.equals("bluesky123")){
System.out.println("Incorrect password");
input++;
}
else if("bluesky123".equals(password)) {
System.out.println("You got it right!");
break;
}
else if(input == 5) {
System.out.println("maximum number of attempts reached");
break;
}
}
}
}
basically, once I hit the 5 loops, it just says "incorrect password" and breaks. not the "maximum attempts" message.
Allow me to annotate:
This if statement will always be evaluated:
if(!password.equals("bluesky123")){
System.out.println("Incorrect password");
input++;
}
This if statement will only be evaluated if the password is "bluesky123". In this case, it will always evaluate to true.
else if("bluesky123".equals(password)) {
System.out.println("You got it right!");
break;
}
There is no case when this if statement will ever be evaluated. Once if-else finds a statement that is true, it will skip all others in that section.
else if(input == 5) {
System.out.println("maximum number of attempts reached");
break;
}
In your case, you should consider a nested if (i.e. an if inside another if).
while(input <= 5 )
{
String password = new2.nextLine();
if(!password.equals("bluesky123")){
System.out.println("Incorrect password");
input++;
}
else {
System.out.println("You got it right!");
break;
}
if((input == 5) && (!password.equals("bluesky123"))) {
System.out.println("maximum number of attempts reached");
break;
}
}
Your logic has some flaws. You have to pay attention to how JAVA processes if / else if
https://www.tutorialspoint.com/java/if_else_statement_in_java.htm
I tested your code it is working! The only thing that you need to do is to move the follow line to inside the while loop
System.out.println("What is the password?");
Doing this it will print "Incorrect password" and then it will print again
"What is the password?"
Because in the way that it is working now seems that the software is not waiting the password to be retyped when in fact it is.
Wrote a roshambo program, ran it once, worked fine, ran it again and the following errors popped up:
RoShamBo!
Play Game
Show Score
Quit
1
Which do you choose?
Rock
Paper
Scissors
2
Which do you choose?
Rock
Paper
Scissors
Invalid Entry, Please Try Again.
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at RoShamBo.getUserChoice(RoShamBo.java:82)
at RoShamBo.winner(RoShamBo.java:112)
at RoShamBo.main(RoShamBo.java:27)
not sure on how to deal with these type of errors, this my first time using methods so i'm thinking it has to do with how I called each method? please help.
thanks in advance.
import java.util.Scanner;
public class RoShamBo
{
public static void main(String[] args)
{
System.out.println("RoShamBo!");
System.out.println("1. Play Game");
System.out.println("2. Show Score");
System.out.println("3. Quit");
Scanner userInput = new Scanner(System.in);
if(userInput.hasNextInt())
{
int userIn = userInput.nextInt();
if(userIn == 1)
{
getUserChoice();
getCompChoice();
winner();
}
else if(userIn == 2)
{
scores();
}
else if(userIn == 3)
{
System.out.println("Qutiing: Final Score was: ");
scores();
userInput.close();
}
else
{
System.out.println("Invalid Entry, Please Try Again.");
userInput.next();
}
}
else
{
System.out.println("Invalid Entry, Please Try Again.");
userInput.next();
}
}
public static String getUserChoice()
{
// ask player for a move : playerMove
System.out.println("Which do you choose?");
System.out.println("1. Rock");
System.out.println("2. Paper");
System.out.println("3. Scissors");
Scanner input = new Scanner(System.in);
String userChoice = " ";
if (input.hasNextInt())
{
int userInput = input.nextInt();
switch(userInput)
{
case 1:
userChoice = "Rock";
break;
case 2:
userChoice = "Paper";
break;
case 3:
userChoice = "Scissors";
break;
}
}
else
{
System.out.println("Invalid Entry, Please Try Again.");
input.next();
}
input.close();
return userChoice;
}
private static String getCompChoice()
{
//Method for getting Computers move
int compChoice = (int) ( 1 + (Math.random() * 3));
String compMove = " ";
switch(compChoice)
{
case 1:
compMove = "Rock";
break;
case 2:
compMove = "Paper";
break;
case 3:
compMove = "Scissors";
break;
}
return compMove;
}
public static String winner()
{
String winnerIs = " ";
String comp = getCompChoice();
String user = getUserChoice();
if(user.equals("Rock") && comp.equals("Scissors") ||
user.equals("Paper") && comp.equals("Rock") ||
user.equals("Scissors") && comp.equals("Paper"))
{
System.out.println("You Win!");
}
else
{
System.out.println("You Lose");
}
return winnerIs;
}
public static void scores()
{
int compCount = 0;
int userCount = 0;
if (winner().equals("You Win!"))
{
userCount++;
}
else
{
compCount++;
}
System.out.println("Player = " + userCount );
System.out.println("Computer = " + compCount );
}
}
Probably here
{
System.out.println("Invalid Entry, Please Try Again.");
input.next();
}
you are doing a next() without checking for has*().
Your stack gives one hint.
at java.util.Scanner.next(Unknown Source).
and
Exception in thread "main" java.util.NoSuchElementException
Turning to the documentation here:
http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#next%28%29
part that is of interest to you:
Throws:
NoSuchElementException - if no more tokens are available
You call .next()
but what do you want to read? Is there anything waiting in input buffer? Also, see my comment, meaning that your logic is busted.Rethink your game logic instead of fixing it.
Giving a complete answer that gets your code to run like it's supposed to would mean writing most of your code, I won't go that way. Instead, you should apply one of the most powerful debugging methods known to humans and do it yourself:
https://en.wikipedia.org/wiki/Rubber_duck_debugging
Good luck and enjoy ;)
I tried making a menu system to make a user select between four options. To distinguish between the selections I check the int entered. It works but somehow I feel it is not very elegant. Especially when I set the initial value of selectedMenu to 1902475424 to check for when the user entered a mismatcing value. I assumed the user wont accidentally type 1902475424.
Is there a way more simple way to make a menu system or will this do? Is this major flawed?
Yes im a beginner to Java :-)
import java.util.Scanner;
import java.util.InputMismatchException;
public class Menu {
public void printMenu() {
System.out.println(
"1. Start new game\n" +
"2. Load game\n" +
"3. Settings\n" +
"4. Exit\n"
);
}
public void selectMenu() throws InputMismatchException {
int selectedMenu = 1902475424;
Scanner aScanner = new Scanner(System.in);
do {
selectedMenu = 1902475424;
try {
System.out.println("Try block begin.");
selectedMenu = aScanner.nextInt();
} catch (InputMismatchException e) {
System.out.println("Catch blok begin.");
System.out
.println("Invalid input, please input a number between 1-4.");
aScanner.nextLine();
}
if ((selectedMenu < 1 || selectedMenu > 4)
&& (selectedMenu != 1902475424)) {
System.out.println("Input out of range \"" + selectedMenu
+ "\". Input a number between 1-4.");
}
} while (selectedMenu == 1902475424
|| (selectedMenu < 1 || selectedMenu > 4));
if (selectedMenu >= 1 && selectedMenu <= 4) {
System.out.println("A new game will now start.");
}
}
}
Your method is leaning into the overkill category :]You can do away with your random value of 1902475424 like so:
public void selectMenu() throws InputMismatchException {
int selectedMenu;
Scanner aScanner = new Scanner(System.in);
do {
try {
System.out.println("Try block begin.");
selectedMenu = aScanner.nextInt();
if(selectedMenu < 1 || selectedMenu > 4) {
System.out.println("Input out of range \"" + selectedMenu + "\". Input..");
}
} catch(InputMismatchException e) {
System.out.println("Catch blok begin.");
System.out.println("Invalid input, please input a number between 1-4.");
aScanner.nextLine();
selectedMenu = 0;
}
} while(selectedMenu < 1 || selectedMenu > 4);
System.out.println("A new game will now start.");
}
Consider the following alternative (pseudocode):
int getMenuOption() {
print(message)
read(input)
if input is valid then return input
else then return getMenuOption()
}
This is recursive, so if the user sits there and enters bad numbers long enough, you could overflow the stack. You could easily augment this to give the user a fixed number of tries:
int getMenuOption(int triesRemaining) {
if (triesRemaining == 0) throw new RetriesExceededException();
print(message)
read(input)
if input is valid then return input
else then return getMenuOption(triesRemaining - 1)
}
Try something like that (I haven't tested it)
import java.util.Scanner;
import java.util.InputMismatchException;
public class Menu {
public void printMenu() {
System.out.println("1. Start new game\n" + "2. Load game\n"
+ "3. Settings\n" + "4. Exit\n");
}
public void selectMenu() throws InputMismatchException {
int selectedMenu;
boolean validSelection = false;
Scanner aScanner = new Scanner(System.in);
while(!validSelection) {
selectedMenu = aScanner.nextInt();
validSelection = true;
switch (selectedMenu) {
case 1:
// doWhen1();
break;
case 2:
// doWhen2();
break;
case 3:
// doWhen3();
break;
case 4:
// doWhen4();
break;
default:
System.out.println("Input out of range \"" + selectedMenu
+ "\". Input a number between 1-4.");
validSelection = false;
}
}
}
}
Here is a revision to the selectMenu() method you provided that should get the job done! I tested it out and it seems to work as expected. :)
public void selectMenu() {
int selectedMenuItem = 0;
Scanner aScanner = new Scanner(System.in);
while(selectedMenuItem == 0){
String userInputMenuItemString = aScanner.nextLine();
try {
int userInputMenuItem = Integer.parseInt(userInputMenuItemString);
if(userInputMenuItem > 0 && userInputMenuItem <= 4){
selectedMenuItem = userInputMenuItem;
}else{
System.out.println("No option #" + Integer.toString(userInputMenuItem) + " exists!\nTry again:");
}
} catch(NumberFormatException ex) {
System.out.println("Please input a number!");
}
}
switch(selectedMenuItem){
case 1:
System.out.println("You chose to start a new game!");
break;
case 2:
System.out.println("You chose to load a game!");
break;
case 3:
System.out.println("You chose to access settings!");
break;
case 4:
System.out.println("You chose to exit. Bye!");
System.exit(0);
break;
}
}