Hangman while loop not working with || - java

I have the following while-loop for a game of Hangman I'm working on:
while(amountOfGuessesLeft > 0 || !wordComplete){
System.out.println("The word now looks like this: " + filteredWord);
System.out.println("You have " + amountOfGuessesLeft + " guesses left");
System.out.print("Your guess: ");
try {
guess = br.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(guess.length() == 0 || guess.length() > 1){
System.out.println("Please just type one letter. Try again.");
}else if(wordSelected.contains(guess) || wordSelected.contains(guess.toUpperCase())){
System.out.println("That guess is correct.");
filteredWord = showGuess(filteredWord, wordLetters, guess.toUpperCase().charAt(0));
if(!filteredWord.contains("_")){
wordComplete = true;
}
}else{
System.out.println("There are no " + guess.toUpperCase() + "'s in this word.");
amountOfGuessesLeft--;
}
}
When the while-loop condition is just amountOfGuessesLeft > 0, everything works fine. However, when I add || !wordComplete, neither condition is applied and the loop never ends. It doesn't throw any errors either. Any help would be appreciated.

You need to use &&.
You want to run the loop as long as there are any guesses left and the user hasn't found the word yet.
Currently, if you run out of guesses and still haven't found the word, !wordComplete will evaluate to true and allows the loop to be executed again.

Related

Using try, catch and a label for the first time [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
We just covered the try-catch topic in last night's lecture. It's not required to put it in this assignment, but I thought I would give it a shot.
I've been struggling with this for a while. Using a continue statement kicked it back to the start of the catch block so that the println inside it executed in a never ending loop.
So apparently there are these things called labels. I found that when I was trying to figure out how to solve the continue problem. I tried putting in a label just as I saw being done in the example code, and now it just gives me a compiler error on the break statement that says "the process flag is missing".
What am I doing wrong?
do {
// Prompt
try {
process: nbPlayers = keyboard.nextInt();
}
catch(Exception e) {
nbPlayers=0;
if (attempts<4) {
System.out.println("Incorrect input type. You have now made " + attempts +". Please enter an integer from 2 to 4.");
++attempts;
break process;
}
else {
System.out.println("Invalid input. You have now made " + attempts +". This game only allows 4 chances to input the requested number of players.\n Shutting down the program now.");
System.exit(0);
}
}
if(attempts < 4 && nbPlayers >= 2 && nbPlayers <= 4) {
valid = true;
} else if(attempts < 3) {
System.out.println("Invalid input. You have now made " + attempts +". This game only allows 4 chances to input the requested number of players.\nYou are allowed to try again.");
} else if(attempts == 3) {
System.out.println("Invalid input. You have now made " + attempts +". This game only allows 4 chances to input the requested number of players.\nYou are allowed to one more time.");
} else if(attempts == 4) {
System.out.println("Invalid input. You have now made " + attempts +". This game only allows 4 chances to input the requested number of players.\n Shutting down the program now.");
System.exit(0);
}
++attempts;
} while(!valid);
Your problem is not quite clear. Let's talk on a code.
What do you think of this ?
int attempts = 0; // is it a good initialization ?
int nbPlayers = 0; // is it a good initialization ?
boolean valid = false; // is it a good initialization ?
String nbPlayersString = "";
do {
// Prompt
try {
nbPlayersString = keyboard.nextLine();
nbPlayers = Integer.parseInt(nbPlayersString);
if(2<= nbPlayers && nbPlayers <= 4) {
valid = true;
}
else {
System.out.println("Bad Attempt " + (attempts + 1) +". Invalid number of players.");
}
}
catch(Exception e) {
nbPlayers=0;
System.out.println("Bad Attempt " + (attempts + 1) +". Wrong input type. ");
}
++attempts;
} while(!valid && attempts < 4);
if(valid)
System.out.println("GOOD JOB!");
else {
System.out.println("You have exhausted all your chances. Program will terminate!");
System.exit(0);
}
Final EDIT
It looks like you also had a cache problem with Scanner.nextInt() after entering an invalid value (string instead of integer). So, in the attempts following, the Scanner cache still had the bad value and considered it.

Last questions: Mastermind Java program

I have two questions regarding my code.
Why does is the output "Oops please enter a number between 1 and 6" when I enter a number between 1 and 6. When I try to be more specific and make an else if statement, nothing happens when I enter a number NOT between 1 and 6.
How do I restart my program? In my code, there is an if statement
when the user inputs "play again" My commented out line reads
Mastermind.main() to re run the program, but that didn't work.
Here is the code:
import java.util.Scanner;
public class Mastermind {
public static void main (String [] args) {
// boolean variable to signal when the game is over.
boolean done = false;
// Scanner object
Scanner scanner = new Scanner(System.in);
// sets the value to twelve outside the loop so it doesn't set back each time.
int guesses = 12;
System.out.println("Please enter a number between 1-6 to begin (or \"quit\") to exit.");
// while loop for the game
while (!done) {
//System.out.println("Please enter a number between 1-6 (or \"quit\") to exit the game:");
// user input
String input = scanner.nextLine();
int number = 0; //Just initialized to some number
// checks to see if the user wants to quit the game.
if (input.equalsIgnoreCase("quit")) {
System.out.println("Goodbye!");
done = true;
scanner.close();
}
else{
try{
//Trying to see if the input was a number
number = Integer.parseInt(input);
}
catch(Exception e){
//The input wasn't an integer, it's invalid the starts loop again.
System.out.println("Invalid input.");
continue;
}
}
// defines necessary int variables
int random1 = (int) (Math.random() * 7);
int random2 = (int) (Math.random() * 7);
int random3 = (int) (Math.random() * 7);
int random4 = (int) (Math.random() * 7);
// If the user doesn't and decides to play, it runs this code.
// checks to see if the user enters a number between 1-6
if (number >= 1 && number <= 6) {
if (number == random1) {
System.out.println("You guessed a correct number!");
guesses--;
System.out.println("guesses = " + guesses);
}
else if (number == random2) {
System.out.println("You guessed a correct number!");
guesses--;
System.out.println("guesses = " + guesses);
}
else if (number == random3) {
System.out.println("You guessed a correct number!");
guesses--;
System.out.println("guesses = " + guesses);
}
else if (number == random4) {
System.out.println("You guessed a correct number!");
guesses--;
System.out.println("guesses = " + guesses);
}
else {
System.out.println("Sorry that's not one of the numbers! Try again.");
guesses--;
System.out.println("guesses = " + guesses);
}
}
if (guesses == 0){
System.out.println("You've run out of guesses. To play again, enter \"play again\". Otherwise, enter or \"quit\")");
if (input.equalsIgnoreCase("play again")){
// how do I restart the program?
//Mastermind.main(); // QUESTION 2
}
else if (input.equalsIgnoreCase("quit")){
System.out.println("Goodbye!");
done = true;
scanner.close();
}
else {
System.out.println("Goodbye!");
done = true;
scanner.close();
}
}
else { //QUESTION 1
System.out.println("Oops! Please choose a number between 1 and 6");
}
}
}
}
You're printing that message every time through the loop whenever guesses == 0 evaluates to false. You probably just need to switch the order of the two blocks. Instead of this:
if (number >= 1 && number <= 6) {
...
}
if (guesses == 0) {
...
}
else { //QUESTION 1
System.out.println("Oops! Please choose a number between 1 and 6");
}
Use this:
if (number >= 1 && number <= 6) {
...
}
else { //QUESTION 1
System.out.println("Oops! Please choose a number between 1 and 6");
}
if (guesses == 0) {
...
}
Regarding restarting your program: if I'm reading the logic correctly, all you need to do is keep done set to false and reset guesses to 12.
Two other logic points. First, you should probably either continue or break after detecting that the user has entered "quit". Second, it seems like you are generating four new random integers for every user guess. I don't know if that's what you intended, but you might want to change the logic a bit. That might also affect the restart logic.

scan.next() not working inside a loop

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.

Java do while loops not looping

As far as I have read so far in my textbook for the class, in the modules for my class and in 2+ hours of searching, I cannot figure out why my code is not working.
The do while loop in the main method is working properly but the do while loops in my get methods are not looping. I put in the wrong number, I get the error message and then instead of asking for the number again, it moves on to the next get method.
I hope it is something simple that I have overlooked but I would appreciate any help I could get on this.
Here is the code for my getHome method:
public static int getHome()
{
int homeNum;
String home;
do
{
home = JOptionPane.showInputDialog(null,"Enter 1(apartment), 2(house),"
+ " or 3(dorm).","Dwelling Type", JOptionPane.QUESTION_MESSAGE);
homeNum = Integer.parseInt(home);
if(!(homeNum == 1) && !(homeNum == 2) && !(homeNum == 3))
{
JOptionPane.showMessageDialog(null, "The value for dwelling type "
+ "must be 1(apartment), 2(house), or 3(dorm)", "Dwelling"
+ "Type Error", JOptionPane.ERROR_MESSAGE);
}
return homeNum;
}
while(homeNum < 0 || homeNum > 3);
And the code in the main method that calls this method:
public static void main(String[] args)
{
String response;
do
{
petRec(getHome(), getHours());
response = JOptionPane.showInputDialog(null, "Do you want to continue?" +
"\nEnter Y for yes and anything else for no.", "Continue?", +
JOptionPane.QUESTION_MESSAGE);
}
while(response.equalsIgnoreCase("y"));
}
Just for clarification here is the petRec method:
public static void petRec(int homeType, double hoursAtHome)
{
String pet;
if(homeType == 1 && hoursAtHome >= 10)
pet = "Cat";
else
if(homeType == 1 && hoursAtHome < 10)
pet = "Hamster";
else
if(homeType == 2 && hoursAtHome >= 18)
pet = "Pot-Bellied Pig";
else
if(homeType == 2 && hoursAtHome >= 10 && hoursAtHome <= 17)
pet = "Dog";
else
if(homeType == 2 && hoursAtHome < 10)
pet = "Snake";
else
if(homeType == 3 && hoursAtHome > 6)
pet = "Fish";
else
if(homeType == 3 && hoursAtHome < 6)
pet = "Ant Farm";
else
pet = "Nothing";
JOptionPane.showMessageDialog(null, "You should get a " + pet + "!",
"Recommended Pet", JOptionPane.INFORMATION_MESSAGE);
}
Last year I took intro to Visual Basic and had infinite loops, this year I'm taking Java and can't get the loop to repeat.
The getHours method is structured almost identical to the getHome method just with different variables and wording in the prompt.
The program is supposed to display the error message when a number that is not 1, 2 or 3 is entered and then loop to ask you for the number again. It displays the error message but then goes on to ask for the hours.
Again I very much appreciate any help that can be offered. This assignment isn't due until Saturday but I only have 2 days off to work on this.
Thank you in advance for your help :)
Move the return statement to outside the loop:
public static int getHome()
{
int homeNum;
String home;
do
{
home = JOptionPane.showInputDialog(null,"Enter 1(apartment), 2(house),"
+ " or 3(dorm).","Dwelling Type", JOptionPane.QUESTION_MESSAGE);
homeNum = Integer.parseInt(home);
if(!(homeNum == 1) && !(homeNum == 2) && !(homeNum == 3))
{
JOptionPane.showMessageDialog(null, "The value for dwelling type "
+ "must be 1(apartment), 2(house), or 3(dorm)", "Dwelling"
+ "Type Error", JOptionPane.ERROR_MESSAGE);
}
}
while(homeNum < 0 || homeNum > 3);
return homeNum;
}
As it is, you are returning from the method at the end of the first loop iteration. You might also want to catch the potential NumberFormatException that can be thrown by the parseInt call.
Also, be aware that this will allow 0 to be entered. Perhaps that's by design; perhaps an oversight. I can't tell.
Welcome to Java:
do
{
...
return homeNum;
}
while(homeNum < 0 || homeNum > 3);
In Java, the following instruction all finish the current statement: the code after will never be executed or you'll get an error. You must move the return outside the loop for it to work correctly (or as intended):
do
{
...
}
while(homeNum < 0 || homeNum > 3);
return homeNum;
return : when you return a value, like in return homeNum, you exit the method in which you are.
continue : when you continue, you'll go to next iteration; this only works in a loop.
break : when you break, you'll end the execution of a loop or a switch statement. For instance, if you had put break; instead of return h omeNum; the loop would have ended here.
throw new Exception("Foobar") : when you throw an error, it will exit the current try .. catch block method up one matching the exception kind.
As an example of break, throw and continue:
public static int getHome()
{
int n = -1;
for (;;) { // infinite loop powered !
try {
String home = JOptionPane.showInputDialog(null,"Enter 1(apartment), 2(house),"
+ " or 3(dorm).","Dwelling Type", JOptionPane.QUESTION_MESSAGE);
int homeRun = Integer.parseInt(home);
if(homeNum != 1 && homeNum != 2) && homeNum != 3) {
// note: this is an example. You should NEVER use exception in these case
throw new IllegalArgumentException("Damn!");
}
n = homeRun;
break;
} catch (NumberFormatException|IllegalArgumentException e) {
JOptionPane.showMessageDialog(null, "The value for dwelling type "
+ "must be 1(apartment), 2(house), or 3(dorm)", "Dwelling"
+ "Type Error", JOptionPane.ERROR_MESSAGE);
continue;
}
}
return n;
}
This is an ugly example showing you the four instructions.
Throwing an exception in this case is bad practise. But it'll go to the catch block because it catches the NumberFormatException (from Integer.parseInt) and the thrown IllegalArgumentException.
The break could be replaced by a return homeRun;
The continue is useless in this case because there is nothing left after the try catch block.
Beside, if you are learning Java, you should perhaps read that because I think you are not doing think right. There exists GUI components that does the cumbersome work of handling input conversion for you.
Or even, instead of JOptionPane, you should rely on System.in and Scanner: it is pretty strange to execute a code in a terminal/console, then being asked in a window on some input, to then come back in the terminal/console.

My try/catch keeps catching the correct information and re asking, but only once. In Java

// this is my code. It will only spit out that last bit of information (wallet and name) the second time i put in the players number
String option;
Boolean validChoice = false;
while(!validChoice){
option = gameScanner.nextLine();
try {
selectedPlayer = Integer.parseInt(option);
if (selectedPlayer<0|| selectedPlayer>playerNames.length) {
System.out.println("Invalid choice!: Please pick another number");
}else {
validChoice = true;
}
} catch(Exception ex){
selectedPlayer = -1;
System.out.println("Invalid choice!: Please pick another number");
}
}
System.out.println("");
System.out.println("PLAYER INFO");
System.out.println("Name: " + playerNames[selectedPlayer]);
System.out.println("Wallet: " + playerWallets[selectedPlayer]);
Problem : your if condition is not correct.as you are taking array index value as input(index always starts from 0) you should always check for both greater than or equal of length instead of only greater than of length of the array.
Reason for failure: assume your playerNames array contains 5 items means length = 5. so validChoid would be between 0 to 4 as array index starts from 0.
in the code as you have given wrong condition selectedPlayer>playerNames.length if the user enters 5(invalid) which will not satisfy above condition and then goes to else block setting the validChoice to true though it is invalid choice. as soon as validChoice becomes true it comes out from the while loop.
Solution: change the if condition from this :
if (selectedPlayer<0|| selectedPlayer>playerNames.length)
to this:
if (selectedPlayer<0 || selectedPlayer >= playerNames.length)
Complete Solution:
String option;
Boolean validChoice = false;
while(!validChoice){
option = gameScanner.nextLine();
try {
selectedPlayer = Integer.parseInt(option);
if (selectedPlayer<0 || selectedPlayer>=playerNames.length) {
System.out.println("Invalid choice!: Please pick another number");
}else {
validChoice = true;
}
} catch(Exception ex){
selectedPlayer = -1;
System.out.println("Invalid choice!: Please pick another number");
}
}
System.out.println("");
System.out.println("PLAYER INFO");
System.out.println("Name: " + playerNames[selectedPlayer]);
System.out.println("Wallet: " + playerWallets[selectedPlayer]);

Categories

Resources