Method Paramaters - java

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.

Related

System.out.print("") isnt printing before the console is stopped by Scanner(System.in), e.i. cursor is just waiting

Here's the code:
private boolean getPlayerAction() {
while (player.getHandValue() < 21) {
System.out.print("Do you want to Hit or Stand?: ");
char c = getInput();
switch (c) {
case 'h' -> {
player.setCard(dealer.dealCard());
System.out.println(player.toString());
}
case 's' -> {
return true;
}
default -> System.out.println("Invalid entry, try again.");
}
}
if (player.getHandValue() > 21) {
System.out.println("Sorry. You bust.");
return false;
}
return true;
}
private char getInput() {
String input = in.nextLine();
if (!input.isEmpty()) return input.toLowerCase().charAt(0);
return 'b';
}
and here's the output:
Dealer is showing 10 with QS
You have 13 with 3H JC
It should have the prompt: "Do you want to Hit or Stand?: " where the blank line is. If I hit enter the output looks like this:
Dealer is showing 10 with QS
You have 13 with 3H JC
Do you want to Hit or Stand?: Invalid entry, try again.
Additional side note, I tried running this with println() instead of print() and it works as it should, but using print() I get the funky weirdness.
First thing I notice is that you may be well served by adding c.tolowercase() before entering the switch statement. That will guarantee that the player's choice is read in regardless of whether they type h or H (or s or S, as it may be).
I think your problem is probably in how Java handles it's System.out.print() and System.out.println() functions. It may be something to do with trying to continue your output stream with System.out.print() after it has closed the stream for that line if you used System.out.println() for your last output display (the part that tells the player their current hand)?
Unless you have a reason that you absolutely need to use .print(), I'd say just use .println() for it since you said that definitely works if you can't find a reason why .print() doesn't.
EDIT:
Maybe your issue is that .print() doesn't close the output stream, so it runs into an issue when immediately after when you try to open the input stream in what the machine sees as the middle of outputting?
You may need to flush the output to see it appear where you're hoping.
Try adding:
System.out.flush();
right after your System.out.print("Do you want to Hit or Stand?: ");
Your not showing any of the code that actually prints the statements before the print() line which is likely the code that is actually causing this issue.
Although, for your case you may need to consider calling
in.next() instead of in.nextLine() when using a print() statement instead of a println(). Thats just a guess since the other code is missing.
The code could also be optimized a lot better but, I am guessing this is some school assignment so it might not matter.

I don't know how to leave this looping structure

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);

making sure a word is a specific length

I am new here and I am making a program to allow a person to sign up for something. It takes in the username, compares it with others, and if it is unique, allows it. When they enter a password however, I don't know how to make sure the word is more than 8 digits. I need to be able to compare the password with something, and only allow the password if it is more than 8 digits or not. Thanks!
You should accept the password into a String type. Then compare it with other String using String.equals(String otherWord) method and check it's length using String.length() method as shown below :-
Scanner s=new Scanner(System.in);
boolean flag=true;
String pwd="";
while(flag) {
pwd=s.nextLine();
if(pwd.length()>8 && pwd.equals("IntendedWord"))
// set flag=false AND then continue your intended action...
else
System.out.println("Please try again");
}
The method you are looking for is String.length().
Use something like:
if (password.length() > 8) {
// password is long enough
}
Try something like this:
// Previous code gets the value for the field and stores it in String pass
if ( pass.length() > 8 )
{
// it is valid. Hash and save
}
else
{
// Not valid. Let user know and ask for reentry.
}
//etc.
You could probably put this and other checking in a validate function and call it before storage.
Let me know if there is anything else you need.
Also, two things to learn about Stack Overflow as a courtesy. Please search for questions similar to yours before posting. And second, give more information when posting so people don't have to guess at what you want/need.
you could use something like
if(password.length() > 8)
{
//some logic
}
that is, considering that you have your password as a string value.

Java won't loop properly

For some reason this program won't loop correctly, its supposed to wait for user input, then decide on weather or not it should loop.Instead, it skips the user input part, goes straight to deciding it needs to loop, then allows user input to be taken into account.
For example, it asks for a number, i type 5, then it says "would you like to go again?" "Please use either yes or no, case sensitive!" "would you like to go again?".After it has run that it will accept user input,I thought about using a sleep(2000),but I don't want it to just skip over and assume the user didn't put anything in.I am stumped! keep in mind this is my second day working with java. I am a newbie and this is only the 3rd program i am working on. I had this issue on another program but i managed to fix it just fine.However this one seems to not want to work in the same fashion despite the fact that i did framework exactly the same.
do {
System.out.println("would you like to go again?");
if (input.hasNextLine()){
again = input.nextLine();
if (again.equals("yes")){
yon2 = false;
dateconverter.main(args);
}else if (again.equals("no")){
System.out.println("good bye");
Thread.sleep(4000);
System.exit(0);
}else{
yon2 = true;
System.out.println("Please use either yes or no. caps sensative!");
}
}
} while (!(yon2 = false));
Java loops correctly. However, yon2 = false is an assignment and not a comparison.
Thus the loop is equivalent to:
do {
// ..
yon2 = false; // assign! :(
} while (!yon2);
So Java is doing exactly what it was told to do.
Now, with that out of the way, I believe the other issue is being confused about the variables usage. Consider this:
boolean askAgain = true;
do {
System.out.println("would you like to go again?");
if (input.hasNextLine()){
String again = input.nextLine();
if (again.equals("yes")){
// Finally done asking
askAgain = false;
dateconverter.main(args);
} else if (again.equals("no")){
System.out.println("good bye");
Thread.sleep(4000);
System.exit(0);
} else {
// If we're here, we still need to ask again
System.out.println("Please use either yes or no. caps sensative!");
}
} else {
// no more lines! do something sensible
System.exit(0);
}
// Loop while we need to ask again!
// Note that the negative is removed
} while (askAgain);
However, taking a second to refactor this allows for something easier to read later and avoids the dealing with a flag entirely:
boolean promptKeepPlaying (Scanner input) {
while (input.hasNextLine()){
System.out.println("would you like to go again?");
String again = input.nextLine();
if (again.equalsIgnoreCase("yes")){
return true;
} else if (again.equalsIgnoreCase("no")){
return false;
} else {
System.out.println("Please use either yes or no.");
}
}
// no more lines
return false;
}
// somewhere else
if (promptKeepPlaying(input)) {
// restart game
dateconverter.main(args);
} else {
// exit game
System.out.println("good bye");
Thread.sleep(4000);
System.exit(0);
}
You've got a bug in your program. You've accidentally written an assignment instead of an equality test.
However, the real lesson here is that you should not be writing cumbersome == and != tests involving booleans. There are simpler, more elegant and less error prone ways of writing the tests. For example, assuming that condition is a boolean.
condition == true is the same as condition
condition == false is the same as !condition
!(condition == false) is the same as condition
condition == condition2 is the same as !(condition ^ condition2)1.
There is a real benefit in taking the time to write your code simply and elegantly.
1 - This is an example where == is more elegant ... but the ^ exclusive-or operator avoids the accidental assignment trap.

Need to type "pass" twice to advance

thanks for reading this. I'm creating just a simple, generic version of blackjack using java. Everything else works completely fine, except when it asks you "hit or pass" and you type pass, you must type it twice for it to reconize it, and I cant seem to find out why. Heres my code on pastebin to make it easier to read: http://pastebin.com/GF7Rzusx
Relevant code from pastebin:
public void ask()
{
System.out.println("Hit or Pass?");
if (in.next().equalsIgnoreCase("Hit"))
{
hit();
}
if (in.next().equalsIgnoreCase("Pass"))
{
pass();
}
}
If the entered word is "Pass" it is read from standard input and then lost, it is not stored. It must be stored for it to be available again in the subsequent check:
String input = in.next();
if (input.equalsIgnoreCase("Hit"))
{
hit();
}
else if (input.equalsIgnoreCase("Pass"))
{
pass();
}
Surely you want:
public void ask()
{
System.out.println("Hit or Pass?");
String answer = in.next();
if (answer.equalsIgnoreCase("Hit"))
{
hit();
} else if (answer.equalsIgnoreCase("Pass"))
{
pass();
}
}
Each time you call in.next() it throws away the previous input and expects another token (input).
Example
Imagine what would happen if you had:
System.out.println(in.next());
System.out.println(in.next());
What would it expect as input and what would it output?
Main differences in code
Note that there are two differences in the new code:
You only call in.next() once and so only need one input, which is stored as answer.
You only check whether the answer is "Pass" if it wasn't already "Hit".
See Java Scanner.next documentation.
On row 112 you do:
in.next()
This will read one string token. So if you write pass, this function will return "pass".
The problem is that you do not save this value. Instead, you run in.next() again on row 116, which will require you to write pass yet again.
Instead you would like to store the string returned from in.next() on line 112.
It is because of the way the ask() method is structured. Since you have two if statements, in.next() gets called once when checking if the response is "hit", then a second time when checking for "pass". When you enter "pass", the first if statement calls next(), which returns "pass" and checks if that is equal to "hit", then moves on. Then when the second if statement calls next(), there is no next entry to return, so you have to enter "pass" again. This works when you enter "hit", however, since that is the first case checked.
Refactoring so ask only makes one call to next() should solve the problem.

Categories