I'm trying to make a "choice" menu, where I am using a switch/case function to make the user choose. The problem in my code is that I want it to keep asking for input until the user types in "sair" which means "exit" in portuguese. When they type "ajuda" which means "help" they get a list of available commands to execute, but if the user types "ajuda" then the "sout" is executed and build is finished, the program ends there...
My goal is to make it run until we choose to stop, I think there was a ways using readln or similar.
Anyways, here's the chunk of code regarding to the choice:
public static String escolha() {
Scanner userInput = new Scanner(System.in);
String strEscolha = userInput.next();
boolean sair = false;
do {
switch (strEscolha) {
case "ajuda":
System.out.println("Comandos disponiveis:");
System.out.println("Ajuda; Fogo; Jogo; Resposta; Estado; Acaso; Reset; Sair;");
break;
case "Ajuda":
System.out.println("Comandos disponiveis:");
System.out.println("Ajuda; Fogo; Jogo; Resposta; Estado; Acaso; Reset; Sair;");
break;
case "sair":
System.out.println("Obrigado por jogar!");
sair = true;
break;
default:
System.out.println("Comando Invalido!");
continue;
}
} while (sair == false);
return null;
}
If anyone has a simple way to make it keep asking for commands, please let me know :(
Thanks in advance!!
PS: I just started, plese don't judge, my knowledge on java is neglectable :\
The main problem of your code is that you do not request user input in the 'ajuda' case.
Here is the code with some minor changes and some comments and recommendations:
// if your method isn't supposed to return anything, simply make it void
public static void escolha() {
Scanner userInput = new Scanner(System.in);
// print some useful information when the application starts, so that the user knows
// what to do
System.out.println("Comandos disponiveis:");
System.out
.println("Ajuda; Fogo; Jogo; Resposta; Estado; Acaso; Reset; Sair;");
String strEscolha = userInput.next();
boolean sair = false;
do {
// remove duplicate case by converting the input to lower letters
switch (strEscolha.toLowerCase()) {
case "ajuda":
System.out.println("Comandos disponiveis:");
System.out
.println("Ajuda; Fogo; Jogo; Resposta; Estado; Acaso; Reset; Sair;");
// read the user input
strEscolha = userInput.next();
System.out.println(strEscolha);
break;
case "sair":
System.out.println("Obrigado por jogar!");
sair = true;
break;
default:
System.out.println("Comando Invalido!");
}
} while (sair == false);
// do not forget to close the scanner, it might cause a memory leak
userInput.close();
}
Firstly, remove the System.exit, or you will shut down the entire JVM without executing the subsequent code (your IDE may have given you a dead code warning about this).
Secondly, you need to use sair == false (or, better, !sair) instead of sair = false. The former is a comparison; the latter is an assignment, making sair false.
do { ... } while (false) will execute the loop body once, but will not repeat.
Thirdly, the return strEscolha; immediately before while will cause the method to return before it attempts to loop, so it should be removed.
Related
I'm trying to make a menu to ask the user to input YES or NO, if none of their input is either that, I want to prompt the user the question again. I was wondering why the code needs another return statement.
You code is wrong
You need to prompt again within the loop, otherwise if you do not eneter Yes or No, it will just spin forever.
When getting the nextLine you need to assign to a variable ,else it is just lost.
The value for valid never changes
so you code should be something like
Scanner sc = new Scanner(System.in) ;
boolean yes = false;
while (true) {
System.out.println("enter yes or no");
String line = sc.nextLine();
if (line.equalsIgnoreCase("yes")) {
yes = true;
break;
}
if (line.equalsIgnoreCase("no")) {
break;
}
// else back to the top
}
return yes;
So I'm building an email administration app and although it is working with if statements, I am trying to incorporate switch statements. I am prompting the user using a scanner to select which department they are from while building their email associated with it. Although when I am trying to return this.department, it is saying it is unreachable. I feel like I am missing something very obvious.
// Ask for the department
private String setDepartment() {
Scanner sc = new Scanner(System.in);
int department;
System.out.println("Select your department:\n1. Sales\n2.Accounting\n3.Development\n4.N/A");
department = sc.nextInt();
while (true) {
switch (department) {
case 1:
this.department = "Sales";
break;
case 2:
this.department = "Accounting";
break;
case 3:
this.department = "Development";
break;
case 4:
this.department = "";
break;
default:
System.out.println("Please choose a valid option (1-4)");
break;
}
sc.close();
}
return this.department; <-- Error: Unreachable code
}
problem is your condition inside the while() loop .It set always to true .So code below the while loop never gets executed .Try to have a different condition inside the while loop which terminates in a certain value.Otherwise you need place what ever you want to return inside the while loop.
Extra: Please also place your sc.close(); outside the while loop otherwise you can't use the resource after the first while loop iteration.so closing resource must be done always at the end.
Solution 1:
while(updatedTerminationCondition){//change the termination condition
}
Solution 2:
while(true){
//place your return value inside here but then loop will only run once
}
The problem is your switch-statement is in a while(true) loop that gets never exited. Unless you explicitly exit the loop e.g. by using break the program will never stop to execute the loop, meaning any code below it will never get reached, thats what the compiler is complaining about.
But if I put it to "valid = false;" it does not work in debug or running.
In fact even running the code, I can't type anything after the "Do you want to order anything else?", no matter if it's in debug or running mode.
Am I missing something? After asking "how many you want to order" and you put in a number after it should ask "do you want to order anything else" which is does but then I can't type and break out of the do while loop. Everything else is working up to that point.
do {
boolean itemValid = true;
while (itemValid) {
System.out.println("Please enter an item name: ");
String enterItem = scnr.nextLine();
if (keepTrack.containsKey(enterItem)) {
System.out.println(keepTrack.get(enterItem));
itemValid = false;
} else {
System.out.println("Sorry we don't exist.");
continue;
}
System.out.println("How many do you want to order?");
int enterQuan = scnr.nextInt();
yourOrder = enterQuan;
valid = false;
}
System.out.println("Do you want to order anything else?");
String yesNo = scnr.nextLine();
if (yesNo.equalsIgnoreCase("n")) {
valid = false;
} else
break;
} while (valid);
Two problems with your code. First, probably unnoticed yet:
do ...
if (keepTrack.containsKey(enterItem)) {
System.out.println(keepTrack.get(enterItem));
itemValid = false;
} else {
System.out.println("Sorry we don't exist.");
continue;
}
When your input is "invalid", you turn into the else branch. The else branch continues the loop. The loop depends on value. Thus: as soon as you start with value=true, and then have an invalid input, you end up with a never-ending loop. Because nothing between the loop start and the continue statement will ever change the conditions that would end the loop.
Your actual question: when you call int enterQuan = scnr.nextInt() that does not consume the "ENTER" that you typed on the console. See here for details.
And there is another problem:
if (yesNo.equalsIgnoreCase("n")) {
valid = false;
} else
break;
}
When the user enters n or N, you go valid=false which ends the outer do-while loop. Thus: when the user enters anything else, the elsepath is taken. What is to be found in the else path? A break. Which also ends the do-while loop.
In other words: your code does exactly what you told it to do: to end the do-while loop, one way or the other.
The real answer is: you need to be much more careful what you put in your code. Each and any character matters. And when you put something into your code for an experiment: remember that it is there, and has effects.
I'm making (my own version of)roulette with Java, and one of the types of bets a player can make is to choose the color that is going to be rolled. (Even is black, odd is red). Is there a way I can use a switch statement to compare a string against an enum?
private enum colors{red, black};
private String colorGuess;
private boolean colorVerify = false;
public void getColorGuess(){
do{
Scanner in = new Scanner(System.in);
colorGuess = in.nextLine();
switch(colors){
case red:
colorVerify = true;
break;
case black:
colorVerify = true;
break;
default:
System.out.println("Invalid color selection!");
break;
}while(colorVerify = false);
This is what i'm trying to get but it's not letting me use the enum 'colors' in a switch statement.
You must have an instance of an enum type (its member) on which you switch. You are trying to switch on the Enum class itself, which is a meaningless construct. So you probably need
colors col = colors.valueOf(colorGuess);
switch (col) ...
BTW the name should be Colors, not colors to respect the very important and non-optional Java naming convention.
You can get an enum from a string with Enum.valueOf(). Take care here, the other answers fail to mention that Enum.valueOf() will throw an IllegalArgumentException if passed an string which isn't a valid member of the enum.
Be sure to properly format and indent your code, it helps us (and you!) read it and understand what's going on:
// note the capitalization, and the singular 'Color'
private enum Color {RED, BLACK};
// At least with the code provided, you don't need colorGuess or colorVerify to be
// instance variables, they can be local to the method. Limiting the amount of
// time a variable lives for (its scope) is critical for quality, maintainable code
public Color getColorGuess() {
Scanner in = new Scanner(System.in); // this should be outside the while loop
while(in.hasNextLine()) {
// .toUpperCase() lets you type "red" or "RED" and still match
String line = in.nextLine().toUpperCase();
try {
// Enum.valueOf() throws an exception if the input is not valid
Color guess = Color.valueOf(line);
switch(guess) {
case RED:
return guess; // return, rather than break, to exit the method
case BLACK:
return guess;
// As long as your switch statement covers all cases in your enum, you
// don't need a default: case, you'll never reach it
}
} catch (IllegalArgumentException e) {
System.out.println("Invalid color selection!");
}
}
}
Note that we now return guess in both cases, which is somewhat redundant. At least with the example code you provided, you don't actually need to track colorVerify at all, because the method will keep looping forever until a valid color is entered. You could replace the whole switch statement in my method with simply return guess; as you know it's a valid guess as soon as Color.valueOf() returns a value.
In other words, you could clean your code up to:
public static Color getColorGuess() {
try (Scanner in = new Scanner(System.in)) {
while(in.hasNextLine()) {
try {
return Color.valueOf(in.nextLine().toUpperCase());
} catch (IllegalArgumentException e) {
System.out.println("Invalid color selection!");
}
}
}
}
Notice that the method is static now, and uses a try-with-resources block to close the Scanner once you're done with it.
I am making a Text-Based Adventure game. In one room, I want to ask the player what to do, and if he goes through the door he/she moves to the next room. If he/she picks up the flashlight, the "what do you want to do?" question is repeated so they can go through the door after that. Here is my code:
case 1:
System.out.println("What do you want to do? Type 'door' to go through the door or 'flashlight' to pick up the flashlight.");
String roomOneAction = input.nextLine();
switch(roomOneAction) {
case "flashlight":
System.out.println("Picked up flashlight.");
//repeat what do you want to do? question
break;
case "door":
System.out.println("You open the door.");
//continue plot, don't repeat question
break;
default:
System.out.println("Error");
// repeat what do you want to do? question
break;
}
break;
With this code right now, it repeats the question for anything you type. I do not want this to happen if "door" is typed.
Also, how can I make it so that once the flashlight is picked up and the question is repeated, the flashlight can't be picked up a second time?
This might be close to what you want:
import java.util.Scanner;
public class Game {
private static boolean flashlightPicked = false;
private static boolean doorEntered = false;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while (true) {
int x = 1;
switch (x) {
case 1:
System.out
.println("What do you want to do? Type 'door' to go through the door or 'flashlight' to pick up the flashlight.");
String roomOneAction = input.nextLine();
switch (roomOneAction) {
case "flashlight" :
if(!flashlightPicked){
System.out.println("Picked up flashlight.");
flashlightPicked = true;
} else {
System.out.println("Already picked up flashlight!");
}
// repeat what do you want to do? question
break;
case "door":
if(!doorEntered){
System.out.println("You open the door.");
doorEntered = true;
}else{
System.out.println("Already opened the door!");
}
// continue plot, don't repeat question
break;
default:
System.out.println("Error");
// repeat what do you want to do? question
break;
}
}
}
}
In this case you should probably store the information if you want to ask again or not:
boolean askAgain = true;
//...
case "door":
//...
askAgain = false;
//...
if (askAgain) {
System.out.println("...");
}
I would recommend using a while loop here. Can the player do anything else in the room or leave the room in a different way? If they can only leave the room using the 'door' command, set up the while loop to have the terminating factor being the 'door' command.
I don't like the idea of cascading multiple switches as you did. You should use state pattern and command pattern, but I assume you're a programming beginner, so I'll just try to answer your question.
Wrap the roomOneAction switch statement in a while loop, like
boolean foundFlashlight = false;
boolean askAgain = true;
while (askAgain)
{
// question + switch statement and so on
}
if the player picks the flashflight, set foundFlashlight to true.
In the next run, the player gets asked again. If he picks flashlight,
you have to evaluate the foundFlashlight variable, if the value is true,
tell the player he already has the flashlight and he should answer again.
In the door case, simply set askAgain to false. The loop while terminate then.
But again, this is not a nice, clean and easy to maintain approach. You should take a look at some design patterns. Especially the above mentioned state pattern.