I am writing a number-guessing game for my Computer Science 1100 class, one part of which is to print the number of attempts the player takes at guessing the target number. I've defined a variable tries to track that; the program increments it by one every time the player makes a guess.
The game restarts after the player guesses the number correctly, and at that point I want to reset the tries counter. I can't figure out how to do that, however, because the program increments tries each time the number is guessed. How can I do it?
import java.util.Scanner;
import java.util.Random;
public class Q2 {
public static void main(String[] args) {
Scanner kbd = new Scanner(System.in);
Random r = new Random();
System.out.println("Welcome to the Number Guessing Game");
int x=0;//defining x for later
int tries = 1;//defining tries for later
while (x!=-1) {
int y = r.nextInt(101);//defining random number 0-100
System.out.print("Guess a number between 0 and 100 or enter -1 to quit: ");
x=kbd.nextInt();//redefining x
x=kbd.nextInt();//redefining x
for (int i=1;x!=-1&&x!=y;i=1) {//for loop
if (x<-1||x>100) {//illegal condition
System.out.print("Out of bounds. Try again: ");
}
else if (x>y) {//input greater than random condition
System.out.print("The number is lower. Try again: ");
}
else if (y>x) {//random greater than input condition
System.out.print("The number is higher. Try again: ");
}
x = kbd.nextInt();//redefining x
tries+=i;//defining pattern for tries
}
if (x==y) {//input=random condition
System.out.println("Congratulations! You guessed the number in " + tries + " tries");
}
}
if (x==-1) {//quit condition
System.out.print("Thank you for playing the game!!");
}
}
}
a) Change the scope of your variable
Variables are only available in the scope they are defined in. For example
while (something) { // all code inside the loop is in an inner scope
int variable = 42;
// variable is accessible here
}
// variable is not accessible here
This means, every time the while-loop performs one iteration, variable is newly created. It is a good practice to only define variables in the scope they actually have a meaning (in this case in the while-loop).
b) Assign the variable every time anew
Another way would be to reset the variable each time it is necessary. This would result in such a design:
int variable; // variable is defined outside the inner scope
while (something) {
variable = 42;
// some code that changes variable's value
}
One possible solution would be to encapsulate your guessing game into it's own method, which will re-initialize all variables when called, and create an if condition inside of your loop if the guess is correct.
private static void guessingGame() {
Scanner scanner = new Scanner(System.in);
double randomNum = Math.random();
double tries = 0, guess = 0;
do while (!(guess == randomNum) {
System.in("What is your guess? ");
guess = scanner.nextDouble();
tries++;
if (guess == randomNum) {
System.out.println("Guessed correctly in " + tries + " tries.");
tries = 0;
}
}
}
public static void main() {
guessingGame();
}
Related
I did look at the threads pertaining to randoms and implemented them into this assignment but I have 2 questions.
1) I need my program to generate random numbers (and print them) and count the iterations. I have counting the iterations down but I don't know why the random numbers don't print out. Does it have something to do with my guess = 0? Here's an example if I'm not clear.
Example:
Enter a number: 13
85
89
73
94
13
This took 5 tries
2) I have no clue why my program always ends up stuck at one number for the answer. The program immediately ends after entering the number 86.
import java.util.*;
public class FeelingLucky {
public static void main (String [] args) {
Scanner sc = new Scanner (System.in);
int tries = 0;
int guess = 0;
Random random = new Random(1);
int num = random.nextInt(100) + 1;
System.out.print("Pick a number between 1 and 100:");
while (guess != num) {
guess = sc.nextInt();
tries++;
}
System.out.println("It took " + tries + " tries to match");
sc.close();
}
}
Random(1) uses seed in constructor which is always the same. Use just Random() - no parameter constructor.
import java.util.*;
public class FeelingLucky {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int tries = 0;
int guess = 0;
Random random = new Random(); // No seed
int num = random.nextInt(100) + 1;
System.out.print("Pick a number between 1 and 100:");
while (guess != num) {
guess = sc.nextInt();
tries++;
}
System.out.println("It took " + tries + " tries to match");
sc.close();
}
}
See Java random always returns the same number when I set the seed?
You've called nextInt() on the Random object only once, so you've only generated the one random number. Inside your loop you call nextInt() on the scanner, which is reading from System.in, so your program is halting and waiting for the user to input a number again each time around the loop.
If you want the user to enter a single number once, and then Random to keep generating numbers until they match, you'd need to swap which one is called inside the loop. To print the random numbers being generated, you'd need to add a print statement inside the loop that prints that current number.
while (guess != num) {
num = random.nextInt(100) + 1;
guess = sc.nextInt();
System.out.printf("you guessed: %d the number was %d%n",guess, num);
tries++;
}
This one will print out each time, and guess a new random number each time.
I just wanted to say first that I'm a beginner so I apologize for my (really) horrible code.
I'm creating a program where you input an int and print out the square root using a do while loop. And when you input "0" the program will stop.
How do you stop it?
public static void main(String[] args)
{
Scanner InputNum = new Scanner(System.in);
DecimalFormat formatTenths = new DecimalFormat("0.0");
do {
System.out.println("Please enter an integer.");
int sqroot = InputNum.nextInt();
double Finalsqroot = Math.sqrt(sqroot);
System.out.println("Your Square Root is: " + (formatTenths.format(Finalsqroot)));
} while (sqroot==0);
System.out.println("Closing...");
InputNum.close();
}
}
You need to test if the value entered was 0 (I would test less than or equal to zero, because the square root of a negative number is imaginary). If so, break the loop. Like,
int sqroot = InputNum.nextInt();
if (sqroot <= 0) {
break;
}
try this
public static void main(String[] args) {
Scanner InputNum = new Scanner(System.in);
DecimalFormat formatTenths = new DecimalFormat("0.0");
int sqroot = 0;
do {
System.out.println("Please enter an integer.");
sqroot = InputNum.nextInt();
double Finalsqroot = Math.sqrt(sqroot);
System.out.println("Your Square Root is: " + (formatTenths.format(Finalsqroot)));
} while (sqroot != 0);
System.out.println("Closing...");
InputNum.close();
}
I just initialize sqroot outside of your while and change == to !=
This academic exercise may demand use of a do/while loop, but if you're not constrained to using it, a for loop would also work:
public static void main(String[] args)
{
Scanner InputNum = new Scanner(System.in);
DecimalFormat formatTenths = new DecimalFormat("0.0");
System.out.println("Please enter an integer.");
for(int sqroot = InputNum.nextInt(); sqroot > 0; sqroot = InputNum.nextInt()) {
double Finalsqroot = Math.sqrt(sqroot);
System.out.println("Your Square Root is: " + (formatTenths.format(Finalsqroot)));
}
System.out.println("Closing...");
InputNum.close();
}
Your program as presented in the question has an intrinsic flaw: you ask for input and then immediately try and do something with it (calc the square root) without determining if it is suitable to use.
Switching to a for loop is one way this can be overcome, because it encourages a program flow of "ask for input", "check if input is acceptable", "use input", "repeat"
If you're constrained to using a do/while loop then you still need to follow this flow, which Elliott Frish addresses in his answer, recommending you add in the "check if input is acceptable" part as a dual purpose test of whether the input is <= 0.. Such values are not acceptable for a square root op, and you also want to end the program when you encounter them, so the test can be used to achieve both goals
Side trivia, for loops can be used pretty much exclusively:
for(;;) //same as while(true)
for(;test;) //same as while(test)
for(bool do = true; do; do = test) //same as do..while(test)
..though using while or do is probably more readable than using a for loop for the same job
Note, your while(sqroot==0) is a bug.. you don't want to continue looping while the user entered 0, you want to continue looping while they DIDN'T enter a 0...
import java.util.Scanner;
public class ex11
{
static Scanner type=new Scanner(System.in);
public static void main(String args[])
{
int fact=1;
System.out.println("Enter a natural number ");
int num=type.nextInt();
int i=1;
while(i<=num)
{
fact*=i;
i++;
}
System.out.println("Factorial of number " + num + " is " + fact);
}
}
I'm trying to place a conditional statement inside the while loop. The condition is to test for would be that of, if num is a negative number, S.O.P.("You entered a negative #"); in other words,
if(num<0)
S.O.P.("You entered a negative #");
However it doesn't print it properly.
If you check inside the loop then it will not work it will still multiply the fact. You need to make sure that the num is not negative before you start the while loop.
int num = 0;
do {
if (num<0){
System.out.println("You printed out a negative number");
}
System.out.println("Enter a natural number ");
int num=type.nextInt();
} while (num<0);
Also on a side note you should probably close your scanners when you are done using them.
The question is hard to understand but from what i read it appears you want a loop to run until a value is entered that meets your pre-condition of being positive
System.out.println("Enter a non negative number :: ");
int num = type.nextInt();
while(num < 0){
System.out.println("The number you entered was negative!");
System.out.println("Enter a non negative number :: ");
num = type.nextInt();
}
Loops like this are crucial to making sure the data that you are using is within the pre-condition of your operation which could cause DivideByZero errors or other problems. This loop should be placed before you ever use the value of num so you can make sure it is within context of your program.
The problem is that if the num is negative, it won't go inside the while loop that is because before the while loop you have initialize i=1, since any negative number is lesser than 1 the condition for while loop become false. If you want to check whether num is negative insert the if condition before the while loop as follows
import java.util.Scanner;
public class ex11
{
static Scanner type=new Scanner(System.in);
public static void main(String args[])
{
int fact=1;
System.out.println("Enter a natural number ");
int num=type.nextInt();
int i=1;
if(num < 0) {
System.out.println("You entered a negative #");
}
else{
while(i<=num)
{
fact*=i;
i++;
}
System.out.println("Factorial of number " + num + " is " + fact);
}
}
}
To answer your question .... like this:
int i = 1; // HERE
while (i <= num) {
if (num < 0) {
System.out.println("You entered a negative #");
}
fact *= i;
i++;
}
However that is not going to work.
Suppose that "num" that you read is less than zero.
At the statement labeled "HERE", we set "i" to one.
In the next statement, we test "i < num".
Since "num" is less than zero, that test gives "false" and we skip over the entire loop!
That means that your conditional statement in the loop body would not be executed ... if "num" is less than zero.
Since this is obviously homework, I will leave it to you to figure out what you should be doing here. But (HINT!) it is not putting the conditional inside the loop.
(Please note: I have corrected a number of style errors in your code. Compare your original version with mine. This is how you should write Java code.)
You basically have to check whether the number is less than 0. This is to be done while taking the input. You can just take the input inside a while loop in this manner:
System.out.println("Enter a natural #");
while(true){ //loop runs until broken
num = type.nextInt();
if(num>=0)
break;
System.out.println("Wrong input. Please enter a positive number");
}
The program control breaks out of the loop if num>=0, i.e., positive, else, it continues to the next part of the loop and displays the error message and takes the input again.
Please note that natural numbers are the ones >= 1. In your program, you are actually trying to input a whole number which is >= 0.
I am trying to create a simple program which creates a random number and asks the user to guess. It will then say higher or lower until the user guesses correct. The problem is, after the user guesses correctly the program will keep looping. I thought that putting the code into a separate method and then calling it in a while loop would work but unfortunately it was no avail. Could anyone suggest how I would correct this?
Below is my code.
package main;
public class NumberGuesser {
public static void main(String[] args) {
code mycode = new code();
while (mycode.guess != mycode.random){
mycode.codebit();
}
}
}
package main;
import java.util.Random;
import java.util.Scanner;
public class code {
Random rand = new Random();
int random = rand.nextInt(1000);
double guess;
public void codebit(){
System.out.println("Guess the number");
Scanner input = new Scanner(System.in);
Double guess = input.nextDouble();
if (guess > random){
System.out.println("Lower");
}
else if (guess < random){
System.out.println("Higher");
}
else if (guess == random){
System.out.println("Well done");
}
}
}
You are re-declaring guess within your method body, which hides your instance member.
Try removing:
Double guess = input.nextDouble();
... and replacing with:
guess = input.nextDouble();
Also non-related to your issue:
As general coding guidelines go, class names should be CamelCase
You don't need to instantiate a Scanner each time. If you experiment with your code structure, you'll be able to have more efficient usage. Just a hint, try looking for the hasNext[...] methods of Scanner.
Double guess = input.nextDouble();
You're initializing a local variable which has the same name as the field here. The field, that is checked by the main class, is never modified. Also, why do you use a double and not an int for the guess?
I think you do not have to go into a separate method here. Just put the code you have in your code class into your main method into an infinite loop. This way, you will be able to stop the program by returning when the guess is correct:
else if (guess == random) {
System.out.println("Well done");
return;
}
your global value guess never be assigned with a value except it first assign a value (that is 0) from system as global variable.
This is caused as you declared a local variable and assigning the local variable every time instead global variable as default java properties.
Removing the declaration of local variable guess can be a solution of that problem. You can solved it other ways to like assign global with local using this.guess = guess.
I'm also pretty new to Java but I would keep it simple and do it like this:
package main;
import java.util.Random;
import java.util.Scanner;
public class GuessNumber {
public static void main(String[] args) {
Random rand = new Random();
Scanner input = new Scanner(System.in);
int guess;
int randomNum;
String answer = "";
System.out.println("~ WELCOME! ~");
System.out.println("Can you guess the secret number?");
do {
System.out.print("\nPicking a number between 1-1000........ ");
randomNum = rand.nextInt(1000)+1; //number will be between 1-1000
System.out.println("Done!");
System.out.print("\nGuess the number: ");
guess = input.nextInt();
while(guess<1 || guess>1000) {
System.out.println("\nOut of range! Try again.");
System.out.print("Your guess: ");
guess = input.nextInt();
}
if(guess==randomNum)
System.out.print("You were right!");
else
System.out.println("\nWrong! Better luck next time.");
System.out.println("\nThe secret number was " + randomNum + ".");
System.out.println("Your guess was " + guess + ".");
System.out.print("\nPlay again (yes/no)? ");
answer = input.next();
if(answer.equalsIgnoreCase("no")) {
System.out.print("\nThanks for playing!");
input.close();
System.exit(0);
}
}while(answer.equalsIgnoreCase("yes"));
}
}
I don't think it's really necessary to create another class. Try it out and see what you think!
import java.util.Random;
import java.util.Scanner;
public class addinggamedowhile
{
public static void main (String[]args)
{
Random r = new Random ();
Scanner s = new Scanner(System.in);
int x = r.nextInt(20)+1;
int y = r.nextInt(20)+1;
int sum = x + y;
int guess;
System.out.println("===========");
System.out.println("Adding Game");
System.out.println("===========");
System.out.println();
int tries = 0;
for (int games = 0; games < 10; games++)
{
do
{
System.out.print (x + " + " + y + " = ");
guess = s.nextInt();
if (guess != sum && tries < 2)
{
System.out.println("Not quite. Try again!");
System.out.println();
tries++;
}
else
System.out.println("Not quite. The answer is " +sum+ ".");
System.out.println();
}
while (guess != sum);
System.out.println("Congratulations. You got it!");
System.out.println();
}
}}
I'm having trouble with this loop. I cannot get the loop to terminate when I want it to. It's supposed to last for only ten "guesses". In addition, when the user gets the question right, my else statement is also executed. The other thing is that once the user gets the question correct, or does not get the question correct in the three times it is allowed, a new set of numbers are supposed to appear. I have not been able to get that to execute properly either. I've tried different things that worked well, but the requirement for the project is to use a do while loop.
How about something like this?
do {
//your code here
} while (guess != sum && tries <= 10);
The loop will keep going until the sum is correct or the number of tries is exhausted. Increment tries by one every time the loop iterates.
Then, after completion (i.e. outside the loop), do a check to see if the guess is the correct sum or if the tries were exhausted and print out the response accordingly.
Alternatively you can use the break keyword when the guess is correct or no more tries. Also, you should probably reset your tries variable inside the outer for loop (so that it get's reset at the beginning f each game).