Code:
package FisherTCh5Sec4to5;
import java.util.Scanner;
public class FisherTCh5Sec4to5 {
public static int generateRandomInt(int lowerLimit, int upperLimit){
int range = (upperLimit - lowerLimit) + 1;
int randomInt = (int) Math.random() * range + lowerLimit;
return randomInt;
}//end generate random int
public static int collectInteger(String purpose, int minimum, int maximum){
Scanner in = new Scanner(System.in);
int userInt = 0;
boolean done = false;
do {
System.out.printf(purpose);
if (in.hasNextInt()){
userInt = in.nextInt();
if (userInt >= minimum && userInt <= maximum){
done = true;
} else System.out.printf("That number isn't in the desired range.\n");
} else System.out.printf("Sorry...I can't use that input.\n");
//Clear input stream
in.nextLine();
} while (!done);
in.close();
return userInt;
}// end method
public static void main(String[] args) {
// Variables
final int LOWER_LIMIT = 1;
final int UPPER_LIMIT = 10;
boolean done = false;
String playAgain = "";
int count = 0;
int wins = 0;
// Open input stream
Scanner in = new Scanner(System.in);
do {
// Use collectInteger to get a number
int userInput = collectInteger("Let's play a game! Try and guess my number (between 1 and 10): ", LOWER_LIMIT,
UPPER_LIMIT);
// use generateRandomInt to get a number
int randomInt = generateRandomInt(LOWER_LIMIT, UPPER_LIMIT);
// If statement to decide a win or loss
if (userInput == randomInt){
System.out.printf("Congrats you win! My number was %d.\n", randomInt);
wins++;
} else System.out.printf("Sorry...my number was %d.\n", randomInt);
// Ask user to play again
System.out.print("Would you like to continue? (\"c\" to continue \"q\" to quit): ");
playAgain = in.next();
if (playAgain.equals("c")){
done = false;
} else done = true;
count ++;
} while(done = false);
// Print and calculate win percentage
double winPercent = (wins / count) * 100;
System.out.printf("Wow! Your win percentage was %.2f%%.\n", winPercent);
// close input stream
in.close();
}//end main
}//end class
Everything is working beautifully except for the "Would you like to play again" portion. It won't let me read in the user input I think. Any ideas?
Your first call to in.close() inside collectInteger() also closes your System.in input stream. This is not reopened when you instantiate a new Scanner. Don't believe me? Test it with
System.out.println( System.in.available() ); // Inside try/catch
You have a few options...
ONE instance of Scanner inside main() – pass the scanner as an argument to collectInteger(). Inside collectInteger() you will need to replace in.close() with in.reset(). Close the scanner inside main when you no longer need it (or System.in).
Global variable - private static Scanner in = new Scanner( System.in ); – You will not need to pass it as a parameter but creates tighter coupling. Again - close it only when you no longer need System.in
Keep multiple Scanners but only close the one inside main – Not recommended but the stream will close in jvm shutdown.
I would also surround any IO operations with try/catch/finally...
try
{
// open resource
// read/write operation
}
catch( /*specific exception(s)*/ )
{
// handle exception
}
finally
{
// close resource
}
Another issue:
boolean done = false; // Currently redundant
do {
...
// Ask user to play again
System.out.print("Would you like to continue? (\"c\" to continue \"q\" to quit): ");
playAgain = in.next();
if (playAgain.equals("c")){
done = false; // Already initialized to false
} else done = true;
count ++;
} while(done = false);
Could be changed to:
boolean done = false;
do {
...
// Ask user to play again
System.out.print("Would you like to continue? (\"c\" to continue \"q\" to quit): ");
playAgain = in.next();
if (playAgain.equals("q")){ // CHANGE
done = true; // CHANGE
}
count ++;
} while(!done); // CHANGE
The line in.close(); in collectInteger closes the input from System.in. Remove that line and it should work.
Also this line: while(done = false);
Should be changed to:while(done == false); or while(!done);
Reasoning: By using one equal sign, you are setting done to false every time the loop condition is checked. This means the loop never iterates as the condition is always false.
Related
I've created many different types of method in my coding as my task requires to, so I faced some problems that I'm trying to incorporate loops that allow only 3 guesses from the user. After each round, the user has the option of whether to continue playing or to stop. How should I implement that? Also, any mistakes in my coding? Thank you in advanced!
import java.util.Random;
import java.util.Scanner;
public class GuessmyGame{
public static void main(String[] args){
Scanner in = new Scanner(System.in);
Random random = new Random();
int number = random.nextInt(100)+1;
printInstruction();
int guess = in.nextInt();
guessNum(number, guess);
numberOfTries(guessNum);
}
public static void printInstruction(){
System.out.println(" I am thinking of a number between 1 and 100.");
System.out.println(" Can you guess what it is? ");
System.out.println(" Type a number : ");
}
public static void guessNum(int number, int guess){
if (number == guess){
System.out.println("Congratulations! You got it right.");
}
else if(number > guess){
System.out.println("Your guess is too low.");
Scanner in = new Scanner(System.in);
guess = in.nextInt();
System.out.println("Your guess is: "+guess);
guessNum(number, guess);
}
else{
System.out.println( "Your guess is too high.");
Scanner in = new Scanner(System.in);
guess = in.nextInt();
System.out.println("Your guess is: "+guess);
guessNum(number, guess);
}
}
public static void numberOfTries(int guessNum){
Random random = new Random();
int number = random.nextInt(100)+1;
for(int i = 0; i < 3; i++){
System.out.println("Out of guesses!");
System.out.println("The number was " + number);
}
}
}
Use a while loop and add a boolean condition.. let's call it canContinue. You'll also need to keep track of how many times the user has attempted to guess, let's say it's called attemptCount as well as the correctness of the user's latest guess (correctGuess).
When attemptCount is 3 or correctGuess is true, prompt the user if they want to continue. If their answer suggests they don't want to continue, set canContinue to false, which causes the exit the loop and complete. Otherwise, reset attemptCount (to 0 presumably to allow another 3 attempts). The code that follows highlights the requested logic. since it's clear the code provided in the question has many bugs.
var promptToRetry = false;
while (canContinue) {
if (correctGuess) {
// Let user know their guess was correct
promptToRetry = true;
}
if (attemptCount > 2) {
// Let user know they didn't get the right number
promptToRetry = true;
}
if (promptToRetry) {
boolean wantsToTryAgain = PromptUserToTryAgain(); //Code returning bool which prompts user if they want to try again (need to implement)
if (wantsToTryAgain) {
attemptCount = 0; //Resets attempt counter
correctGuess = false; //Resets the guess
promptToRetry = false;
} else {
canContinue = false; //Causes loop to exit
}
}
...
}
}
Here is my code:
import java.util.*;
class Main {
public static void main(String[] args) {
Scanner Keyboard = new Scanner(System.in);
{
System.out.println("What is the answer to the following problem?");
Generator randomNum = new Generator();
int first = randomNum.num1();
int second = randomNum.num2();
int result = first + second;
System.out.println(first + " + " + second + " =");
int total = Keyboard.nextInt();
if (result != total) {
System.out.println("Sorry, wrong answer. The correct answer is " + result);
System.out.print("DO you to continue y/n: ");
} else {
System.out.println("That is correct!");
System.out.print("DO you to continue y/n: ");
}
}
}
}
I'm trying to keep the program to continue but if the user enters y and closes if he enters n.
I know that I should use a while loop but don't know where should I start the loop.
You can use a loop for example :
Scanner scan = new Scanner(System.in);
String condition;
do {
//...Your code
condition = scan.nextLine();
} while (condition.equalsIgnoreCase("Y"));
That is a good attempt. Just add a simple while loop and facilitate user input after you ask if they want to continue or not:
import java.util.*;
class Main
{
public static void main(String [] args)
{
//The boolean variable will store if program needs to continue.
boolean cont = true;
Scanner Keyboard = new Scanner(System.in);
// The while loop will keep the program running unless the boolean
// variable is changed to false.
while (cont) {
//Code
if (result != total) {
System.out.println("Sorry, wrong answer. The correct answer is " + result);
System.out.print("DO you to continue y/n: ");
// This gets the user input after the question posed above.
String choice = Keyboard.next();
// This sets the boolean variable to false so that program
// ends
if(choice.equalsIgnoreCase("n")){
cont = false;
}
} else {
System.out.println("That is correct!");
System.out.print("DO you to continue y/n: ");
// This gets the user input after the question posed above.
String choice = Keyboard.next();
// This sets the boolean variable to false so that program
// ends
if(choice.equalsIgnoreCase("n")){
cont = false;
}
}
}
}
}
You may also read up on other kinds to loop and try implementing this code in other ways: Control Flow Statements.
This question already has answers here:
Cant figure out how to exit the loop of my program
(3 answers)
Closed 6 years ago.
My program for class asks to run the program as long as the user doesn't enter the input of -99. When I run the program and enter a usable number that isn't -99, the console will run a continuous looping answer until I have to press end.
How can I change the program so for each input there will be one answer and the program restarts until user inputs -99?
import java.util.Scanner; //import scanner
import java.io.*; //import library
public class is_odd_or_even_number {//begin class
public static void main(String []args) {//begin main
Scanner input = new Scanner(System.in);
//use try/catch method to test for invalid input
try{
//promt user to input a value
System.out.print("Enter a positive integer value: ");
int number = input.nextInt();
//PART I NEED HELP WITH **************
while (number != -99){
//Start of if statement to test which to print and call of isEven method
if (isEven(number)) {
System.out.println("Your number is Even!");
}
else
System.out.println("Your number is Odd!");
}
}
//open catch method and print invalid
catch(Exception notNumber) {
System.out.println("Input not a number, try again.");
}
}
//begin testing for odd or even in new method
public static boolean isEven(int num){
return(num & 1) == 0;
}
}
Here, you don't let the user entry other thing that the first input before the loop.
The retrieval of the input from the user :
int number = input.nextInt();
should be in the loop.
Try that :
int number = 0;
//PART I NEED HELP WITH **************
while (number != -99){
number = input.nextInt();
//Start of if statement to test which to print and call of isEven method
if (isEven(number)) {
System.out.println("Your number is Even!");
}
else
System.out.println("Your number is Odd!");
}
}
You can do like this way ;)
System.out.print("Enter a positive integer value: ");
int number = input.nextInt();
//PART I NEED HELP WITH **************
while (number != -99){
System.out.print("Not good, please enter a new one : ");
number = input.nextInt();
}
//Start of if statement to test which to print and call of isEven method
if (isEven(number)) {
System.out.println("Your number is Even!");
}
else {
System.out.println("Your number is Odd!");
}
So it will ask until you're not writing -99 as you said, but if you're asking for "a positive int" normally nobofy would write -99 :p
End a while loop
You can use a boolean value shouldContinue to control whether the programs should continue to the next input.
if (number != -99) {
shouldContinue = true;
} else {
shouldContinue = false;
}
This can be simplified as follow:
shouldContinue = number != -99 ? true : false;
// or even shorter
shouldContinue = number != -99;
Read the value correctly
But you need to ensure that you input number is reset at each loop execution so that you can read the next number:
while (shouldContinue) {
...
number = input.nextInt();
}
Other enhancements
Do not import unused packages or classes
Use camel case for Java class name
Use comment style /** ... */ for Javadoc
Always try to avoid infinite loop, e.g. use an integer count tries and count down at each loop.
Here's the final answer look like:
import java.util.Scanner;
public class IsOddOrEvenNumber {
public static void main(String []args) {
Scanner input = new Scanner(System.in);
boolean shouldContinue = true;
int tries = 0;
while (shouldContinue && tries < 10) {
try {
System.out.print("Enter a positive integer value: ");
int number = input.nextInt();
if (isEven(number)) {
System.out.println("Your number is Even!");
} else {
System.out.println("Your number is Odd!");
}
shouldContinue = number != -99 ? true : false;
} catch (Exception notNumber) {
System.out.println("Input not a number, try again.");
}
tries--;
}
System.out.println("Game over.");
}
/**
* Begin testing for odd or even in new method
*/
public static boolean isEven(int num){
return (num & 1) == 0;
}
}
Here you are the main method which will be running as long as user is not entering -99;
You should include all your code in the while loop (even try/catch).
public static void main(String []args) {//begin main
Scanner input = new Scanner(System.in);
int number = 0;
//Keep application running as long as the input is not -99
while (number != -99){
//use try/catch method to test for invalid input
try{
//promt user to input a value
System.out.print("Enter a positive integer value: ");
number = input.nextInt();
//Start of if statement to test which to print and call of isEven method
//if the entered number is -99, the following code will skipped.
if(number == -99) continue;
if (isEven(number))
System.out.println("Your number is Even!");
else
System.out.println("Your number is Odd!");
}
//open catch method and print invalid
catch(Exception notNumber) {
System.out.println("Input not a number, try again.");
}
}
}
You could accept this answer, in case it is what you are looking for :)
I've been given the task of making a factorial calculator that takes input from 9 to 16 using a while loop. The conditions are that if the user puts in an input that is not 9 to 16 or an int, it should loop back in the beginning and ask for input again.
My code looks like this:
Scanner myScanner;
int x = 1;
int factorial=1;
int input;
myScanner = new Scanner(System.in);
System.out.println("put in an int and i will show you its factorial");
while (true) {
input = myScanner.nextInt();
if (input<9 || input >16) {
System.out.println("please enter a valid int");
}
else{
break;
}
}
for (int i=input; i >0; i--) {
factorial *= i;
}
The problem is that this isn't really using a while loop to go back to the beginning of the code. I'm really just inputting a redundant statement to make it a while loop.
So I guess my question is, how can I make a while loop that goes back to the beginning of the loop if the wrong input is typed in?
an alternative is to use a boolean value such as
boolean validInput = false;
and loop until you have valid input. that way you won't try to calculate a value when users enter -1 in the other answer
Try doing it this way:
Scanner myScanner;
int x = 1;
int factorial=1;
int input = 0;
myScanner = new Scanner(System.in);
System.out.println("Put in an integer value between 9 and 16 and I will show you its factorial. Type -1 to exit.");
while (input != -1) {
//Try block for handling invalid string inputs
try {
input = myScanner.nextInt();
} catch (Exception e){
input = 0;
}
if (input<9 || input >16) {
System.out.println("please enter a valid int");
}
else {
for (int i=input; i >0; i--) {
factorial *= i;
//input = -1; //Optionally end here if that's how things are intended to function
}
System.out.println(factorial);
}
}
Initialize the input with a value (0). And inform the user if they type in a certain value (i.e. -1) the loop ends. Move your for loop in the else block and set the while condition as input != 1.
Alternatively, if you want the program to end if the user supplies a valid value, then in the else block, set the input value to -1 manually, or just break out of the loop using the break keyword.
I want the user to enter integers into an array. I have this loop I wrote which has a try and catch in it, in case a user inserts a non integer. There's a boolean variable which keeps the loop going if is true. This way the user will be prompted and prompted again.
Except, when I run it, it gets stuck in a loop where it repeats "Please enter # " and "An Integer is required" without letting the user input a new number. I reset that number if an exception is caught. I don't understand.
import java.util.*;
public class herp
{
//The main accesses the methods and uses them.
public static void main (String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("Hello and welcome!\n");
System.out.print("This program stores values into an array"+" and prints them.\n");
System.out.println("Please enter how many numbers would like to store:\n");
int arraysize = scan.nextInt();
int[] mainarray = new int[arraysize+1];
int checkint = 0;
boolean notint = true;
int prompt = 1;
while (prompt < mainarray.length)
{
// Not into will turn true and keep the loop going if the user puts in a
// non integer. But why is it not asking the user to put it a new checkint?
while(notint)
{
try
{
notint = false;
System.out.println("Please enter #"+ prompt);
checkint = scan.nextInt();
}
catch(Exception ex)
{
System.out.println("An integer is required." +
"\n Input an integer please");
notint = true;
checkint = 1;
//See, here it returns true and checkint is reset.
}
}
mainarray[prompt] = checkint;
System.out.println("Number has been added\n");
prompt++;
notint = true;
}
}
}
Once the scanner has thrown an InputMismatchException it cannot continue to be used. If your input is not reliable, instead of using scanner.nextInt() use scanner.next() to obtain a String then convert the string to an int.
Replace:
checkint = scan.nextInt();
With:
String s = scan.next();
checkint = Integer.parseInt(s);
I have corrected it like below. I don't rely on exception, but check if the next Scanner input is int (using hasNextInt()). If not int, just consume Scanner token and wait for the next user input.
Looks like it is working, apart from 0 being inserted as a first array element, because you started indexing prompt from 1.
public class Herp {
//The main accesses the methods and uses them.
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Hello and welcome!\n");
System.out.print("This program stores values into an array" + " and prints them.\n");
System.out.println("Please enter how many numbers would like to store:\n");
int arraysize = scan.nextInt();
int[] mainarray = new int[arraysize + 1];
int checkint = 0;
boolean notint = true;
int prompt = 1;
while (prompt < mainarray.length) {
while (notint) {
notint = false;
System.out.println("Please enter #" + prompt);
// check if int waits for us in Scanner
if (scan.hasNextInt()) {
checkint = scan.nextInt();
} else {
// if not, consume Scanner token
scan.next();
System.out.println("An integer is required."
+ "\n Input an integer please");
notint = true;
}
}
mainarray[prompt] = checkint;
System.out.println("Number has been added\n");
prompt++;
notint = true;
}
for (int i : mainarray) {
System.out.print(i + " ");
}
}
}