Problem specification: Infinite loop ( menu enters an infinite loop );
Objective: Request user for an integer input and proceed in accordance to specified logic inside of the code. How to avoid the infinite loop?;
Code:
public Purchase groceryStoreMenu(LemonadeStand lemonadeStand){
boolean getMenu = true;
int userEnteredNumber = -1;
currentPurchase = new Purchase();
while(getMenu){
try{
System.out.println("Grocery Store");
System.out.printf("%s\t%s%n%s\t%s%n%s\t%s%n%s\t%s%n%s\t%s%n%s\t%s%n" , "1:" , "Buy lemons", "2:", "Buy cups" , "3:" , "Buy sugar" ,
"4:" , "Buy ice" , "5:" , "Done"); //change this
userEnteredNumber = reader.nextInt();
if (userEnteredNumber == 1 ) {
money = lemonadeStand.profit(0);
lemonsMenu(money);
}else if (userEnteredNumber == 2){
money = lemonadeStand.profit(0);
cupsMenu(money);
}else if (userEnteredNumber == 3){
money = lemonadeStand.profit(0);
sugarMenu(money);
}else if (userEnteredNumber == 4){
money = lemonadeStand.profit(0);
iceMenu(money);
}else{
money = lemonadeStand.profit(0);
dailyGreetingMenu();
}
if (userEnteredNumber != 1 && userEnteredNumber !=2 && userEnteredNumber != 3
&& userEnteredNumber != 4 && userEnteredNumber != 5) {
throw new Exception();
} else if(userEnteredNumber == 6) {
getMenu = false;
//break;
} else {
getMenu = false;
//break;
}
}
catch(Exception e)
{
System.out.println("Error in number format. Enter a valid number from the choices (1,2,3,4,5,6)");
}
}
return currentPurchase;
Your program never reaches if(userEnteredNumber == 6) with 6 value, because if userEnteredNumber is 6, the first condition will grab it:
if (userEnteredNumber != 1 && userEnteredNumber !=2 && userEnteredNumber != 3
&& userEnteredNumber != 4 && userEnteredNumber != 5) {
throw new Exception();
}
then it throws exception, and it is catched within loop block. And any number other than 1, 2, 3, 4, 5, 6 is the same. So the loop never ends.
I don't like your code-style at all. But if you want to do it this way, you shall add userEnteredNumber != 6 to first if condition.
looks like the execution is never gonna enter the following block:
else if(userEnteredNumber == 6) {
getMenu = false;
//break;
}
the if condition should not contain '&&'.it should have been '||'
Also looks like you dont want your user to enter any number other than 1,2,3,4,5.
if (userEnteredNumber != 1 || userEnteredNumber !=2 || userEnteredNumber != 3
|| userEnteredNumber != 4 || userEnteredNumber != 5) {
getMenu = false;
throw new Exception();
}
Related
I'm working on a card game for a personal project and I was wondering how I could make it so that each specific card can only be used a set number of times. I'm thinking about making an loop that adds to a specific number, and if the number reaches that specific value, the card can no longer be played. My issue is that I am having trouble with syntax and have just been confusing myself. cardLimiter is the variable i want to use to add to a specific value, though I just need a few pointers. Thanks!
public static void emperorsTurn() {
Random cards = new Random();
int computerinput = 0;
int numberx = 5;
for (int counter = 1; counter <= 3; counter++) {
computerinput = 1 + cards.nextInt(2);
}
Scanner sc = new Scanner(System.in);
System.out.println("Please pick the card you are playing. \n if you are playing the Emperor press 1, if you are playing the citizen press 2 ");
int userinput = sc.nextInt();
if (userinput == 1 && computerinput == 1 && cardLimiter == 0) {
System.out.println("you have played the emperor! \n the emperor is defeated by the slave");
cardLimiter++;
if ((userinput == 1 && computerinput == 1 && cardLimiter == 1)) {
System.out.println("you cannot play the emperor this turn \n you have played the citizen instead");
}
} else if (userinput == 1 && computerinput == 2) {
System.out.println("you have played the emperor the emperor defeats the citizen");
winOrLose();
wincounter();
numberx--;
} else if (userinput == 2) { //when the user input is 2
if (computerinput == 1) {
System.out.println("you have played the citizen, this defeats the slave");
wincounter();
} else if (computerinput == 2) {
System.out.println("you have played the citizen, this ties with the citizen");
}
//print out something else if number is not 1,2 or 3
}
}
In this part, you've got the second if statement nested inside the first:
if (userinput == 1 && computerinput == 1 && cardLimiter == 0) {
System.out.println("you have played the emperor! \n the emperor is defeated by the slave");
cardLimiter++;
if ((userinput == 1 && computerinput == 1 && cardLimiter == 1)) {
System.out.println("you cannot play the emperor this turn \n you have played the citizen instead");
}
}
If userinput == 1 && computerinput == 1 && cardLimiter == 0 it will print out "you have played the emperor" etc. But then you immediately increment cardLimiter, so it will also print out "you cannot play the emperor this turn".
I imagine that's not the desired behavior, so I would recommend moving that second if statement out of the first one. Perhaps something like this:
if (userinput == 1 && computerinput == 1 && cardLimiter == 0) {
System.out.println("you have played the emperor! \n the emperor is defeated by the slave");
cardLimiter++;
} else if ((userinput == 1 && computerinput == 1 && cardLimiter == 1)) {
System.out.println("you cannot play the emperor this turn \n you have played the citizen instead");
}
That way, only one of the System.out.println statements will execute.
I'm trying to make a simple code to play Rock, Paper, Scizzors, there is more to the code however this is the important part
int comResult = (int)(Math.random() * 3);
String comChoice;
if (comResult == 0) {
comChoice = "rock";
} else if (comResult == 1) {
comChoice = "scizzors";
} else if (comResult == 2) {
comChoice = "paper";
}
String results;
if (comChoice == humanChoice)
When I get to comparing the computers choice to the humans the computer says that I haven't declared a value for comChoice even though I put it in the if then statement, how do I properly declare the value
You can add an "else" at the end of your condition block to make sure comChoice gets initialized.
if (comResult == 0) {
comChoice = "rock";
} else if (comResult == 1) {
comChoice = "scizzors";
} else if (comResult == 2) {
comChoice = "paper";
} else {
comChoice = "invalid input";
}
You can use switch with default case.
I'm working on this program that asks for model numbers of cars infinitely until the person inputs 0 to break the loop. When i run it and input a number it just infinitely loops either your car is defective or it is not defective until it crashes. I'm pretty stuck right now any help would be greatly appreciated.
Scanner input = new Scanner(System.in);
System.out.print("Enter a model number or 0 to quit: ");
modelNum = input.nextInt();
while (modelNum != 0) {
if (modelNum >= 189 && modelNum <= 195) {
System.out.println("Your car is defective it must be repaired");
} else if (modelNum == 189 || modelNum == 221) {
System.out.println("Your car is defective it must be repaired");
} else if (modelNum == 780) {
System.out.println("Your car is defective it must be repaired");
} else if (modelNum == 119 || modelNum == 179) {
System.out.println("Your car is defective it must be repaired");
} else {
System.out.println("Your car is not defective");
}
if (modelNum == 0) {
System.out.println("end");
break;
}
}
It's because you never ask the user for another input. You should do so before the end of the loop.
Include the this part into your loop:
Scanner input = new Scanner(System.in);
System.out.print("Enter a model number or 0 to quit: ");
modelNum = input.nextInt();
You have to ask for a new value to be evaluated:
while (modelNum != 0) {
// if conditions
modelNum = input.nextInt();
}
Also note that:
if (modelNum == 0) {
System.out.println("end");
break;
}
won't be necessary because if the last value is 0 the condition in the while loop will be false and won't loop again.
Last thing: why you have all those if-else-if when they all do the same thing (print "Your car is defective it must be repaired"). This will be enough:
while (modelNum != 0) {
if ((modelNum >= 189 && modelNum <= 195) || modelNum == 221 || modelNum == 780 || modelNum == 119 || modelNum == 179) {
System.out.println("Your car is defective it must be repaired");
} else {
System.out.println("Your car is not defective");
}
modelNum = input.nextInt();
}
if you enter 0, the loop will break, therefore the last if statement will never run.
This loop just tells you if the car is defective or not depending on the model number, but you never tell the program to exit the loop if the car is defective. To do so you have to put break statements into each if statement of the loop.
Moreover this statement is useless:
if(modelNum == 0)
{
System.out.println("end");
break;
since if u enter 0 the loop won't start.
I have a program that deals with using different loops in different methods. The program as a whole is working fine apart from one method that calls another.
I am having trouble with a method that calls another.
What I want to do is:
Have the method call the other and run it which takes a variable
from the user (1 - 100).
Increment a variable if an invalid input is
entered.
Display a message and exit back to menu when 3 inputs are
entered in a row.
The method that is being called works fine on it's own and it works when I call it.
What I can't get to work is the display message when after 3 invalid inputs. At present, it takes about 7 invalid inputs then it displays the message??
Method that works:
public static boolean processGrade(int percentMark)
{
Menu m = new Menu();
clrscr();
System.out.println("Please enter your mark e.g. 90. (input -1 to exit): ");
percentMark = Genio.getInteger();
if
(percentMark >=70 && percentMark <=100)
{
clrscr();
System.out.println("Your Grade is A - Excellent!\n\n");
pressKey();
clrscr();
}
else if(percentMark >= 60 && percentMark <70)
{
clrscr();
System.out.println("Your Grade is B - Good!\n\n");
pressKey();
clrscr();
}
else if (percentMark >=50 && percentMark <60)
{
clrscr();
System.out.println("Your Grade is C - Ok!\n\n");
pressKey();
clrscr();
}
else if(percentMark >=40 && percentMark <50)
{
clrscr();
System.out.println(" Your Grade is D - Must Do Better!\n\n");
pressKey();
clrscr();
}
else if (percentMark <40 && percentMark >= 0 )
{
clrscr();
System.out.println(" Your Grade is E - Must Do Better!\n\n");
pressKey();
clrscr();
}
else if (percentMark < -1 || percentMark >100)
{
clrscr();
System.out.println("ERROR: Value MUST be in the range of 0 - 100!");
pressKey();
clrscr();
return false;
}
else if (percentMark == -1)
{
//clrscr();
System.out.println("You entered -1, you will now return to the menu!");
pressKey();
return false;
}
return true;
}
Method that I can't get to work that calls the above message:
public static void processGradeV2(int percentMark)
{
int invalid = 0;
outerloop:
do {
clrscr();
boolean result = processGrade(percentMark);
processGrade(percentMark);// Call processGrade method
if(result == false)
{
invalid++;
}
if(invalid == 3)
{
clrscr();
System.out.println("Sorry, you have entered an invalid integer 3 times in a row! The program will return to the menu screen.");
pressKey();
break outerloop;
//return;
}
if(percentMark == -1)
{
clrscr();
System.out.println("You entered -1, you will now return to the menu!");
pressKey();
clrscr();
break outerloop;
//processUserChoices();
}
}
while(invalid <3);
}
processGrade(percentMark);// Call processGrade method
will cause you a problem here, delete it.
You already assigned the processGrade(percentMark); result to the result variable.
I would delete boolean result = processGrade(percentMark) and instead change your if statement to:
if(!processGrade(percentMark)){
invalid++;
}
So the program that I am trying to write is something like this. The opponent picks a number at random where each number corresponding to a person. then the user does the same thing. then the out is to show what the user pick, what the opponent picked and who won that match. its similiar to rock, paper scissor but with some more stuff added to it. i also have to show the numbers of rounds played and how many times the user had won. But my problem is this. No matter what my input is, it keeps saying that i made an invalid choice and to pick it again. This is what I have.
public static void main(String[] args) {
int game=0;
int won = 0;
int opponent;
Random rand = new Random();
System.out.println("Welcome to the game. Here are the rules:");
Scanner in = new Scanner(System.in);
rules();
choices();
int choice = selected(in);
while (choice !=0) {
rules();
choices();
choice = selected(in);
opponent = opp();
result(choice, opponent, in);
game+=1;
}
System.out.println("You played " +game+" games.");
System.out.println("Quitting");
}
public static void rules(){
System.out.println("\nFlurg beats Stuga and Kvartal");
System.out.println("Stuga beats Kvartal");
System.out.println("Kvartal beats Lerberg");
System.out.println("Lerberg beats Flurg and Stuga");
System.out.println("The computer wins in the event of a tie.");
System.out.println();
}
public static int opp(){
Random rand = new Random();
int opponent = rand.nextInt(4)+1;
return opponent;
}
public static void choices(){
System.out.println("Please select your choice:");
System.out.println("'1' for Flurg ");
System.out.println("'2' for Stuga ");
System.out.println("'3' for Kvartal ");
System.out.println("'4' for Lerberg ");
System.out.println("'0' to Quit ");
System.out.print("Selection: ");
}
public static int selected(Scanner in){
int choice = in.nextInt();
while (choice != 1 && choice != 2 &&
choice != 3 && choice != 4 &&
choice != 0) {
System.out.println("Invalid choice");
choices();
choice = in.nextInt();
}
return choice;
}
public static int result(int choice, int opponent, Scanner in) {
int won=0;
System.out.print("You picked:" +choice+". Opponent picked:" +opponent+".");
if(choice == 1 && (opponent == 2) || (opponent == 3)){
System.out.println("You won!");
won+=1;
}
else if(choice == 2 && opponent == 3){
System.out.println("You won!");
won+=1;
}
else if(choice == 3 && opponent == 4){
System.out.println("You won!");
won=+1;
}
else if(choice == 4 && (opponent == 1 || opponent == 2)){
System.out.println("You won!");
won+=1;
}
else {
System.out.println("You lost!");
}
return won;
}
}
EDIT
So I fixed exactly what i was told about the !=1 part. but it is again looping. for some reason, it does not want to run result()
EDIT#2
Main also has been fixed with the similar problem.
EDIT#3
I have added more lines based on what I was told.
change this
choice != '1' && choice != '2' &&
choice != '3' && choice != '4' &&
choice != '0'
to this
choice != 1 && choice != 2 &&
choice != 3 && choice != 4 &&
choice != 0
What you were trying to do was int != char and the value for '1' in ASCII is 49 SO it was indeed not 1. You are reading int from the Scanner.
The problem is here
int choice = in.nextInt();
while (choice != '1' && choice != '2' &&
choice != '3' && choice != '4' &&
choice != '0') {
System.out.println("Invalid choice");
nextInt() will return the decimal value of an int type. (int)1 != (char)'1'. The easiest solution I can think of is
while (choice != 1 && choice != 2 &&
choice != 3 && choice != 4 &&
choice != 0) {
You are comparing the found values to chars.
int choice = in.nextInt();
while (choice != '1' //...
However, this compares the entered numerical value to the ASCII-code of the character which is 49 for the character '1'. Therefore, your loop will continue until you enter one of the numbers 48 ('0') to 52 ('4').
You should compare to the numbers instead:
while (choice != 1 && choice != 2 && choice != 3 && choice != 4 && choice != 0) {
System.out.println("Invalid choice");
}
The same goes for
while (choice !='0') {
rules();
choices();
selected(in);
opp();
result(choice, opponent, in);
}
in your main method -- change this to
while (choice != 0) { // change this to 0 instead of '0'
rules();
choices();
choice = selected(in); // assign the value to choice
opponent = opp(); // assign the value to opponent
result(choice, opponent, in);
}
You also did not assign the return values of the methods to the local variables -- they are never going to change and the loop will never end like that!