Why is the if statement not evaluated every loop - java

Ok I am making a simple text based game and I am unsure why and infinite loop is being created. Its not really infinite but I am unsure why the if statement is not evaluated every loop. Here is the whole program. The if Statement I need fixed is in the roomEight method which is at the end of the code.
//********************************
// A simple game that moves the
// player though the map
//********************************
import java.util.*;
import java.text.*;
public class mazegame
{
private static Scanner scan = new Scanner (System.in); // starts scanner for the program
public static Scanner scanS;
// ScanS is a scanner for strings.
// To call this variable type mazegame.scanP;
public static int lifeCount = 15;
public static int damage = 1;
// imp stats
public static int impAmount = 0;
public static int impDamage = 1;
public static int impLife = 1;
// Low level monster stats
// m followed by a number stands for monster then the level of monster
public static int m1health = 5;
public static int m1damage = 2;
// High level monster
public static int m2health = 10;
public static int m2damage = 2;
// Boss stats
public static int bosshealth = 30;
public static int bossdamage = 10;
// Placement of player
public static int placement = 3;
public static String movement;
public static int scanVal; // holder a scanner value generic.
public static void main(String[] args)
{
System.out.println("You wake up on a cold hard floor");
time();
System.out.println("you are unsure how you got there.");
time();
System.out.println("There is an opening a head");
time();
System.out.println("you walk forward into the opening the ground begins to tremble");
time();
System.out.println("the wall behind you closes you are trapped.");
time();
time();
clear(); // clears screen for user.
roomThree();
}
public static void timeHalfSec()
{
try
{
Thread.sleep(500); //1000 milliseconds is one second.
}catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
}
public static void time()
{
try
{
Thread.sleep(1500); //1000 milliseconds is one second.
}catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
}
public static void clear()
{
final String ANSI_CLS = "\u001b[2J";
final String ANSI_HOME = "\u001b[H";
System.out.print(ANSI_CLS + ANSI_HOME);
System.out.flush();
}
public static void position(int placement)
{
switch( placement )
{
//********************************
// For each room create a method and
// call it in this switch statement.
//********************************
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8: roomEight();
break;
case 9:
break;
case 10:
break;
case 11:
break;
case 12:
break;
case 13:
break;
case 14:
break;
case 15:
break;
case 16:
break;
case 17:
break;
case 18:
break;
case 19:
break;
case 20:
break;
case 21:
break;
case 22:
break;
case 23:
break;
case 24:
break;
case 25:
break;
}
}
public static void askMove()
{
System.out.println("You can walk forward, left , or right. Beware the imps.");
System.out.println("Enter L for left, R for right, and F for forward.");
time();
System.out.print("Move:");
movement = scan.nextLine();
}
public static void roomThree()
{
askMove();
//--------------------------------
// This switch stament is only for this room
//--------------------------------
switch ( movement )
{
case "l":
case "L":
placement = 2;
System.out.println("Changing rooms Please wait");
time();
clear();
break;
case "r":
case "R":
placement = 4;
System.out.println("Changing rooms Please wait");
time();
clear();
break;
case "f":
case "F":
placement = 8;
System.out.println("Changing rooms Please wait");
time();
clear();
break;
}
// The switch statement changes position and position calls the next room method.
position(placement);
}
public static void roomEight()
{
System.out.print ("You have just entered a new room.");
System.out.print ("There is an imp ahead would you like to see its stats? 1 for yes and 0 ");
impAmount = 1;
scanVal = scan.nextInt();
if(scanVal == 1 )
{
impStats();
}
System.out.println("Would you like to hit the imp? 1 for yes and 0 for no.");
scanVal = scan.nextInt();
while (impAmount != 0)
{
if (scanVal == 1)
{
impAmount = 0;
damage++;
lifeCount = 15;
System.out.println("You killed an imp! You found brass knuckles your damage increased by one. Here are your stats");
playerStats();
}else{
lifeCount--;
System.out.println("The imp hit you. You took one damage");
playerStats();
timeHalfSec();
dead();
}
}
}
public static void playerStats()
{
System.out.println("*----------------*");
System.out.println("Your Hearts: " + lifeCount);
System.out.println("Your Damage: " + damage);
System.out.println("*----------------*");
}
public static void impStats()
{
System.out.println ("*----------------*");
System.out.println("Amount of Imps: " + impAmount);
System.out.println("Imp Health: 1");
System.out.println("impDamage: 1");
System.out.println("*----------------*");
}
public static void dead()
{
if(lifeCount < 1)
{
System.exit(0);
}
}
}
//********************************************************************************************************************************
// Places to look for code and things to look up.
// Lookup: .equalsIgnoreCase, global scanner.
// Places to look for code:
// http://stackoverflow.com/questions/23586732/how-to-make-a-one-static-scanner-global-variable-without-closing-scan-constantly
// https://www.youtube.com/watch?v=zijvKOjnmwY
// http://stackoverflow.com/questions/16706716/using-two-values-for-one-switch-case-statement
// http://www.csci.csusb.edu/dick/samples/java.classes.html#System
// http://stackoverflow.com/questions/22452930/terminating-a-java-program
//
//
//
//********************************************************************************************************************************

You'd probably want to move the following two lines into the loop :
System.out.println("Would you like to hit the imp? 1 for yes and 0 for no.");
scanVal = scan.nextInt();

As I can see, you scan the nextInt that a user enter, you do stuff with it and then you re-scan the nextInt. The problem with that is when you use the scanner and ask for a single int, there is still the new-line char in the scanner ('\n'). Thus, when you ask a second time for the int, this will return the new line char. My understanding of all this is not on point, but what you have to do is one of those solution :
Use nextLine instead of nextInt and parse the string value into an Int. This will clear the buffer, and you will be able to validate if the user entered a valid Int. You'd do it like this :
String scanVal = scan.nextLine();
//You can add some try catch in order to validate the int being parsed
int choice = Integer.parseInt(scanVal);
Or you can clear the buffer after you have scanned your int by calling scan.nextLine()after scan.nextInt()
Hope this helps!

Related

Stuck in Infinite loop, why it does not wait for scanner to re-enter the values [duplicate]

my question is short and sweet. I do not understand why my program infinitely loops when catching an error. I made a fresh try-catch statement but it looped and even copied, pasted and modified the appropriate variables from a previous program that worked. Below is the statement itself and below that will be the entire program. Thank you for your help!
try {
input = keyboard.nextInt();
}
catch(Exception e) {
System.out.println("Error: invalid input");
again = true;
}
if (input >0 && input <=10)
again = false;
}
Program:
public class Blanco {
public static int input;
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
nameInput();
}
/**
*
* #param name
*/
public static void nameInput() {
System.out.println("What is the name of the cartoon character : ");
Scanner keyboard = new Scanner(System.in);
CartoonStar star = new CartoonStar();
String name = keyboard.next();
star.setName(name);
typeInput(keyboard, star);
}
public static void typeInput(Scanner keyboard, CartoonStar star) {
boolean again = true;
while(again){
System.out.println("What is the cartoon character type: 1 = FOX,2 = CHICKEN,3 = RABBIT,4 = MOUSE,5 = DOG,\n"
+ "6 = CAT,7 = BIRD,8 = FISH,9 = DUCK,10 = RAT");
try {
input = keyboard.nextInt();
}
catch(Exception e) {
System.out.println("Error: invalid input");
again = true;
}
if (input >0 && input <=10)
again = false;
}
switch (input) {
case 1:
star.setType(CartoonType.FOX);
break;
case 2:
star.setType(CartoonType.CHICKEN);
break;
case 3:
star.setType(CartoonType.RABBIT);
break;
case 4:
star.setType(CartoonType.MOUSE);
break;
case 5:
star.setType(CartoonType.DOG);
break;
case 6:
star.setType(CartoonType.CAT);
break;
case 7:
star.setType(CartoonType.BIRD);
break;
case 8:
star.setType(CartoonType.FISH);
break;
case 9:
star.setType(CartoonType.DUCK);
break;
case 10:
star.setType(CartoonType.RAT);
break;
}
popularityNumber(keyboard, star);
}
public static void popularityNumber(Scanner keyboard, CartoonStar star) {
System.out.println("What is the cartoon popularity number?");
int popularity = keyboard.nextInt();
star.setPopularityIndex(popularity);
System.out.println(star.getName() + star.getType() + star.getPopularityIndex());
}
}
Your program runs forever because calling nextInt without changing the state of the scanner is going to cause an exception again and again: if the user did not enter an int, calling keyboard.nextInt() will not change what the scanner is looking at, so when you call keyboard.nextInt() in the next iteration, you'll get an exception.
You need to add some code to read the garbage the user entered after servicing an exception to fix this problem:
try {
...
} catch(Exception e) {
System.out.println("Error: invalid input:" + e.getMessage());
again = true;
keyboard.next(); // Ignore whatever is entered
}
Note: you do not need to rely on exceptions in this situation: rather than calling nextInt(), you could call hasNextInt(), and check if the scanner is looking at an integer or not.

Java: Cant break after a case in a switch-case - Why?

I programmed a game.
I used switch case to implement a state machine.
The problem is that in case ZIEHEN_SP the break statement doesn't work.
When I debug it, the compiler just step over the break statement and goes to the next case ZIEHEN_BA.
I commented the part where the compiler ignores the break statement.
Why?
import java.util.*;
import java.util.Scanner;
import java.io.*;
class BlackJack2 {
static int chips = 100;
static int einsatz = 0;
enum State { INIT, EINSATZ,ZIEHEN_SP, ZIEHEN_BA}
static State state = State.INIT;
static ArrayList<Integer> bankKarten = new ArrayList<Integer>();
static ArrayList<Integer> spielerKarten = new ArrayList<Integer>();
static Scanner scanner = new Scanner(System.in);
static String s = "";
static int eingabe = 0;
static void init(){
System.out.println("\nEin neues Spiel beginnt: ");
bankKarten.clear();
spielerKarten.clear();
bankKarten.add(giveCard());
spielerKarten.add(giveCard());
}
static void chipsSetzen(){
einsatz = 0;
if(chips == 0){
System.out.print("\nSie haben " + chips + " Chips!");
System.exit(1);
}
do{
System.out.print("\nSie haben " + chips + " Chips");
System.out.print("\nWie viel moechten Sie setzen? ");
try{
einsatz = Integer.parseInt(scanner.next());
} catch(Exception e){
}
} while(einsatz <= 0 || einsatz > chips);
chips -= einsatz;
}
static int sumSpielerKarten(){
int sum=0;
for(int i=0; i<spielerKarten.size(); i++){
sum +=spielerKarten.get(i);
}
return sum;
}
static int sumBankKarten(){
int sum=0;
for(int i=0; i<bankKarten.size(); i++){
sum +=bankKarten.get(i);
}
return sum;
}
static int giveCard(){
return (int)(Math.random()*11+1);
}
static boolean oneMoreCard(){
int ss = sumSpielerKarten();
if(ss >= 21){
return false;
} else {
do{
System.out.print("\nMoechten sie eine witere Karte ziehen? (y/n): ");
s = scanner.next();
if(s.equals("y")){
return true;
} else if(s.equals("n")){
return false;
}
} while(!s.equals("y") || !s.equals("n"));
}
return false;
}
static String evaluateWinner(int s, int b){
String ret = "";
if(b > 21 || (s > b && s<=21) || s == 21 && b != 21){
ret = "Player";
} else if(s > 21 || b > s || b == 21 && s != 21){
ret = "Bank";
} else if(b == s){
ret = "Both";
}
return ret;
}
static int updateMoney(int s, int b){
String winner = evaluateWinner(s, b);
int newChips = 0;
if(winner == "Player"){
newChips = einsatz*2 + chips;
} else if(winner == "Both"){
newChips = einsatz + chips;
} else if(winner == "Bank"){
newChips = chips;
}
System.out.println("Winner: "+ winner);
return newChips;
}
static void showCards(){
System.out.print("\nBank:\t");
for(int i=0; i<bankKarten.size(); i++){
System.out.print( "[" + bankKarten.get(i) + "]");
}
System.out.println("\t= " + sumBankKarten());
System.out.print("Player:\t");
for(int i=0; i<spielerKarten.size(); i++){
System.out.print( "[" + spielerKarten.get(i) + "]");
}
System.out.println("\t= " + sumSpielerKarten());
}
static void banksTurn(){
int sb = sumBankKarten();
int ss = sumSpielerKarten();
if(sb != 21 && ss != 21 && ss < 21){
while(sb < 17 || (ss > sb && sb < 17)){
bankKarten.add(giveCard());
}
}
updateMoney(ss, sb);
}
public static void main(String args[]){
while(true){
switch(state){
case INIT:
init();
state = State.EINSATZ;
break;
case EINSATZ:
chipsSetzen();
state = State.ZIEHEN_SP;
break;
case ZIEHEN_SP:
showCards();
while(oneMoreCard()){
spielerKarten.add(giveCard());
showCards();
}
state = State.ZIEHEN_BA;
break; // << Compiler ignores this statement and goes directly to case ZIEHEN_BA
case ZIEHEN_BA:
banksTurn();
state = State.INIT;
break;
}
}
}
}
Because you change state to a value that matches with State.ZIEHEN_BA condition :
state = State.ZIEHEN_BA;
So here :
while(true){
...
state = State.ZIEHEN_BA;
break;
case ZIEHEN_BA:
banksTurn();
state = State.INIT;
break;
...
}
the case ZIEHEN_BA is executed at the next iteration of the loop.
What Eclipse shows may be an optimization of the JVM performed at runtime or by the compiler. You could disassemble the class to have more information.
EDIT
I have done the test and i don't think it is a compiler optimization.
Look at this minimal example where I don't set the state in the case :
public class TestSwitch {
public enum MyEnum {
A, B
};
public static void main(String[] args) {
MyEnum state = MyEnum.A;
while (true) {
switch (state) {
case A:
break;
case B:
break;
}
}
}
}
Here is the disassembled code of the main() method :
public static void main(java.lang.String[]);
Code:
0: getstatic #18 // Field a/TestSwitch$MyEnum.A:La/TestSwitch$MyEnum;
3: astore_1
4: invokestatic #24 // Method $SWITCH_TABLE$a$TestSwitch$MyEnum:()[I
7: aload_1
8: invokevirtual #27 // Method a/TestSwitch$MyEnum.ordinal:()I
11: iaload
12: tableswitch { // 1 to 2
1: 36
2: 39
default: 39
}
36: goto 4
39: goto 4
And look at the version where I set the state in case A to enter in case B :
public class TestSwitch {
public enum MyEnum {
A, B
};
public static void main(String[] args) {
MyEnum state = MyEnum.A;
while (true) {
switch (state) {
case A:
state = MyEnum.B;
break;
case B:
break;
}
}
}
}
Here is the disassembled code of the main() method :
public static void main(java.lang.String[]);
Code:
0: getstatic #18 // Field a/TestSwitch$MyEnum.A:La/TestSwitch$MyEnum;
3: astore_1
4: invokestatic #24 // Method $SWITCH_TABLE$a$TestSwitch$MyEnum:()[I
7: aload_1
8: invokevirtual #27 // Method a/TestSwitch$MyEnum.ordinal:()I
11: iaload
12: tableswitch { // 1 to 2
1: 36
2: 43
default: 43
}
36: getstatic #31 // Field a/TestSwitch$MyEnum.B:La/TestSwitch$MyEnum;
39: astore_1
40: goto 4
43: goto 4
There is not optimization in this compiled code.
After case A execution :
36: getstatic #31 // Field a/TestSwitch$MyEnum.B:La/TestSwitch$MyEnum;
39: astore_1
the next instruction is a goto to the loop :
40: goto 4
So the optimization is probably performed at runtime by the JVM or the Eclipse debugger.
The compiler optimized your code :-)
As you set the switch variable to State.ZIEHEN_BA and there's nothing to be executed in between (while (true) and reentering the switch) that's exactly the next lines to be executed.
I'm not sure if it's supposed to behave that way (changing variable switched on inside switch will cause following cases to be checked) but in your case I totally agree with the compiler.
As you can see in this example, this behaviour is not always the case:
public static void main(String[] args) {
int i = 3;
switch(i) {
case 1:
System.out.println("1:");
break;
case 2:
System.out.println("2:");
break;
case 3:
System.out.println("3:");
i = 5;
break;
case 4:
System.out.println("4:");
break;
case 5:
System.out.println("5:");
i = 5;
break;
case 6:
System.out.println("6:");
break;
case 7:
System.out.println("7:");
break;
default:
break;
}
System.out.println("I = " + i);
}
Results in
3:
I = 5
This is an optimization. When you set the state to ZIEHEN_BA, the compiler knows it will get there as a next step. Without optimization, there would just be some aditional steps, but it will get there anyway:
Set the state; do the break; goto the while(true), now do the switch and...it gets to ZIEHEN_BA. So that is equivalent to going there directly.
Actually , compiler is not ignoring the break.
As you set state = State.ZIEHEN_BA in the existing case statement
So after invoking break it's going straight to ZIEHEN_BA in the next iteration of while(ture) loop .... :)
It may seems that it's directly going to ZIEHEN_BA by ignoring break but it's entering there in the following iteration.
The main program which you wrote is an unbreakable loop. Once if we see the code properly, you were assigning the state to the other case whenever some case was hit. And moreover you never ended the loop. The while loop doesn't know where to stop. Not exactly sure what you want to do.
FYI, the break is not skipped but it worked only break the switch loop. And I guess you expectation is to break the while loop...
If you want the code stop at a particular point, place a break for while loop. Again placing break; inside switch doesn't work as it breaks the switch loop. Instead try to set a Boolean variable before while and change the variable value to false where ever you want the loop to break.

How would you give the user the option to exit the program after answering 4 consecutive questions correctly?

I'm attempting to give the user the option to exit the program after he/she gets 4 multiplication questions correct. If he/she chooses to continue, I have to give him/her another chance to exit each time. I hope that makes sense.. My posted code works but I have a feeling that I will have to change some things in order to give user the option to terminate.
import java.security.SecureRandom; //program will use random numbers
import java.util.Scanner; //program will need user input
public class RandomMultiplication
{
public static void main(String[] args)
{
while(true)//continues to play game
{
question();
}
}
public static void question()
{
boolean repeat = false;
SecureRandom randomNumbers = new SecureRandom();
//pick random numbers (1-9) for multiplication scenario
int number1 = randomNumbers.nextInt(10); //first number
int number2 = randomNumbers.nextInt(10); //second number
while(!repeat)
{
int responseCode = randomNumbers.nextInt(4);
if(multiplicationProblem(number1,number2))
{
switch(responseCode)
{
case 0: System.out.println("Very Good!");
break;
case 1: System.out.println("Excellent!");
break;
case 2: System.out.println("Keep up the good work!");
break;
case 3: System.out.println("Nice work!");
break;
}//ends switch
repeat = true; //stops repeating the same question
}//end if statement
else
{
responseCode = randomNumbers.nextInt(4);
switch(responseCode)
{
case 0: System.out.println("No. Please try again!");
break;
case 1: System.out.println("Wrong, Try once more!");
break;
case 2: System.out.println("Don't give up!");
break;
case 3: System.out.println("No. Keep trying!");
break;
}//ends switch
}//ends else condition
}//ends while loop
}
public static boolean multiplicationProblem(int number1, int number2)
{
Scanner input = new Scanner(System.in);
int userInputAnswer;
int correctCounter = 0;
System.out.printf("How much is %d times %d?", number1, number2);
userInputAnswer = input.nextInt();
if (userInputAnswer == number1 * number2)
{
return true;
}
else
{
return false;
}
}
}

How to get a system.out.println to return in a method

I have a program which plays a game of superhero top trumps and I need to repeat the menu every time a user plays the game. I've tried to create a method (displayMenus) which would be inserted into every switch statement (except for closing the program), however I don't understand how to get it to return this menu.
public class Heros {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int index = 0;
do {
int inp = input.nextInt();
switch (inp) {
//FIRST
case 1:
index = 0;
System.out.println(HerosAsList.getHeros().get(index));
System.out.println(displayMenus);
break;
//NEXT
case 2:
index++;
if (index > HerosAsList.getHeros().size() - 1) {
index = HerosAsList.getHeros().size() - 1;
}
System.out.println(HerosAsList.getHeros().get(index));
System.out.println(displayMenus);
break;
//PREV
case 3:
index--;
if (index < 0) {
index = 0;
}
System.out.println(HerosAsList.getHeros().get(index));
System.out.println(displayMenus);
break;
//LAST
case 4:
index = HerosAsList.getHeros().size() - 1;
System.out.println(HerosAsList.getHeros().get(index));
System.out.println(displayMenus);
break;
//QUIT
case 0:
System.out.println("Closing system");
System.exit(inp);
break;
}
}
while(index<HerosAsList.getHeros ().size());
}
public static displayMenus () {
System.out.println("First - 1");
System.out.println("Next - 2");
System.out.println("Prev - 3");
System.out.println("Last - 4");
System.out.println("Quit - 5");
System.out.println("");
System.out.println("Enter Choice:");
}
}
any help is greatly appreciated, I just can't seem to get my head around methods!
Firstly, the declaration of displayMenus is invalid. You need to give it a return type (even if that is void), e.g.:
public static void displayMenus () {
If you make it void, you would need to invoke displayMenus() without calling System.out.println:
displayMenus();
If you make it String, you would need to build a String in displayMenus and return it, e.g.:
public static String displayMenus() {
return "First - 1" + ...;
}
then you can invoke System.out.println(displayMenus()).
Just change displayMenus to return the menu as a String, rather than printing it:
public static String displayMenus() {
return "First - 1\nNext - 2\nPrev - 3\nLast - 4\nQuit - 5\n\nEnter Choice:\n";
}
I simplified the code down, because there were quite a few syntax errors in the code itself, but this should answer your question. Your displayMenus() function doesn't need to return a String, you can instead call this at the beginning of your do...while loop. The logic flow should be:
Initialize scanner
Create variable for choice
Enter do...while loop
Call displayMenus()
Read user choice from scanner
Do switch logic
Back to 3rd item if the loop isn't broken
I made a small class to demo this:
package zzzTestProj;
import java.util.Scanner;
public class NewClass {
public static void main(String[] args) {
Scanner userInputScanner = new Scanner(System.in);
int userMenuChoice;
do {
displayMenus();
userMenuChoice = userInputScanner.nextInt();
switch (userMenuChoice) {
// FIRST
case 1:
break;
// NEXT
case 2:
break;
case 0:
System.out.println("Closing system");
System.exit(userMenuChoice);
break;
}
} while (userMenuChoice != 5);
}
public static void displayMenus() {
System.out.println("First - 1");
System.out.println("Next - 2");
System.out.println("Prev - 3");
System.out.println("Last - 4");
System.out.println("Quit - 5");
System.out.println("");
System.out.print("Enter Choice:");
}
}

Exception handling infinite loop

my question is short and sweet. I do not understand why my program infinitely loops when catching an error. I made a fresh try-catch statement but it looped and even copied, pasted and modified the appropriate variables from a previous program that worked. Below is the statement itself and below that will be the entire program. Thank you for your help!
try {
input = keyboard.nextInt();
}
catch(Exception e) {
System.out.println("Error: invalid input");
again = true;
}
if (input >0 && input <=10)
again = false;
}
Program:
public class Blanco {
public static int input;
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
nameInput();
}
/**
*
* #param name
*/
public static void nameInput() {
System.out.println("What is the name of the cartoon character : ");
Scanner keyboard = new Scanner(System.in);
CartoonStar star = new CartoonStar();
String name = keyboard.next();
star.setName(name);
typeInput(keyboard, star);
}
public static void typeInput(Scanner keyboard, CartoonStar star) {
boolean again = true;
while(again){
System.out.println("What is the cartoon character type: 1 = FOX,2 = CHICKEN,3 = RABBIT,4 = MOUSE,5 = DOG,\n"
+ "6 = CAT,7 = BIRD,8 = FISH,9 = DUCK,10 = RAT");
try {
input = keyboard.nextInt();
}
catch(Exception e) {
System.out.println("Error: invalid input");
again = true;
}
if (input >0 && input <=10)
again = false;
}
switch (input) {
case 1:
star.setType(CartoonType.FOX);
break;
case 2:
star.setType(CartoonType.CHICKEN);
break;
case 3:
star.setType(CartoonType.RABBIT);
break;
case 4:
star.setType(CartoonType.MOUSE);
break;
case 5:
star.setType(CartoonType.DOG);
break;
case 6:
star.setType(CartoonType.CAT);
break;
case 7:
star.setType(CartoonType.BIRD);
break;
case 8:
star.setType(CartoonType.FISH);
break;
case 9:
star.setType(CartoonType.DUCK);
break;
case 10:
star.setType(CartoonType.RAT);
break;
}
popularityNumber(keyboard, star);
}
public static void popularityNumber(Scanner keyboard, CartoonStar star) {
System.out.println("What is the cartoon popularity number?");
int popularity = keyboard.nextInt();
star.setPopularityIndex(popularity);
System.out.println(star.getName() + star.getType() + star.getPopularityIndex());
}
}
Your program runs forever because calling nextInt without changing the state of the scanner is going to cause an exception again and again: if the user did not enter an int, calling keyboard.nextInt() will not change what the scanner is looking at, so when you call keyboard.nextInt() in the next iteration, you'll get an exception.
You need to add some code to read the garbage the user entered after servicing an exception to fix this problem:
try {
...
} catch(Exception e) {
System.out.println("Error: invalid input:" + e.getMessage());
again = true;
keyboard.next(); // Ignore whatever is entered
}
Note: you do not need to rely on exceptions in this situation: rather than calling nextInt(), you could call hasNextInt(), and check if the scanner is looking at an integer or not.

Categories

Resources