Java help regarding looping (do loops) - java

I'm trying to make a very basic game where you guess a number between 1-1000 using a do loop. Everything works, except when I finally make the correct guess, I am still prompted to make another guess, and when I enter the same correct guess again, the program terminates like it's suppose to.
Why do I have to make that extra guess to finally get my program to work? Am I looping around an extra time? Also, if I make a correct guess (the compiler will say I am correct then still prompt me), then a wrong guess (the compiler will tell me I'm wrong), then the correct guess again, the program will only terminate after I make the correct guess a second time.
The second do loop at the bottom is what I put in my main method. Everything above is in a method I wrote called play.
public static boolean play()
{
boolean c;
int n = 0;
do {
String input = JOptionPane.showInputDialog("Enter a number between 1-1000");
n = Integer.parseInt(input);
if (n == guess)
{
System.out.println("Correct");
c = true;
}
else if (n < guess)
{
System.out.println("Not Right");
c = false;
}
else
{
System.out.println("Not Right");
c = false;
}
guess++;
} while (c == false);
return c;
}
In main method:
do {
game1.play();
} while (game1.play() != true);

This loop runs the play method twice in each iteration of the loop :
do {
game1.play(); // first call
} while (game1.play()!=true); // second call
You are not testing the value returned by the first call, so even if it returns true, you would still call game1.play() again, which will display "Enter a number between 1-1000" again.
Replace it with:
boolean done = false;
do {
done = game1.play();
} while (!done);
This would only call play() one time in each iteration of the loop.
That said, I'm not sure why you need the outer loop.
You can just replace in with one call to game1.play(), since game1.play() will loop until the correct number is entered.

Related

while loop inside for loop, confused?

Completely new to programming, and I was doing a project and I am confused on how I can make it work. Please help me
boolean answer1 = true;
for (int i=0;i<q.questionbank.length;++i)
{ q.Question = input(q.questionbank[i]);
while(answer1 == true)
{
if (q.Question.equals(a.correctans) || (q.Question.equals(a.impossibleans) || (q.Question.equals(a.wrongans))))
{
score = printquiz(answer,score,q.Question);
answer1 = false;
}
else
{
print("Not a Valid Answer, please try again\n");
}
}
}
return score;
Over here, I have a class called questionbank and quiz. The correctans/impossibleans/wrongans are part of the quiz data type. whereas the q.question is part of questionbank. I have some question on an array in the questionbank data type. I want to use for loop to go through the questions and if the user input the correct answer, there score goes up. It works for the first question but doesnt for the second question. usually when they answer correctly, I have another method printquiz that has decision statements to tell the user if their answer is correct or wrong, and assign them points. but its not even going to that method after the first iteration of the loop. I am confused on what is going on. Please help me
This is how I would have set it up. Assume the answer to be false until you get one. Then set it to true to exit the loop.
for (int i = 0; i < q.questionbank.length; ++i) {
q.Question = input(q.questionbank[i]);
answer1 = false;
while (!answer1) {
if (q.Question.equals(a.correctans) || (q.Question.equals(a.impossibleans) || (q.Question.equals(a.wrongans)))) {
score = printquiz(answer, score, q.Question);
answer1 = true;
} else {
print("Not a Valid Answer, please try again\n");
}
}
}
The second time doesn't work, because you set answer1 to false and never set it back to true again. So the while loop is not being entered anymore (= doesn't evaluate to true anymore) after the answer1 = false line of code in the if statement has been reached the first time.
To fix this, try to put answer1 = true inside the for loop, before the while loop.

java: loop with switch only works sometimes

I'm really scratching my heard on this one. I'm new at java, and I'm having the strangest thing happen.
It's homework and I'm taking it one step at a time. My issue is the loop just keeps going and stops asking for input, just keeps looping until it terminates. My comments are largely for myself. I tried to extract what was causing my problem and post it here.
Look at the "hatColor" switch, you'll notice the way I'm making sure the user enter only from the options I have allotted. Should I be using a exception handler or something?
Anyway, in short, the problem is that if I enter something with spaces, the loop skips asking for my next input. Like, if I entered "y y y y y " to the scanner when first prompted, the program will terminate and not give me the chance to enter something else.
Please, anyone that understands this, I would really appreciate your help.
import java.util.Scanner;
public class Testing
{
static String hatColor;
public static void main(String[] args) {
gameStart();
}
public static void gameStart()
{
Scanner userInput = new Scanner(System.in);
boolean keepLooping = true;
int loopCounter = 0;
System.out.println("The game begins. You must choose between 3 different colored hats."
+ " You can type white, black, or gray.");
while (keepLooping == true)
{
hatColor = userInput.next();
switch(hatColor)
{
case "white":
System.out.println("You have chosen the path of well intentioned decisions.");
walletDrop();
//the two items below are only there in case the wallet drop somehow completes without calling another method
keepLooping = false; // stops the while loop from looping again.
break; // breaks out of the switch
case "gray":
System.out.println("You have chosen the path of free will.");
walletDrop();
keepLooping = false;
break;
case "black" :
System.out.println("You have chosen the path of personal gain.");
walletDrop();
keepLooping = false;
break;
default : //we could just copy this default chunk for later switch statements
if (loopCounter >= 3)//end program on them
{
System.exit(0);
}
System.out.println("You didn't enter a usable answer. Try again");
loopCounter++;
if (loopCounter == 3)
{
System.out.println("This program will self destruct if you enter another invalid response.");
}
}//end of switch
}//end of while
}//end of game start method
public static void walletDrop()
{
System.out.println("wallet drop successful");
}
}
So I have actually solved this right after posting. In case someone else needs to look here for help:
The issue I was experiencing was due to using the scanner method
variableToAssign = scannerName.next();
instead of
variableToAssign = scannerName.nextLine();

Issue with do-while loop

Please note that I while I am comfortable with Java, I am not exceptionally gifted nor do I know all the jargon, so please explain your answers with very little coder jargon and as much normal English, or explain what the jargon means after you use it. Also, this is my first time with Stackoverflow, so let me know if this was a decent question and give me some pointers.
I am taking an AP Computer Science class at my high school. We use Java. We were recently taught do-while loops and I just completed the "lab" that uses do-while loops, however, there is an issue.
Firstly, let me explain the lab. The program generates a random integer between 1-10 which the user must guess (guess is stored as an int using a scanner), there are a few integer values which track number of guesses, how many guesses were greater than the computer integer, and how many were too low. When you look at my code, you will notice that I have a System.out.println(compGen);//compGen is the computer generated int. The purpose was to test the code.
The issue is in the if-statement that compares userGen (user guess) and compGen.
if(userGen==compGen)
{
//do a lot of stuff
}
In this if-statement, it is not printing the correct SOPs that I have written IF the user guesses more than once. HOWEVER, I did not write this into the program, it seems to do it on its own. I used the SOP I mentioned early where the compGen int is printed, and I typed that in as my first guess and it worked perfectly. Everything in the if-statement block executed perfectly and printed everything correctly. However, when I did it as my second guess, third guess, or any guess that was not the first one, NOTHING was printed. See code below and run it. I don't believe this should make a difference, but the IDE that I use is Eclipse, hence the package statement. Please help.
package Chapter_3.Lab03_Chapter3;
import java.util.*;
public class Guess
{
public static void main(String[] args)
{
Scanner userInput = new Scanner(System.in);//Scanner
int compGen = (int)(Math.random()* 10 + 1);//compGen is computer number
System.out.println(compGen); //USED TO VERIFY FAILURE. VALUE WAS ENTERED TO TEST CODE
int guessTrack = 0;//tracks number of guesses
int tooHighTrack = 0;//CREATING INTS TO TRACK STUFF
int tooLowTrack = 0;
System.out.println("Welcome to the integer guessing game that everyoone loves!");//PROMPT
System.out.println("Please enter your guess for the integer. Remeber, it is between one and ten.");//GREETING
int userGen = userInput.nextInt();//USER GUESS
do
{
guessTrack++;//Increase guess value
if(userGen > compGen)//checks user value in relation to computer generated int
{
System.out.println("Try again! Your guess was too high!");//inform user of bad guess
userGen = userInput.nextInt();//new guess
tooHighTrack++;//if guess is too high, this int tracker increases
}
else if(userGen < compGen)//checks user value in relation to computer generated int
{
System.out.println("Try again! Your guess was too low!");//inform user of guess
userGen = userInput.nextInt();//new guess
tooLowTrack++;//increases if user guess is too low
}
else if(userGen==compGen)//if both values are equivalent, execute THIS IS THE PROBLEM STATEMENT!!
{
System.out.println("Great job! You guessed the right number!");//congratulate
if(guessTrack>1)
{
System.out.println("It took you: "+guessTrack+" guess to get the right answer.");//print guess tracked int
}
else
{
System.out.println("It took you: "+guessTrack+" guesses to get the right answer.");//print guess tracked int
}
System.out.println(tooHighTrack +" guesses were too high and "+ tooLowTrack+ " were too low.");//print how many guess were too big or too low
System.out.println("HELLO"); //Used to verify failure of code
userInput.close();//close scanner object
}
}
while (userGen != compGen);//condition to be ultimately checked
}
}
I haven't been able to figure out what is wrong. At one point I deleted the entire if-statement and re-typed it (I knew it wouldn't do anything, but I had to try). This issue makes no sense to me. There are no errors or anything that pop up, nothing pops up on the console which scares me a little. Thanks in advance.
First off, a lot of text you put here. Maybe try to minimize the problem next time as a suggestion ;) Otherwise everything is fine
To your problem. Let me minimize your code and then explain to you, what happens.
1. The Code
int val = scanner.nextInt();
do {
if (val < 5) {
// too low
val = scanner.nextInt();
} else if (val > 5) {
// too high
val = scanner.nextInt();
} else {
// correct
// THIS CODE DOESN'T RUN?!
}
} while (val != 5);
2. What does your code do?
You read your first number before your loop. That's fine. Then, you enter an if-elseif-else statement. Note, that once inside one of those blocks, the other blocks won't get executed. Now the problem is, that you read your next user inputs inside of the if-elseif! The program reads the next value and leaves the whole if-elseif-else. Your code does not execute, because the loop then ends before the next iteration, therefore the correct user input is not going through the if-elseif-else at all.
3. The solution
Remove all nextInt() reads and just have one as the first thing inside the loop:
int val;
do {
val = scanner.nextInt();
if (val < 5) {
// too low
} else if (val > 5) {
// too high
} else {
// correct
// THIS CODE RUNS NOW!
}
} while (val != 5);
Such things, structures that need to do something at least once before checking the loop condition, are usually done with do while loops rather than while loops
You are setting user input during the loop, and it is then checked afterwards. Try moving the body of the else if(userGen==compGen) block to after the loop like this:
public static void main(String[] args)
{
Scanner userInput = new Scanner(System.in);//Scanner
int compGen = (int)(Math.random()* 10 + 1);//compGen is computer number
System.out.println(compGen); //USED TO VERIFY FAILURE. VALUE WAS ENTERED TO TEST CODE
int guessTrack = 0;//tracks number of guesses
int tooHighTrack = 0;//CREATING INTS TO TRACK STUFF
int tooLowTrack = 0;
System.out.println("Welcome to the integer guessing game that everyoone loves!");//PROMPT
System.out.println("Please enter your guess for the integer. Remeber, it is between one and ten.");//GREETING
int userGen = userInput.nextInt();//USER GUESS
do
{
guessTrack++;//Increase guess value
if(userGen > compGen)//checks user value in relation to computer generated int
{
System.out.println("Try again! Your guess was too high!");//inform user of bad guess
userGen = userInput.nextInt();//new guess
tooHighTrack++;//if guess is too high, this int tracker increases
}
else if(userGen < compGen)//checks user value in relation to computer generated int
{
System.out.println("Try again! Your guess was too low!");//inform user of guess
userGen = userInput.nextInt();//new guess
tooLowTrack++;//increases if user guess is too low
}
}
while (userGen != compGen);//condition to be ultimately checked
//The numbers have matched since it exited the loop.
System.out.println("Great job! You guessed the right number!");//congratulate
if(guessTrack>1)
{
System.out.println("It took you: "+guessTrack+" guess to get the right answer.");//print guess tracked int
}
else
{
System.out.println("It took you: "+guessTrack+" guesses to get the right answer.");//print guess tracked int
}
System.out.println(tooHighTrack +" guesses were too high and "+ tooLowTrack+ " were too low.");//print how many guess were too big or too low
System.out.println("HELLO"); //Used to verify failure of code
userInput.close();//close scanner object
}
The while condition is checked as soon as the program reaches the end of the code inside the loop. So suppose they enter the wrong number; the program says it's too low or too high, and then asks for another number:
userGen = userInput.nextInt();//new guess
Now suppose this new number is the correct one. The program finishes your if statement, then gets to the end of the loop. Then, at that point, userGen is equal to compGen. So the while condition fails, and the program exits the loop immediately, without ever getting to the code that prints the results.
One way to solve it would be to move the logic for userGen == compGen, that prints the results, outside the loop--that is, after the end of the loop. That way, it will be executed whenever the loop is exited. Note that when you exit the loop, we know that userGen == compGen, because if it weren't, the loop would go back.
Let's say the computer generated number was 3, and you guess 5.
5>3, so the if(userGen > compGen) statement executes:
System.out.println("Try again! Your guess was too high!");//inform user of bad guess
userGen = userInput.nextInt();//new guess
tooHighTrack++;//if guess is too high, this int tracker increases
you print the message, get a new guess, then increment your counter... but when you get the new guess, say it was the correct answer 3, userGen is now equal to CompGen (both are 3) and now the
while condition is evaluated:
while (userGen != compGen)
this is now false because userGen == compGen (both are 3). Your code never gets a chance
to print the correct message because the loop exits before it can happen. hope that helps
Your userGen is not being checked after every user input.
The problem is that you have your check inside an else-if block, which will check the end of the while statement before it loops back through again.
If you change
else if(userGen==compGen)
to
if(userGen==compGen)
then because it is not apart of the if-else block, it will be checked after every input (before the while condition is checked)
Alternatively you could move your user-input to the start of the do-while block like so:
package Chapter_3.Lab03_Chapter3;
import java.util.*;
public class Guess
{
public static void main(String[] args)
{
Scanner userInput = new Scanner(System.in);//Scanner
int compGen = (int)(Math.random()* 10 + 1);//compGen is computer number
System.out.println(compGen); //USED TO VERIFY FAILURE. VALUE WAS ENTERED TO TEST CODE
int guessTrack = 0;//tracks number of guesses
int tooHighTrack = 0;//CREATING INTS TO TRACK STUFF
int tooLowTrack = 0;
System.out.println("Welcome to the integer guessing game that everyoone loves!");//PROMPT
System.out.println("Please enter your guess for the integer. Remeber, it is between one and ten.");//GREETING
int userGen = -1;//USER GUESS
do
{
userGen = userInput.nextInt();
guessTrack++;//Increase guess value
if(userGen > compGen)//checks user value in relation to computer generated int
{
System.out.println("Try again! Your guess was too high!");//inform user of bad guess
userGen = userInput.nextInt();//new guess
tooHighTrack++;//if guess is too high, this int tracker increases
}
else if(userGen < compGen)//checks user value in relation to computer generated int
{
System.out.println("Try again! Your guess was too low!");//inform user of guess
userGen = userInput.nextInt();//new guess
tooLowTrack++;//increases if user guess is too low
}
else if(userGen==compGen)//if both values are equivalent, execute THIS IS THE PROBLEM STATEMENT!!
{
System.out.println("Great job! You guessed the right number!");//congratulate
if(guessTrack>1)
{
System.out.println("It took you: "+guessTrack+" guess to get the right answer.");//print guess tracked int
}
else
{
System.out.println("It took you: "+guessTrack+" guesses to get the right answer.");//print guess tracked int
}
System.out.println(tooHighTrack +" guesses were too high and "+ tooLowTrack+ " were too low.");//print how many guess were too big or too low
System.out.println("HELLO"); //Used to verify failure of code
userInput.close();//close scanner object
}
}
while (userGen != compGen);//condition to be ultimately checked
}
}
This will cause your if-else block to be checked everytime a user inputs data before the conditions for the do-while are checked.

Trouble with creating Battleship using Java

The following block of code is supposed to check if the coordinates that the user entered are the coordinates of the ship. The ship is located on a two dimensional array at (1,1) and (1,2).
The problem started when I surrounded the getUserGuess method implementation with a while loop. The loop checks if the ship is still alive and will keep asking for the user to enter coordinates until the ship is sunk. However, as soon as the user enters either pair of the correct coordinates, the entire ship is sunk.
I have no idea why this keeps happening. As soon as I comment out the loop, the problem stops, but the loop is necessary.
Here is the method:
public void checkResult(String userGuess) {
while (frigateIsAlive == true) {
if (userGuess.equalsIgnoreCase(board[1][1])){
System.out.println("hit!");
numOfHitsOnFrigate++;
board[1][1] = " *";
createBoard();
}
if (userGuess.equalsIgnoreCase(board[1][2])) {
System.out.println("hit!");
numOfHitsOnFrigate++;
board[1][2] = " *";
createBoard();
}
else if (numOfHitsOnFrigate == 2) {
System.out.println("Enemy frigate has been sunk!");
frigateIsAlive = false;
break;
}
else {
System.out.println("miss!");
// try again
}
}
}
public String getUserGuess()
{ // takes the users guess
System.out.println("Choose a coordinate on the board to fire at");
int x = input.nextInt();
int y = input.nextInt();
String userGuess = board[x][y];
return userGuess;
}
Let me know if you need to see any other part of the code in order to better assist me.
This method is flawed :
If userGuess matches board[1][1], the loop will make you increment numOfHitsOnFrigate twice, and then you'll change frigateIsAlive to false and exit.
If userGuess matches board[1][2], the loop will make you increment numOfHitsOnFrigate infinite times and you'll never exit.
If userGuess doesn't match, the loop will never terminate, and keep printing miss! without getting new input.
You need to remove the loop, since this method checks a single userGuess, and change the conditions :
public void checkResult(String userGuess) {
if (userGuess.equalsIgnoreCase(board[1][1])){
System.out.println("hit!");
numOfHitsOnFrigate++;
board[1][1] = " *";
createBoard();
} else if (userGuess.equalsIgnoreCase(board[1][2])) {
System.out.println("hit!");
numOfHitsOnFrigate++;
board[1][2] = " *";
createBoard();
} else {
System.out.println("miss!");
// try again
}
if (numOfHitsOnFrigate == 2) {
System.out.println("Enemy frigate has been sunk!");
frigateIsAlive = false;
}
}
Based on what you wrote - I surrounded the getUserGuess method implementation with a while loop. - you have another loop which keeps getting input from the user. That other loop, whose code you haven't shown us, is necessary, since without it the game won't progress.
What you probably want (pseudo-code):
start (of a loop)
ask user for a guess
check result for the guess
sunk => stop / not sunk => continue to start
(i.e. you misplaced your while loop)

Repeated Addition

I just got a task asking me to do repeated addition from 1 to 21, as follows :
1,4,6,9,11,14,16,19,21
and get the total.
I tried this code but it returned to be a +2 addition, and it even bypass the prerequisite of bil<=21
public class test
{
public static void main(String[]args)
{
int bil=1;
long total=0;
boolean mult = true;
for(bil=1; bil<=21;bil++)
{
if(mult=true)
{
bil+=1;
mult=false;
}
else if(mult=false)
{
bil+=2;
mult=true;
}
System.out.println(bil);
total=total+bil;
}
System.out.println("----+");
System.out.println(total);
}
}
(if it's TL;DR)
Basically the request is 1+4+6+9+11+14+16+19+21=?
I can't seem to get these code to work, please help me?
EDIT : Thanks guys I got it now :D
You need boolean mult = false; so that the first time the loop runs, bil is incremented by 3 and not 2.
First, you are not comparing your boolean with ==. Therefore, every time the for() loop executes, the first block will be the one that enters since mult = true will always store true in mult... and then qualify that if() block to run.
If this assignment wasn't intentional, then you need to change it to == and also put some logic in your loop to toggle mult appropriately.
Basically when it runs through the first loop it only adds one because of the state of the boolean but also there should be an == operator to check instead of just an =
Try this:
for (bil = 1; bil < 21; bil++) {
if (bil % 2 == 0) { // If bil is divisible by 2, then add 2
bil += 2;
continue;
}
bil += 3;
}

Categories