I don't know how to leave this looping structure - java

Ok, so the code below loops wonderfully. It can loop as long as it wants to. The thing is though, I can never get out of the loop. I'm trying to build a text-adventure, by the way for those wondering, but I really need to get out of this loop.
System.out.println("\n\nWelcome, " + name + "! To proceed, enter your class of fighter.");
System.out.println();
boolean x = true;
while (x){
//information print statements
System.out.println("What will your class be? ");
String heroclass = scan.nextLine();
heroclass.toLowerCase();
String A;
switch (heroclass)
{
case "slayer": A = "You have selected the Slayer class.";
break;
case "blader": A = "You have selected the Blader class.";
break;
case "bandit": A = "You have selected the Bandit class.";
break;
case "wizard": A = "You have selected the Wizard class.";
break;
default: A = "Invalid entry.";
break;
}
String killloop = A;
if (killloop.charAt(0) == 'Y'){
x = false;
}
}

You need to assign heroclass.toLowerCase(); to the original value of heroclass:
heroclass = heroclass.toLowerCase();
If you do not do this, the lowercase version of heroclass is not saved.

heroclass is of String type. String is immutable type of object, so you can't update this string. heroclass.toLowerCase() just return another String object with lower cased characters, so you need to reassign this string result to this variable:
heroclass = heroclass.toLowerCase();

Put your loop in a labeled block:
myblock: {
while (true) {
//code
heroclass = heroclass.toLowerCase();
switch(heroclass)
{
case "slayer": A = "text";
break myblock;
//repeat with other cases
}
}
}
//goes to here when you say "break myblock;"
What you're doing is basically assigning the label myblock to the entire loop. When you say break myblock it breaks out of the entire section inside of the brackets.
NOTE: I would recommend this solution over the others because it doesn't depend on the magic value assigned by the switch; it works no matter what it is.
Also, I've added the part to make it case insensitive. Sorry about the confusion!

Although coding wombat is right, i'm not a big fan of the way you did things here. A loop around your whole program like this isn't good practice. It's super clunky and will lead to many problems, not to mention you're making things more complicated for yourself. Ideally you'd want to put this class selection part of the program inside a method. Then if the user's input is invalid, simply call back the method recursively until you get correct input.
Ex.
case A: do this...
case B: do this...
case C: System.out.println("Not a valid input);, classSelector();
Also, when you use OOP you have the benefit of storing all the player's attributes inside an object, as well as making methods that manipulates those attributes. It will make your code a lot cleaner and easier to work with.
Ex.
Player1.heal(10);

Related

Why isn't my output showing after my switch statement

I'm learning Java right now and I've never used switch statements before. I tried to enter a simple charmed quiz, but something in the switch statement isn't working.
I've tried putting text at various points in the program to test if the program every reaches that code. I have a good response inside the actual switch, so If I answer Question 1 wrong the text prompt will show up. But any later than inside the switch statement and none of my scoring output appears until all iterations of the for loop are complete. I have tried moving the "correct/incorrect" output to various points and none of them seem to work.
Scanner myScanner = new Scanner(System.in);
System.out.println("Enter your name!");
String name = myScanner.nextLine();
int wrongCounter = 0;
boolean correctChecker = false;
int score = 0;
String answer;
System.out.println("Welcome to the Charmed Quiz, " + name + "!");
for (int i = 0; i < 10; i++) {
if (wrongCounter < 4) {
switch(i) {
case 0:
System.out.println("Who read the spell that gave the Charmed Ones their powers?");
System.out.println("Enter your answer");
answer = myScanner.nextLine();
switch (answer) {
case "Pheobe":
correctChecker = true;
break;
default:
correctChecker = false;
break;
}
case 1:
System.out
.println("Who travelled to a cursed town with Prue when Pheobe was shot in a premonition?");
System.out.println("Enter your answer");
answer = myScanner.nextLine();
switch (answer) {
case "Cole":
correctChecker = true;
break;
default:
correctChecker = false;
break;
}
}
if (correctChecker == true) {
score++;
System.out.println("Correct!");
} else {
wrongCounter++;
System.out.println("Incorrect!");
}
This definitely isn't the best way of achieving a quiz game, but if you're using this as a learning exercise then the best course of action is to take the advice from #rzwitserloot.
Add a break after your main switch statement cases as opposed to the inner switch statement.
There is no real use having an inner switch statement though when you can use correctChecker = "Pheobe".equals(answer); to get a true or false boolean value in a single line.
This just means you can avoid the second switch statement which makes it way less confusing.
Altogether your cases could look something like this:
case 0:
System.out.println("Who read the spell that gave the Charmed Ones their powers?");
System.out.println("Enter your answer");
answer = myScanner.nextLine();
correctChecker = "Pheobe".equals(answer);
break;
}
In future, it would be better to store questions and answers in an array and use the for loop to iterate through that. This is a good tutorial on the subject.
Good luck with the rest of your project!
There are many, many problems with this code. The primary issue is that break breaks the closest construct it can break, which in your case is the inner switch. Whereas your intent is clearly to break out of both. Either [A] add another break right before the case 1: statement, or [B] use a labelled break; put something like outer: before the first (primary/outer) switch, and then make all those statements break outer;.
But, really, none of this (either the outer or the inner) are in any way sensible in switch form. I get that this is a learning exercise, but I'd think of something else to learn with.
Also, it's Phoebe, not Pheobe.

How do I use switch statements inside if else statements

I'm trying to write a program that can decide what mechanism a organic reaction will go through using a series of if else and switch statements.
Could you guys help me figure out what I'm doing wrong here? I'm having a problem getting the first if else statement to work. The program runs on my computer(I'm using the BlueJ editor), but when I respond to the first question "Is it soluble in solution?" it defaults to the else statement. The switch statements on the inside of the if else statement works fine by itself.
Can I use switch statements inside if else statements? Is there an easier way to program this?
Could you also explain why it doesn't work, or why another method would be more efficient?
Thanks a ton :)
import java.util.Scanner;
/**
* This program will decide what mechanism a reaction will undergo given information about the reactants.
* I will also include a mechanism to give a rudimentary explanation of the decision making process to
* get the reaction mechanism.
*/
public class mechanism
{
public static void main(String[] args)
{
System.out.println("Hello, this program is designed to figure out what mechanism a reaction will under go.");
//The decision tree will be a series of if-else statements. If I find a better method, I will use that
System.out.println("Is the reactant soluble in the solvent? Answer in yes or no.");
Scanner keyboard = new Scanner(System.in);
String Solubility = keyboard.next(); //Defines if the reactant is soluble in the solvent
String functional = "unassigned";//Defines if the functional roup is primary secondary or tertiary
String Base = "unassigned";//Defines the strength of the base if needed
String Polar = "unassigned";//Defines if the reactant is polarizable
String Solvent = "unassigned"; //Defines if the solvent is protic or aprotic
if ( Solubility == "yes" )
{
System.out.println("Is the functional group attached to a primary, secondary, or tertiary carbon?");
System.out.println(" Answer in p for primary, s for secondary, and t for tertiary.");
keyboard = new Scanner(System.in);
functional = keyboard.next();
switch (functional){
case "p": System.out.println("All unimolecular reactions are ruled out, leaving E2 and Sn2.");
System.out.println("Is the reactant a strong base? Answer in y for yes or n for no");
keyboard = new Scanner(System.in);
Base = keyboard.next();
if (Base == "y" ){
System.out.println("The reaction undergoes E2");
} else{
System.out.println("The reaction undergoes Sn2");
}
break;
case "s": System.out.println("No reactions have been ruled out.");
System.out.println("Is the reactant a strong base? Answer in y or n");
keyboard = new Scanner(System.in);
Base = keyboard.next();
if( Base == "y" ){
System.out.println("yay");
} else {
System.out.println("whatever");
}
break;
case "t": System.out.println("tertiary");
break;
}
}
else{
System.out.println("No reaction will occur");
}
}
}
It's another one of those mistakes that you and I will make once in a while.
Short answer: You can't use == to compare strings!
Long answer:
In your if statements, you are comparing strings with ==. You should never EVER do that. The == compares the memory addresses of the two operands if they are not a primitive. I know you want to check if the characters of the two strings are the same. But two strings with the same characters may not have the same memory address!
What you should do is use the equals method to compare strings, like this:
if (Solubility.equals("yes"))
You can also use the equalsIgnoreCase method. It does what it says on the lid. Remember to change all the other if statements as well!
Moreover, you cannot use switch statements to switch a string. But seeing you didn't recieve any compiler error, I think you are using Java 8.
But if you are not using Java 8, the best way IMO to resolve this is to switch a Character.
char functionalChar = functional.charAt(0);
switch (functionalChar) {
case 'p': // remember to use single quotes!
...
}
Although this is not the biggest problem, it is still worth correcting:
You only need to instantiate Scanner once.
It is perfectly fine to use a switch statement for multiple input types - even within an if statement.
Your problem is that you keep re-initializing the Scanner object.
Once you have initialized the Scanner:
Scanner keyboard = new Scanner(System.in);
Then elsewhere where you would like to receive input, just re-use it:
//keyboard = new Scanner(System.in); // You don't need this line
Base = keyboard.next();
Also, the reason that you are never entering your if statement is the way you are comparing Solubility with'Yes'. For Strings, you should use either equals() or equalsIgnoreCase if case does not matter.
Change the if statement to the following line and your code will work as expected:
if ( Solubility.equalsIgnoreCase("yes"))

Java do-while with multiple string validation

Trying to create a simple program that has three options for text input. If the user types one of the three, the program moves on. If the user types something else, the program loops back and asks for the input again until a proper response is given.
Using a drop down list or other method will not work, as this is for an assignment.
System.out.print("Enter one of the following: cheese, water, or burger: ");
userMedium = user_input.nextLine( ); // store user input as a string
mediumConvert = userMedium.toLowerCase();
boolean verifyName;
if (mediumConvert.equals("cheese") || mediumConvert.equals("water") || mediumConvert.equals("burger")){
verifyName = false;
} else {
verifyName = true;
}
while (verifyName = true){
System.out.println("Please input a valid medium (cheese, water, or burger): ");
userMedium = user_input.nextLine( );
mediumConvert = userMedium.toLowerCase();
}
This is what I have set up so far, but this just keeps repeating the loop OVER AND OVER. After this section I want to execute a switch to work off each of the three correct responses.
I've spent the last hour on google and YouTube, but everything I found is using integers. It seems pretty easy to validate user input when it is just a number and an operand. But how do I use three possible strings?!
while (verifyName = true)
↑
You're assigning and not comparing. The expression of the assignment returns the assigned value, so your loop is equivalent to:
while (true)
You should change it to:
while (verifyName)
Basically, you should write while (verifyName == true), but it's redundant since it's like asking "Is it true that verifyName has the value true?". Also it prevents potential bugs, like just inserting one = instead of two..
Noticed two things:
1.) By doing
while(verify = true)
you are actually assigning the value true to verifyName. You need to use
while(verifyName)
2.) Where do you reassign the value of verifyName?
You should be validating and reassigning inside the while block.
Also you should consider cleaner alternative solution, but that can wait for another day.
You will never break out of the whileloop because the variable verifyName is never updated inside the loop. This means that you'll either never execute the loop because the user inserted the input you wanted or you'll end up with an infinite loop.
You need to do your input verification inside the loop as well and be careful with the boolean validation as well.
Something like:
while (verifyName) {
System.out.println("Please input a valid medium (air, water, or steel): ");
userMedium = user_input.nextLine( );
mediumConvert = userMedium.toLowerCase();
if (mediumConvert.equals("cheese") || mediumConvert.equals("water") || mediumConvert.equals("burger")){
verifyName = false;
} else {
verifyName = true;
}
}

How to properly use methods in Java for Magic 8 Ball program

I have no code to paste since all I have is a template of my methods to be used. Hopefully this isn't too broad because I've looked all over and haven't received the answer I'm needing.
Many have seen or heard of a "Magic 8 Ball" program. A user asks a question, and they receive a random answer in return. I could have written the code easily with one method, but now we've delved into using multiple methods and I'm missing a piece of the puzzle.
The rules of this program:
1) I have to create at least three methods: the main, an input method, and an output method.
2) I have to use a switch statement for the random answers.
3) I have to use a while loop (or a do-while) to prompt the user to either ask another question, or quit.
I think my only problem lies in where to place each piece of the code. I'm going to need to call a Scanner. That's no big deal. I know how to do the switch statement. I know how to randomize the output. I'm most likely going to use a boolean for the keep going/quit part. But where do I actually PLACE the scanner? The boolean? In the main? In an input method? What about the processing section for the randomization? Are all my variables declared in the main so they spread throughout?
I hope my question makes sense.
Creating Scanner once either in main, or in the constructor as a class level object will be much cheaper than creating every time you call the input method. If created at class level it can be used directly in input method, otherwise if it is created in main method it can be passed as an argument to the input method.
Boolean can be in the input method because you are directly comparing the input and you have no more use for it.
When you have an object, especially an expensive one, it is better to create it only once wherever applicable, or create it as few times as possible.
Excuse my sloppy code, and ignore the case names. They are temporary since I will be renaming them. I tried every scenario after compiling. I asked a question, it answered, and it asked if I wanted to ask another. I asked another, it repeated the prompt. I answered "n", and it said "Thanks for playing. Goodbye", and stopped running. Here is my code. Problem solved.
import java.util.Scanner;
public class MagicBall {
public static void main(String[] args) {
int random = 0;
boolean playAgain = true;
while (playAgain) {
askAnother(random);
}//end while
}//end main
public static void askAnother(int r) {
System.out.print("Hello! What is your question? ");
Scanner input = new Scanner(System.in);
String question = input.nextLine();
String yes_or_no;
String next_question;
randomAnswer(r);
boolean playAgain = true;
while(playAgain) {
System.out.println("Would you like to ask another question? Y to ask, N to quit.");
yes_or_no = input.nextLine();
if (yes_or_no.equalsIgnoreCase("Y")) {
System.out.println("What is your next question?");
next_question = input.nextLine();
randomAnswer(r);
}//end if
else if (yes_or_no.equalsIgnoreCase("N")) {
playAgain = false;
System.out.println("Thanks for playing. Goodbye.");
System.exit(0);
}
else {
System.out.println("Invalid Input. Please enter Y or N.");
continue;
}//end else
}//end while
}//end input method
public static int randomAnswer(int r1) {
r1 = (int)(Math.random() * 9);
switch(r1) {
case 0: System.out.println("Yes"); break;
case 1: System.out.println("Yes1"); break;
case 2: System.out.println("Yes2"); break;
case 3: System.out.println("Neutral"); break;
case 4: System.out.println("Neutral1"); break;
case 5: System.out.println("Neutral2"); break;
case 6: System.out.println("No"); break;
case 7: System.out.println("No1"); break;
case 8: System.out.println("No2"); break;
}//end switch
return r1;
}//end output method
}//end MagicBall class

Method Paramaters

Trying to write a program that asks the user if they want instructions. If the user enters maybe the console responds with "please enter a yes or no answer" and repeats the question.
I'm having difficulty listing the method parameters for the method askYesNoQuestion. Are the parameters simply String yes, String no? I am also stuck on how do I make the program repeat the question after someone enters maybe? Does my code look generally correct for what I'm trying to do?
import acm.program.*;
public class Instructions extends ConsoleProgram{
public void run(){
String answer = readLine("Would you like instructions? : ")
{
if (answer.equals("maybe")) {
println ("Please enter a yes or no answer.");
}
}
}
private boolean askYesNoQuestion(String yes, String no ){
if (askYesNoQuestoin ("would you like instructions? "))
if (answer.equals("yes")) {
return yes;
} else {
if (answer.equals("no"))
return no;
}
}
Up to you how you do it, but really you are trying to convert a user's string input to something a bit easier for Java to work with.
I'd suggest askYesNoQuestion() would take the question to ask and then return true for yes and false for no. If you really want to handle "maybe" then use and int (or better yet an enum) to handle the response.
boolean askYesNoQuestion(String question)
{
while(true) {
// print the question
// get the answer
// if answer.equals("yes") return true
// if answer.equals("no") return false
// any other answer asks the question again
}
return false;
}
// call looks like
if (askYesNoQuestion("Do you want instructions?")) {
// do instructions
}
// Do the rest of the app.
//
Firstly, pass the question, not the answer (you don't know the answer yet; you only know the question), so your method should look like:
private boolean askYesNoQuestion(String question)
next, loop until you get a yes or a no response:
private boolean askYesNoQuestion(String question) {
println (question);
while (true) {
String answer = // read answer
if (!answer.equalsIgnoreCase("yes") && !answer.equalsIgnoreCase("no")) {
println ("Please enter a yes or no answer.");
} else {
return answer.equalsIgnoreCase("yes");
}
}
}
If you are using Java 7, the Switch statement now supports Strings.
I mean:
switch(inputString){
case "yes": /*do something */ break;
case "no": /*do something */ break;
case "maybe": /*do something */ break;
default: /*do something */ break;
}
So based on your requirement, you can write corresponding cases. For instance, you can display the message "enter yes or no" if user inputs "maybe" or something other than "yes" or "no" (using case "maybe" and default). Ideally, "maybe" is not required. the default case is used to handle this.
You can enclose this in a do-while loop and based on your condition, choose to continue or break
I don't know about your readline method, but I assume it's valid. So your run method should be :
public String run(){
while(true) {
String answer = readLine("Would you like instruction?: ");
if (answer.equals("maybe") {
System.out.println("Please enter a yes or no answer");
}
else {
return answer;
}
}
}
So, when this method is run, it will loop until the user doesn't type "maybe" (and hope they will type yes or no).
Well...there's a lot going on here. Don't feel bad about this, but it wouldn't work in this state - the compiler would throw a lot of stuff at you. Let's look at it step by step.
Before we look at syntax, let's look at program flow. What do we want to do? From your description you want to accomplish the following:
Have a user respond to a question for instructions.
If they reply with yes, then give them the instructions and exit.
If they reply with no, then exit.
If they reply with maybe, clarify that they should only have a yes or no answer, then ask your question again.
Now, we can look at syntax to accomplish this. In general, we will need a way to capture the user's response, and use that to decide what to do next. readLine() isn't what you're going to use (since that method doesn't exist); you'll want to use Scanner. The documentation in the API should be enough to get you started.
Next, now that we have the input, we need a way to repeat if the user doesn't answer yes or no. You have a choice - either a while loop or a do...while loop will work. We would have to check whether or not our condition is met, and if it isn't, we keep going.
Third, the string "yes" is different from "Yes" and "YeS" and "YEs". Case matters with strings, so the idea to compare them would be to equalsIgnoreCase().
Fourth, the method being created should only take in a single parameter - what the response is. You don't know what that will be until you actually do work on it - which is an if else-if else-if else statement. I see no reason for that method to call itself.
Finally, you don't call the method anywhere in run! You have to do that or it won't really matter what that method does; as long as it's syntactically correct, Java will happily ignore it if it's never called.

Categories