I took an excerpt of my code that needs working on, I know its standard practice to post all of the code but I dont think its needed here.
if(playerValue > 10 && playerValue < 21){
System.out.println("Players Value so far " + playerValue + ", Do you want to draw another card? Y/N");
// input a y or n answer
decision = sob.next();
if(decision.equals("Y") || decision.equals("y")){
continue;
}else if(decision.equals("N") || decision.equals("n")){
break;
}
}
}
How how I change this statement to either accept a Y or N, as right now if I input anything bar them two character, it will continue as if I have pressed Y.
You should have an else case:
if(playerValue > 10 && playerValue < 21){
System.out.println("Players Value so far " + playerValue + ", Do you want to draw another card? Y/N");
// input a y or n answer
decision = sob.next();
if(decision.equalsIgnoreCase("Y")){
continue;
}else if(decision.equalsIgnoreCase("N")){
break;
}
else
{
//whatever you want to happen if they don't enter either y or n
}
}
}
Maybe in the else have another loop that says please enter a valid input and keep looping until they give a valid input...
Here is how you can change your code to "insist" on the user to enter a Y or a N:
static void readYesOrNo(Scanner input) {
String str;
while (true) {
str = input.next();
if (str.equalsIgnoreCase("y")) {
return true;
}
if (str.equalsIgnoreCase("n")) {
return false;
}
System.out.println("Please enter Y or N");
}
}
I put this code into a static method so that you could reuse it in other places. Now you can use this method in your code like this:
if(playerValue > 10 && playerValue < 21){
System.out.println("Players Value so far " + playerValue + ", Do you want to draw another card? Y/N");
if (readYesOrNo(sob)) {
continue;
}
break;
}
You Can Try This:
if(playerValue > 10 && playerValue < 21){
while(true){
System.out.println("Players Value so far " + playerValue + ", Do you want to draw another card? Y/N");
// input a y or n answer
decision=sob.next();
if(decision!=null && (decision.equalsIgnoreCase("y")||decision.equalsIgnoreCase("n"))){
break;
}
else{
System.out.println("please answer with Either y or n");
continue;
}
}//end of while loop
//put your code here
}
Related
I am still new to Java and as such I am still figuring some things out. I have been having issues with including code asking the user if they want to play again. I have attempted putting it in the main class in a print statement which gave me an error. After that, I attempted putting it in the Guess.java class in multpile places but I just recieved errors. I have read up on the issue and some sites have suggested a while loop but I am unsure how to implement it into my current code. I have included both the main class which is called GuessingGame.java and the Guess.java class below. Thank you for any assistance that can be provided.
GuessingGame.java
public class GuessingGame {
public static void main(String[] args) {
new Guess().doGuess();
}
}
Guess.java
class Guess {
private int answer = 0;
int tries = 0;
Scanner input = new Scanner(System.in);
int guess, i;
boolean win = false;
int amount = 10;
public Guess() {
answer = generateRandomNumber();
}
//Generate a private number between 1 and a thousand
private int generateRandomNumber() {
Random rand = new Random();
return rand.nextInt(1000) + 1;
}
public void doGuess() {
while (!win) {
System.out.println("You are limited to ten attempts."
+ " Guess a number between 1 and 1000: ");
guess = input.nextInt();
if (tries > 9) {
System.out.println("You should be able to do better!"
+ " You have hit your ten guess limit. The number"
+ " was: " + answer);
System.out.println("Do you want to play again?: ");
return;
}
if (guess > 1000) {
System.out.println("Your guess is out of the range!");
} else if (guess < 1) {
System.out.println("Your guess is out of the range!");
} else if (guess == answer) {
win = true;
tries++;
} else if (guess < answer && i != amount - 1) {
System.out.println("Your guess is too low!");
tries++;
} else if (guess > answer && i != amount - 1) {
System.out.println("Your guess is too high!");
tries++;
}
}
System.out.println("Congragulations! You guessed the number!"
+ "The number was: " + answer);
System.out.println("It took you " + tries + " tries");
}
}
You already found a good position for adding this functionality:
System.out.println("Do you want to play again?: ");
The first step now is to also tell the user what he/she should enter after that question:
System.out.println("Do you want to play again? (enter 0 for yes and 1 for no): ");
After that we need to get the user input of course:
int number;
//If the user enters e.g. a string instead of a number, the InputMismatchException
//will be thrown and the catch-block will be executed
try {
number = input.nextInt();
//If number < 0 OR number > 1
if(number < 0 || number > 1) {
//The rest of the try-block will not be executed.
//Instead, the following catch-block will be executed.
throw new InputMismatchException();
}
break;
}
catch(InputMismatchException e) {
System.out.println("Enter 0=yes or 1=no");
//Clears the scanner to wait for the next number
//This is needed if the user enters a string instead of a number
input.nextLine();
}
If you don't know about try-catch-statements yet, I suggest to read this explanation. For details about the InputMismatchException, please see the documentation.
The problem now is that the user only has one chance to enter 0 or 1. If the user makes a wrong input the program will just stop. One solution to this problem is to just put the code in a while-loop:
int number;
while(true) {
try {
number = input.nextInt();
if(number < 0 || number > 1) {
throw new InputMismatchException();
}
break;
}
catch(InputMismatchException e) {
System.out.println("Enter 0=yes or 1=no");
input.nextLine();
}
}
After this block, we can be sure that number is either 0 or 1. So now we can add a simple if-statement to check the value:
if(number == 0) {
new Guess().doGuess();
}
return;
So all in all the code looks like this:
System.out.println("Do you want to play again? (enter 0 for yes and 1 for no): ");
int number;
while(true) {
try {
number = input.nextInt();
if(number < 0 || number > 1) {
throw new InputMismatchException();
}
break;
}
catch(InputMismatchException e) {
System.out.println("Enter 0=yes or 1=no");
input.nextLine();
}
}
if(number == 0) {
new Guess().doGuess();
}
return;
Don't forget to add the following import-statements:
import java.util.Scanner;
import java.util.InputMismatchException;
import java.util.Random;
Try this. Basically, if the user responds with "yes" , we will call the function again.
if (tries > 9) {
System.out.println("You should be able to do better!"
+ " You have hit your ten guess limit. The number" + " was: " + answer);
System.out.println("Do you want to play again? (yes/no): "); // modified line
if("yes".equalsIgnoreCase(input.next())){ // newly added if block
answer = generateRandomNumber();
tries=0;
i=0;
win = false;
doGuess();
}
return;
}
I'm creating a little mini game of Hangman. The user has 10 chances to guess, but only 5 lives.
The app works, but will continue after the 5th life, even though, I was hoping it would throw the player out of that loop.
The instantiable class (Hangman.java) is working without problems.
The secret word is "julie" as described in the instantiable class.
My App class:
import javax.swing.JOptionPane;
public class HangmanApp {
public static void main(String args[]) {
String input, secret, result, playAgain;
char guess;
int i, j, k, lives;
Hangman myHangman = new Hangman();
do{
JOptionPane.showMessageDialog(null, "Hello, welcome to Hangman! You have 10 chances but only 5 lives! Best of luck");
lives = 5;
for (j = 10; j > 0; j--) {
while (lives >= 0){
input = JOptionPane.showInputDialog(null, "Please enter a letter");
guess = input.charAt(0);
//process
myHangman.setGuess(guess);
myHangman.compute();
result = myHangman.getResult();
if ((input.charAt(0) == 'j') || (input.charAt(0) == 'u') || (input.charAt(0) == 'l') || (input.charAt(0) == 'i') || (input.charAt(0) == 'e')) {
JOptionPane.showMessageDialog(null, "That letter is in the word! Current correct letters: " + result + ".");
} else {
lives--;
JOptionPane.showMessageDialog(null, "Sorry, that letter is not there. Current correct letters: " + result + ".");
}
//output
//JOptionPane.showMessageDialog(null, "Current correct letters: " + result);
};
lives = -1;
}
result = myHangman.getResult();
secret = myHangman.getSecret();
if (secret.equals(result)) {
JOptionPane.showMessageDialog(null, "Congratulations, you got it!! The word was " + secret + ".");
} else {
JOptionPane.showMessageDialog(null, "Sorry, you didn't get it, better look next time! The word was " + secret + ".");
}
playAgain = JOptionPane.showInputDialog("Do you want to play again? yes/no");
}while (playAgain.equals("yes"));
}
}
Try the following change:
while (lives > 0){
you start at 5 and then go down to 4 3 2 1 AND 0. with the change this will stop at 0
// don't need two nested cycles, you can do it in a single one
// The cycle exits if any one of the conditions fail
// max attempts exhausted or all the lives are lost
// -------------------v v------------------------
for (j = 10, lives=5; j > 0 && lives > 0 ; j--) {
// -------------------------------------^
// j - the number of attempt is decremented for each trial,
// no matter if successful or not
//... the rest of cycle logic, which will decrement the lives
// only in cases of unsuccessful attempts
}
do {
loop = false;
if (userInput.equalsIgnoreCase("Score")){
System.out.println("You have chose to input a score.\nEnter your score here: ");
score = kbInput.nextDouble();
System.out.println("What was the best possible score?");
total = kbInput.nextDouble();
finalScore = score / total * 100;
percent = (finalScore + "%");
if (finalScore >= 90){
grade = 'A';
} else if (finalScore >= 80){
grade = 'B';
} else if (finalScore >= 70){
grade = 'C';
} else if (finalScore >= 60){
grade = 'D';
} else {
grade = 'F';
}
System.out.println("You got " + percent + ". Which is a letter grade '" + grade + "'.");
loop = false;
} else if (userInput.equalsIgnoreCase("Percent")) {
System.out.println("You have chosen to input a percent.\nEnter your percent here: ");
finalScore = kbInput.nextDouble();
if (finalScore >= 90){
grade = 'A';
} else if (finalScore >= 80){
grade = 'B';
} else if (finalScore >= 70){
grade = 'C';
} else if (finalScore >= 60){
grade = 'D';
} else {
grade = 'F';
}
System.out.println("You got a letter grade '" + grade + "'.");
loop = false;
} else {
System.out.println("Sorry, I don't understand that.");
loop = true;
}
} while (loop = true);
I am fairly new to Java and I have been taking a class and doing mini projects on my own. My plan was to have the code loop back to the beginning whenever you reached the final if statement due to entering an invalid string (i.e. anything besides Score and Percent). I can't seem to figure out what is wrong, it only loop sections of the if / else statements.
You have made a classic mistake that Java newbies make. You intended to use ==, but accidentally miss-typed it as =. You could fix the typo, but there is a BETTER solution that will avoid this problem in the future.
You should not use == to test booleans. Instead, you should rewrite your code as per the following pattern:
while (loop = true) { // BUG!!!
while (loop == true) { // WRONG
while (loop) { // CORRECT
while (loop = false) { // BUG!!
while (loop == false) { // WRONG
while (!loop) { // CORRECT
This advice applies to pretty much every use of == with boolean operands. (The exception is op1 == op2 where neither op1 or op2 are boolean literals.)
UPDATE
There are also problems with the way you get input from the user.
You are not reading userInput within the loop. That might be a problem, depending on the requirements, and on whether / how it was initialized prior to the start of the loop.
If the user enters a bad floating point number, you will get an exception. This includes the case where the user enters something like "100.0 points".
You don't validate the inputs; e.g. test for negative scores, scores greater than the maximum, percentages outside of the range 0..100.
Finally, the way you are terminating the loop is clunky. It would be better to do something like this:
while (true) {
// do stuff
if (...) {
// we want to terminate the loop
break; // <<------
}
// do more stuff
}
Since you are still struggling to understand, here is a "sample solution" to the programming problem:
import java.util.Scanner;
import java.util.NoSuchElementException;
public class Example {
public static void main(String[] args) {
Scanner kbdInput = new Scanner(System.in);
String mode = "";
double percent = -1;
while (true) {
System.out.println("Enter 'score' or 'percent': ");
mode = kbdInput.next().toLowerCase();
kbdInput.nextLine();
if (mode.equals("score") || mode.equals("percent")) {
break;
}
System.out.println("I don't understand that. Try again.");
}
while (true) {
try {
if (mode.equals("score")){
System.out.println("You chose to input a score.");
System.out.println("Enter it here: ");
double score = kbdInput.nextDouble();
kbdInput.nextLine();
System.out.println("What is the best score?");
double total = kbdInput.nextDouble();
kbdInput.nextLine();
percent = score / total * 100;
if (score >= 0.0 && total > 0.0 &&
percent >= 0.0 && percent <= 100.0) {
break;
}
System.out.println("The score / best score you " +
"gave make no sense.");
} else if (mode.equals("percent")) {
System.out.println("You chose to input a percent.");
System.out.println("Enter it here: ");
percent = kbdInput.nextDouble();
kbdInput.nextLine();
if (percent >= 0.0 && percent <= 100.0) {
break;
}
System.out.println("The percent you gave is not " +
"between 0 and 100.");
}
} catch (NoSuchElementException ex) {
kbdInput.nextLine();
System.out.println("You entered an invalid number.");
}
System.out.println("Try again.");
}
if (percent >= 0.0 && percent <= 100.0) {
char grade;
if (percent >= 90){
grade = 'A';
} else if (percent >= 80){
grade = 'B';
} else if (percent >= 70){
grade = 'C';
} else if (percent >= 60){
grade = 'D';
} else {
grade = 'F';
}
System.out.println("You got " + percent +
"%. Which is a letter grade '" + grade + "'.");
}
}
}
The things to note:
I have split this into two loops. One to request and validate the "mode" of inputting the scores. And the second to actually input them. (I have inferred this was a requirement from your code. That may not be correct.)
There is a lot more validation of the inputs than in your version.
I have used kbdInput.nextLine() to "consume" unwanted input in a few places. Note that the next methods leave any input characters that they don't want or can't recognize in the input buffer. If you are not careful, the next call to nextXxxx will attempt to parse the same characters all over again.
I explicitly catch and deal with errors in entering numbers; see the exception handler.
I have moved common code to calculate and display the grade to the end.
I have changed your multi-line println statements into separate statements. There is a good reason for this.
"\n" is not always the correct way to output a line break. It depends on the execution platform
println will do it correctly, assuming that the output is destined for the same machine that the code is running on.
See also: System.out.println() vs \n in Java
Finally, this code will NOT deal with the case where the user enters an END-OF-FILE at the keyboard (e.g. ^D on Linux).
Exercise: See what happens if you do that. Work out what happens, and find an appropriate fix for it.
I'm working on a program to play the game of Go Fish. Everything works except for the scan.next() after looping through once.
Well, sometimes it works and sometimes it doesn't. Here's the code:
System.out.println(compHand.showHand());
while (!(deck.isEmpty())) {
y = 0;
while (x == 1) {
System.out.println("\nYour hand:" + userHand.showHand()+ "\nYour turn. What number do you want to match?");
guess = scan.next();
if (compHand.checkHand(guess)) {
System.out.println("Darn...here you go.");
userHand.removeNum(guess);
compHand.removeNum(guess);
userHand.showHand();
uP++;
}
else {
System.out.println("Nope! Type '1' to go fish!");
y = scan.nextInt();
if (y == 1) {
userHand.goFish();
System.out.println(userHand.showHand());
}
y = 0;
}
guess = "";
x--;
}
while (x == 0) {
System.out.println("Do you have any " + compHand.ask() + "s?");
ans = scan.next();
if (!(ans.contains("go"))) {
System.out.println("Yay!");
userHand.removeNum(ans);
compHand.removeNum(ans);
cP++;
x++;
}
else {
System.out.println("Aww...darn.");
compHand.goFish();
x++;
}
}
System.out.println("Computer's points so far: " + cP + "\nYour points so far: " + uP + "\n");
}
}
So the first time it loops through to do the user's hand, it works. Then it works for the computer's turn, but if the computer has to go fish. When it loops back up to the user's hand it skips the guess = scan.next();.
I don't know what to do...
The problems comes from the buffer. You have to free it. To do so, put a scan.nextLine() just before the closing bracket of the loop and it will free the buffer. You will be able then to enter an input.
I've made a program that asks the user for a number and then checks if it is equal, less or greater than a random number. A siple guessing game. It works perfectly but I would like to display the output on the same line as the input but I can't figure out how to do this.
Ok, I've picked a number between 1 and 100. What is your first guess?
Guess 1: 36
<
Guess 2: 50
>
Guess 3: 46
That is correct. The hidden number is 46.
This is how I want it to look like:
Guess 1: 36 <
Guess 2: 50 >
Guess 3: 46 That is correct. The hidden number is 46.
How do I do this? The cursor is moving down after the input when I use Scanner.nextInt();
This is my current code:
while (!isCorrect) {
System.out.print("Guess " + guessCount + ": ");
currentGuess = input.nextInt();
if (currentGuess == randomNumber) {
isCorrect = true;
System.out.println("That is correct. The hidden number was " + randomNumber);
}
else if (currentGuess > randomNumber) {
System.out.println(" >");
++guessCount;
}
else if (currentGuess < randomNumber) {
System.out.println(" <");
++guessCount;
}
}
That's not consistently possible. You could try echoing a \b backspace character, but that probably wouldn't work. Once the user types the new line, there is no way to take it off.
The best you are going to be able to accomplish is to re-echo the input.
while (!isCorrect) {
System.out.print("Guess " + guessCount + ": ");
currentGuess = input.nextInt();
if (currentGuess == randomNumber) {
isCorrect = true;
System.out.println("That is correct. The hidden number was " + randomNumber);
}
else if (currentGuess > randomNumber) {
System.out.println(currentGuess + " >");
++guessCount;
}
else if (currentGuess < randomNumber) {
System.out.println(currentGuess + " <");
++guessCount;
}
}
for the output:
Guess 1: 36
36 <
Guess 2: 50
50 >
Guess 3: 46
That is correct. The hidden number is 46.
If you really need to format your output like that you could try saving your input to an arraylist, clearing the screen, then printing all the previous inputs to the screen again.
List<Integer> foo = new ArrayList<Integer>();
while (!isCorrect) {
System.out.print("Guess " + guessCount + ": ");
guessCount++;
currentGuess = input.nextInt();
foo.add(currentGuess);
for(int a = 0; a < 50; a++) {
System.out.println('\n');
}
for(int i = 0; i < foo.size(); i++) {
currentGuess = foo.get(i);
System.out.print("Guess " + (i+1) + ": " + currentGuess);
if (currentGuess == randomNumber) {
isCorrect = true;
System.out.println(" That is correct. The hidden number was " + randomNumber);
}
else if (currentGuess > randomNumber) {
System.out.println(" >");
}
else if (currentGuess < randomNumber) {
System.out.println(" <");
}
}
}
To clear the screen I just printed out 50 blank lines.
A solution to clear the console is proposed here:
Java: Clear the console
however, it didn't work for me or Chris.