Implementing try-catch block with throw statements - java

In a guessing game I have to make, I need to include a try-catch block with two catch clauses (one multi catch block for my two custom exceptions: BadGuessException and TooManyGuessesException, and one block for NumberFormatException).
I tried creating conditions in my program to throw my custom exceptions, because I don't know the logic behind how else they would work properly. I am having compilation errors, and would like help re-working my program so that it implements the try-catch-catch block properly.
My custom exception classes:
public class BadGuessException extends Exception
{
/**
* no-arg constructor
*/
public BadGuessException()
{
super("Sorry, that was an invalid guess!");
}
/**
* parametrized constructor
* #param message String message passed to super class's constructor
*/
public BadGuessException(String message)
{
super(message);
}
}
public class TooManyGuessesException extends Exception
{
/**
* no-arg constructor
*/
public TooManyGuessesException()
{
super("Sorry, too many guesses!");
}
/**
* parametrized constructor
* #param guess integer value representing amount of guesses (turns)
*/
public TooManyGuessesException(int guess)
{
super("Sorry, you guessed " + guess + " times!");
}
}
My program, which is having compilation errors:
import java.util.Random;
import java.util.*;
public class GuessingGame throws NumberFormatException
{
public static void main(String[] args)
{
//Scanner object to receive user input
Scanner keyboard = new Scanner(System.in);
//Create Random class object & random variable
Random rng = new Random();
int n = rng.nextInt(10 - 1 + 1) + 1;
//Initialize incrementor for guessing turns
int turn = 1;
//Create variable for user input (guess)
int guess;
try
{
while(guess != n)
{
//Exception handling for more than five turns
if(turn > 5)
throw new TooManyGuessesException();
//Prompt user to enter their guess
System.out.println("Guess a number between 1 and 10 inclusive.");
System.out.println("Hint: the answer is " + n);
//Receive user input (their guess)
guess = keyboard.nextInt();
//Increment turn variable
turn++;
if(guess < 1 || guess > 10)
throw new BadGuessException();
else if(guess == n)
System.out.println("YOU WIN!\nIt took you " + turn + " attempts.");
}
}
catch(BadGuessException e | TooManyGuessesException e)
{
e.getMessage();
}
catch(NumberFormatException e)
{
System.out.println("Sorry, you entered an invalid number format.");
}
}
}

Make the changes in the GuessingGame class Remove e after BadGuessException in multiple try block. and initialize guess with 0 and remove the NumberformatException from your class declartion;
import java.util.Random;
import java.util.*;
public class GuessingGame
{
public static void main(String[] args)
{
//Scanner object to receive user input
Scanner keyboard = new Scanner(System.in);
//Create Random class object & random variable
Random rng = new Random();
int n = rng.nextInt(10 - 1 + 1) + 1;
//Initialize incrementor for guessing turns
int turn = 1;
//Create variable for user input (guess)
int guess = 0 ;
try
{
while(guess != n)
{
//Exception handling for more than five turns
if(turn > 5)
throw new TooManyGuessesException();
//Prompt user to enter their guess
System.out.println("Guess a number between 1 and 10 inclusive.");
System.out.println("Hint: the answer is " + n);
//Receive user input (their guess)
guess = keyboard.nextInt();
//Increment turn variable
turn++;
if(guess < 1 || guess > 10)
throw new BadGuessException();
else if(guess == n)
System.out.println("YOU WIN!\nIt took you " + turn + " attempts.");
}
}
catch(BadGuessException | TooManyGuessesException e)
{
e.getMessage();
}
catch(NumberFormatException e)
{
System.out.println("Sorry, you entered an invalid number format.");
}
}
}

Related

How to handle java exception InputMismatchException along with custom exceptions?

I'm making a simple program that is a guessing game all you need to do is guess the random number. As long as your not getting the correct answer it will keep asking for input.
I created two exceptions which is thrown if the input value is high or low which works.
I also needed to use another exception which is InputMismatchException but when its used its giving me an infinite loop. Instead of asking the user for input it just skips directly to the InputMismatchException. How do I get it to work with my custom exceptions?
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
final int min = 1, max = 50;
final int random = (int) Math.floor(Math.random() * (max - min + 1) + min);
boolean status = false;
int count = 0;
while (status != true) {
try {
System.out.println("Guess a number from 1 to 50: ");
int answer = scan.nextInt();
if (answer < random) {
throw new InputTooLowException("");
} else if (answer > random) {
throw new InputTooHighException("");
} else if (answer == random) {
System.out.println("\n" + "Congratulations! You got it in " + count + " attempt/s");
status = true;
}
} catch (InputTooLowException e) {
System.out.println("Too low. Try again.");
status = false;
count = count + 1;
} catch (InputTooHighException e) {
System.out.println("Too high. Try again.");
status = false;
count = count + 1;
} catch (InputMismatchException e) {
System.out.println("Invalid Input");
status = false;
}
}
}
}
This program works for me.
Again, I want to highlight that this is a bad/non-idiomatic use of Exceptions.
I highly recommend Joshua Blochs famous Book "Effective Java". Chapter 10, Item 69 is about this: "Use exceptions only for exceptional conditions".
The Carnegie Mellon University Software Engineering Institute also has this in their coding guidelines.
Now regarding the infinite loop: I didn't realize that InvalidInputException is not one of your custom Exceptions, but from java.util and thrown by scan.nextInt.
The documentation of Scanner says:
When a scanner throws an InputMismatchException, the scanner will not pass the token that caused the exception, so that it may be retrieved or skipped via some other method.
That means, if you type in text, not a number, Scanner will let you know, but not simply throw away the input. You have to handle it yourself. E.g., by calling next. I have added a check hasNext here. A user could press Ctrl+d which means something like "End of File" (EOF). This closes the input stream. My check prevents an error here, but your call to nextInt may then throw a NoSuchElementException. This should be handled in real code, but I doubt your professor will notice.
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
final int min = 1, max = 50;
final int random = (int) Math.floor(Math.random() * (max - min + 1) + min);
boolean status = false;
int count = 0;
while (status != true) {
try {
System.out.println("Guess a number from 1 to 50: ");
int answer = scan.nextInt();
// Note that this is a _terrible_ use of Exceptions
// and _bad practice_.
if (answer < random) {
throw new InputTooLowException("");
} else if (answer > random) {
throw new InputTooHighException("");
} else if (answer == random) {
System.out.println("\n" + "Congratulations! You got it in " + count + " attempt/s");
status = true;
}
} catch (InputTooLowException e) {
System.out.println("Too low. Try again.");
count = count + 1;
} catch (InputTooHighException e) {
System.out.println("Too high. Try again.");
count = count + 1;
} catch (InputMismatchException e) {
System.out.println("Invalid Input");
// Check if there actually is an invalid token
if (scan.hasNext()) {
// Discard invalid token
scan.next();
}
}
}
}
// Defining Exceptions here, but could do it in their own files.
private static class InputTooHighException extends Exception {
public InputTooHighException(String msg) { super(msg); }
}
private static class InputTooLowException extends Exception {
public InputTooLowException(String msg) { super(msg); }
}
}

How to display error message instead of java exception?

I am trying to make a Guessing Game for a Java assignment, I have everything I need except exception handling, you see I'm trying to make it display an error message instead of displaying Exception in thread "main" java.util.InputMismatchException when someone tries to enter a numerical number in alphabetical form. The code I have is followed.
(I know I need a try and catch but I don't know what to put exactly.)
package guessNumber;
import java.util.Scanner;
public class GuessNumberApp {
public static void main(String[] args) {
final int LIMIT = 10;
System.out.println("Guess the number!");
System.out.println("I'm thinking of a number from 1 to " + LIMIT);
System.out.println();
// get a random number between 1 and the limit
double d = Math.random() * LIMIT; // d is >= 0.0 and < limit
int number = (int) d; // convert double to int
number++; // int is >= 1 and <= limit
// prepare to read input from the user
Scanner sc = new Scanner(System.in);
int count = 1;
while (true) {
int guess = sc.nextInt();
System.out.println("You guessed: " + guess);
if (guess < 1 || guess > LIMIT) {
System.out.println("Your Guess is Invalid.");
continue;
}
if (guess < number) {
System.out.println("Too Low.");
} else if (guess > number) {
System.out.println("Too High.");
} else {
System.out.println("You guessed it in " + count + " tries.\n");
break;
}
count++;
}
System.out.println("Bye!");
}
}
try something like that:
try {
int guess = sc.nextInt();
} catch(InputMismatchException e) {
System.out.println("some nice error message");
continue;
}
This would replace
int guess = sc.nextInt();

Java classes and calling variables in other classes

I'm still fairly new in java programming and I've gotten some aspects down but the classes within Java are by far giving me the most trouble. What I'm trying to do is make a random number game where the player has to pick a number 1 through 10 and if it's wrong then try again and have the program record how many times they guessed (but not add to the number of guess when a number has been picked previously or if the number that was picked is outside the specified range) I have already worked out the logic code and was trying to make a class specifically for just the logic and a class that is specifically just for the I/O interface. But I'm having one heck of a time. Any input or tips will be very appreciated and I will provide the code that I already have below:
This is the Logic class where I want it to handle all the logic
package guessapp;
import java.util.HashSet;
import java.util.Scanner;
public class GuessLogic {
public static int Logic() {
HashSet<Integer> hs = new HashSet<>();
int GuessLogic = (int) (Math.random() * 10 + 1);
Scanner keyboard = new Scanner(System.in);
int A;
int guess;
int NumGuess = 1;
do {
guess = keyboard.nextInt();
if (hs.contains(guess)) {
A = 1;
return A;
}
if (guess < 0 || guess > 10) {
A = 2;
return A;
}
if (guess == GuessLogic) {
A = 3;
return A; // this will stop the loop
} else if (guess < GuessLogic) {
NumGuess++;
A = 4;
return A;
} else if (guess > GuessLogic) {
NumGuess++;
A = 5;
return A;
}
hs.add(guess);
} while (true);
}
public static int getGuess() {
int guess;
Scanner keyboard = new Scanner(System.in);
guess = keyboard.nextInt();
return guess;
}
}
And this is the class I want to handle all I/O interface
import java.util.HashSet;
import java.util.Scanner;
public class GuessApp {
public static void main(String[] args) {
int r, w, y;
r = GuessLogic.Logic();
w = GuessLogic.getGuess();
int NumGuess;
NumGuess = 2;
System.out.print("Enter a guess: ");
if (r == 1) {
System.out.println("You have already entered this number");
}
if (r == 2) {
System.out.println("Your guess is out of the specified range. Please try again.");
}
System.out.println("Your guess is " + w);
if (r == 3) {
System.out.println("You got it right!! Congrats!! Total Number of Guesses: " + NumGuess);
} else if (r == 4) {
System.out.println("You are wrong!!! Hint: Guess Higher, Guess number: " + NumGuess);
} else if (r == 5) {
System.out.println("You are wrong!!! Hint: Guess Lower, Guess number: " + NumGuess);
}
}
}
Below is the modified codes. There are some general ideas:
GuessLogic should be used as an instance rather than a static class. Because you need GuessLogic to save the operations and the target number.
The while loop should be coded in main. Because GuessLogic is responsible for logic only.
The elements is Set is unique, so there is no need to count how many different number by yourself.
GuessApp:
public class GuessApp {
public static void main(String[] args) {
int r, w, y;
GuessLogic guessLogic = new GuessLogic();
while(true){
System.out.print("Enter a guess: ");
w = guessLogic.getGuess();
r = guessLogic.Logic();
if (r == 1) {
System.out.println("You have already entered this number");
continue;
}
if (r == 2) {
System.out.println("Your guess is out of the specified range. Please try again.");
continue;
}
System.out.println("Your guess is " + w);
if (r == 3) {
System.out.println("You got it right!! Congrats!! Total Number of Guesses: " + guessLogic.getNumber());
break;
} else if (r == 4) {
System.out.println("You are wrong!!! Hint: Guess Higher, Guess number: " + guessLogic.getNumber());
} else if (r == 5) {
System.out.println("You are wrong!!! Hint: Guess Lower, Guess number: " + guessLogic.getNumber());
}
}
}
}
GuessLogic:
public class GuessLogic {
HashSet<Integer> hs = new HashSet<>();
int number = (int) (Math.random() * 10 + 1);
public int getNumber(){
return hs.size();
}
public int Logic(int guess) {
if (hs.contains(guess)) {
return 1;
}
if (guess < 0 || guess > 10) {
return 2;
}
if (guess == number) {
return 3; // this will stop the loop
} else if (guess < number) {
// just add to the set. The set will guarantee that there is no repetitive item.
hs.add(guess);
return 4;
} else if (guess > number) {
hs.add(guess);
return 5;
}
return -1;
}
public int getGuess() {
int guess;
Scanner keyboard = new Scanner(System.in);
guess = keyboard.nextInt();
return guess;
}
}

Find perfect squares

I am trying to write a loop that calls a method to determine if a number entered is a perfect square. It compiles just fine so I must have a logic error, for the life of me though I can't find it. No matter the number I put in it seems to always return false, leading me to believe the problem lies inside the isPerfect() method. I however, do not know enough about java yet to know where to go from here. Here's the code I've got so far:
public class Square
{
public static void main(String[] args)
{
int input = 0; //The default value for input
Scanner keyboard = new Scanner(System.in);
while (input != -1)
{
System.out.println("Please enter a number, or enter -1 to quit");
input = keyboard.nextInt();
if (isPerfect(input) == true) //Call isPerfect() to determine if is a perfect square
{
System.out.println(input + " is a perfect square.");
}
else if(input == -1) //If equals exit code, quit
{
break;
}
else //If it is not a perfect square... it's not a perfect square
{
System.out.println(input + " is not a perfect square.");
}
}
}
public static boolean isPerfect(int input)
{
double num = Math.sqrt(input); //Take the square root of the number passed
if (((num * num) == input) && (num%1 == 1)) //If the number passed = it's roots AND has no remainder, it must be a perfect sqaure
{
return true; //Return true to the call
}
else
{
return false; //Return false to the call
}
}
}
Two potential issues.
arithmetic with doubles is inaccurate. You probably want
int num = Math.round(Math.sqrt(input));
Your test for no remainder doesn't do what you think ... (num%1 == 1) just tests whether n is odd. And you dont really need it .. all you need is if( num*num == input) { ... }
So with the program fixed, here is the entirety of the code:
import java.util.Scanner;
public class Square
{
public static void main(String[] args)
{
int input = 0; //The default value for input
Scanner keyboard = new Scanner(System.in);
while (input != -1)
{
System.out.println("Please enter a number, or enter -1 to quit");
input = keyboard.nextInt();
if (isPerfect(input) == true) //Call isPerfect() to determine if is a perfect square
{
System.out.println(input + " is a perfect square.");
}
else if(input == -1) //If equals exit code, quit
{
System.out.println("Breaking!");
break;
}
else //If it is not a perfect square... it's not a perfect square
{
System.out.println(input + " is not a perfect square.");
}
}
System.out.println("Main complete!");
}
/**
The isPerfect() method returns whether or not a number is a perfect square.
#param input The input from the keyboard scanner, passed as an argument
*/
public static boolean isPerfect(int input)
{
int num = ((int)Math.sqrt(input)); //Take the square root of the number passed, as an integer
if (num*num == input) //If the number passed = it's roots AND has no remainder, it must be a perfect sqaure
{
return true; //Return true to the call
}
else
{
return false; //Return false to the call
}
}
}
import java.util.Scanner;
class perfect
{
public static void main(String args[])
{
int count=0;
System.out.println ("enter any number");
Scanner in =new Scanner(System.in);
int n=in.nextInt();
for(int i=1;i<n;i++)
{
if(n>i*i)
{
count++;
System.out.println( i*i);
}
}
System.out.println("there are "+ count + " perfect numbers");
}
}

How to reduce code in main method by making new methods for my code?

Hi I am using Eclipse to program a game.
Basically, the user chooses 1. Even or 2. Odd
A randomly generated dice rolls. If the user lands on the choice he made (even number or odd number) he stays otherwise, he moves 5 steps back.
The user is vsing the computer. So if user is Even, computer is Odd, and vice versa
My problem is I don't know how to call this kind of method. Please look at my code and give me advice. If it can be better let me know also.
package Testing;
import java.util.Scanner;
import java.util.Random;
public class hundredsteps {
public static int playerChoice(){
System.out.println("Please choose an option below");
System.out.println("1. Even");
System.out.println("2. Odd");
Scanner input = new Scanner(System.in);
int choice = input.nextInt();
return choice;
// player set EVEN by default
}
public static int playerRoll(){
System.out.println("Press enter to roll");
Scanner input = new Scanner(System.in);
String roll = input.nextLine();
Random generator = new Random();
int dice1 = generator.nextInt(6)+1;
int dice2 = generator.nextInt(6)+1;
int sumOfDice = dice1 + dice2;
return sumOfDice;
}
public static int cpuRoll(){
Random generator = new Random();
int dice1 = generator.nextInt(6)+1;
int dice2 = generator.nextInt(6)+1;
int sumOfDice = dice1 + dice2;
return sumOfDice;
}
public static String gameWinner(int player, int cpu){
String winner = " ";
if (player == 100 && cpu == 100){
winner = " TIE ";
System.out.println("TIE GAME!!");
}else if (player == 100){
System.out.println();
winner = " player ";
System.out.println("Congratulations! You've won!");
}else if (cpu == 100){
winner = " cpu ";
System.out.println("Sorry, you lost. The computer won this round");
}
return winner;
}
public static void main(String[] args) {
int playerPosition = 0, cpuPosition = 0;
int playerRoll = 0, cpuRoll = 0;
do{
System.out.println();
playerRoll = playerRoll();
System.out.println();
System.out.println("You rolled " +playerRoll);
playerPosition = playerPosition + playerRoll;
if (playerPosition % 2 == 0){
System.out.println("You are now on step number " +playerPosition);
} else if (playerPosition % 2 != 0){
System.out.println("You landed on an odd number! You must move 5 steps back");
playerPosition = playerPosition - 5;
System.out.println("You are now on step number " +playerPosition);
}
cpuRoll = cpuRoll();
System.out.println("The computer rolled "+cpuRoll);
cpuPosition = cpuPosition + cpuRoll;
if (cpuPosition % 2 != 0){
System.out.println("The computer is now on step number " +cpuPosition);
} else if(cpuPosition % 2 == 0){
System.out.println("The computer landed on an even number! The computer moved 5 steps back");
cpuPosition = cpuPosition - 5;
System.out.println("The computer is now on step number " +cpuPosition);
System.out.println();
}
if (playerPosition > 100){
System.out.println("You rolled too high!");
System.out.println("You moved 20 steps back");
playerPosition = playerPosition - 20;
} if (cpuPosition > 100){
System.out.println("The computer rolled too high");
System.out.println("The computer moves 20 steps back");
cpuPosition = cpuPosition - 20;
}
} while (playerPosition <= 99 && cpuPosition <= 99);
gameWinner(playerPosition, cpuPosition);
}
}
Do you mean all the methods you call in main() keep throwing compile errors if they aren't static, so you "can't" call them?
If thats what you mean, you need to make some code to run/test your code. You need some objects. Java is object oriented (OO), so always think about "things" rather than "procedures/sequences of commands."
For example, make a test class, that will "contain" your "game object"
public class GameTest {
public static void main(String[] args) {
DiceGame game = new DiceGame();
}
}
Put your game in a separate class ( a whole new file):
public class DiceGame {
//all your primitive/object references
//add a constructor
public DiceGame() {
//initialize primitives/objects
play();
}
public void play() {
//game logic goes here
//the stuff you have in main() right now
//this isn't a static method, so call any other methods you want
}
//put your other methods here
}
Then run the file GameTest, not DiceGame. This is just one of several patterns you can use to get your code running.
If this is not what you mean, can you clarify your question?
You must be making this too hard for yourself. If you want all of the code from you main() in another method then make it so.
public static void main(String[] args) {
newMethod();
}
public static void newMethod() {
// All the stuff from your old main goes in here
}
I can only imagine that you don't understand static methods and why the methods you call from your main() must be static.
Alternatively, do exactly what #nexus_2006 said and put your game in it's own class and then in your main() create an instance of that class and start the game from there.
public static void main(String[] args) {
DiceGame game = new DiceGame();
game.play();
}
The main() above can even go inside DiceGame.java. Either way works fine.

Categories