How do I make my code restart? - java

So I have this code and it is inside a while(MainMenu) and what i want to learn is how to restart my code.. Sometimes using MainMenu=false; and then MainMenu=true; works but sometimes it doesnt causing me to use return to crash the program because the user can cheat...
if(CitizenLoveNum<=20){
JOptionPane.showMessageDialog(null, "Your citizen are protesting against you! You need to stop them now before something really bad happens", "Citizens on Strike!", JOptionPane.WARNING_MESSAGE);
String Strike=JOptionPane.showInputDialog("Choose 1 of the options below! \n 1.Pay Them (-1000$) \n 2.Send Army (With this move you can lose from 0 to 5 men!)", "Citizens on Strike!");
if(Strike.equals("1")){
if(MoneyCount<=0){
JOptionPane.showMessageDialog(null, "Out Of Money! Try again later..", "No Money Left", JOptionPane.WARNING_MESSAGE);
return;
}
JOptionPane.showMessageDialog(null,"The Citizen's are calm once more. But try buying them recources so that won't happen again!", "Citizens on Strike!",JOptionPane.INFORMATION_MESSAGE);
MoneyCount-=1000;
MainMenu=false;
MainMenu=true;
}else{
Random Army= new Random();
int ArmyNum = Army.nextInt(5 - 0) + 0;
JOptionPane.showMessageDialog(null,"You have sent the army. You lost "+ArmyNum+" Soldiers.", "Citizens on Strike!",JOptionPane.INFORMATION_MESSAGE);
SoldierCount1-=ArmyNum;
MainMenu=false;
MainMenu=true;
}
}
It works where i putted the MainMenu=false; MainMenu=true; but it doesnt where i used return; i had to put return; because MainMenu=false; MainMenu=true; was not working. Thank you for your time :)
Edit: it usually does not work when I use an if inside an if... hope that helps

From what I can interpret, you probably have some code like this:
while(true) {
// A: Do stuff here
while(MainMenu) {
// B: Stuff before your posted code
if(CitizenLoveNum<=20){
// C: Your posted code
}
}
// D: Do other stuff here
}
If you want to go to B, use continue;.
If you want to go to D, use break;.
If you need to go to A without touching D, then enclose D in an if statement.
If your program is ending when you use continue, you probably are missing the while(true) at the top. This part is necessary to keep your code running unconditionally, forever. Otherwise, upon exiting while (MainMenu), your program will run to completion.
Also, I would like to add that
MainMenu = false;
MainMenu = true;
Is equivalent to
MainMenu = true;
Your code executes sequentially. Once you are inside the while loop, MainMenu is not checked again until you encounter a continue or all the code inside the loop finishes executing.

If you want to return to the top of the while body, you can use the keyword
continue;
Changing the MainMenu value in the while body will not cause any action becuase it gets checked before every new loop, the continue keyword will be applied immediately.

This:
MainMenu=false;
MainMenu=true;
Is the same as this:
MainMenu=true;
You're assigning a value that will be checked when it gets back to the start of the loop. If the value is true at that point, it will continue. So if you want to continue looping, set it to true. If you want to stop, just set it to false. Do one or the other, not both. Note that MainMenu=false will continue executing the current loop, and (unless it later gets set to true) will stop it from looping again.
What the return statement does is exits the function that your while loop is enclosed in entirely. If you had cleanup code after the end of your loop, you wouldn't want to return, as that would skip it.
If you want to execute more code after the loop (not exit the function yet), but you want to immediately exit the loop without finishing the current iteration, you can use the break statement.
If you want to return to the start of your loop immediately (from anywhere in the loop) and continue executing it, use the continue statement. Whether the loop executes again will depend on the value of MainMenu.

Related

Unexpected infinite loop after input reading

I'm trying to create a program that keeps asking a question until the user presses enter. But for some reason, the program goes into an infinite loop that continuously outputs:
"Enter the operation: You need to add '[' at the beginning of the set."
If you accidentally do not follow the rules. Now, the program should print that message but only once. I think the loop continuously asks for the operation but it goes straight to the error (If you do not enter anything, I guess that counts as not using an [ at the beginning).
I already know how to solve it but because I tried everything!! I am not sure how my solution changes anything... Can you give me advice on how to solve it and/or explain to me what is it about the do-while loop implemented at the end that does the trick?
Edit: TextIO is a class written by Eck, D. J. in his book. I will link the chapter where it gives the code here: http://math.hws.edu/javanotes/c2/s6.html
The problematic code is
while (true) {
System.out.print("\nEnter the operation: ");
TextIO.skipBlanks();
if (TextIO.peek() == '\n') { //There is no operation, end the program.
break;
}
try {
calculation();
}
catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
}
The solution I implemented looks like this:
while (true) {
System.out.print("\nEnter the operation: ");
TextIO.skipBlanks();
if (TextIO.peek() == '\n') { //There is no operation, end the program.
break;
}
try {
calculation();
}
catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
do {
ch = TextIO.getAnyChar(); // Read ahead the "enter".
} while (ch != '\n'); //If necessary, make sure to stop the error message and keep the loop going.
}
Thanks, guys!!
It sounds like you're using TextIO class from David J. Eck's Introduction to Programming Using Java, Eighth Edition book.
According to the source of the class:
[TextIO.peek()] returns the next character in the current input source, without actually removing that character from the input.
You're checking the input actually without removing it. That's why in the next iteration, the loop keeps reading the same bad input, and throwing the exception indefinitely.
Also your fix performs what is lacking after calling peek(). Removing the char from the input.
Hence, replacing peek() by getAnyChar() in your first attempt solves the problem.
I'm not sure what's TextIO, you should use the standard Scanner class.

I put a loop break in java at the start of loop block and not before the loop keyword. Is that common or would it bring unexpected results?

I will show you my submitted assignment's answer to give the idea of it
void chkbnch()
{
System.out.println("\n The students under notice period are =>\n\n");
for(int i=0;i<25;i++)
**ol:{**
int cnm=0;
int cnm2=0;
for(int j=0;j<7;j++)
{
if(mrks[i][j]>=50)
{
cnm++;
}
if(cnm==3)
{
//i++;
**break ol;**
}
if(mrks[i][j]<50)
{
cnm2++;
}
}
if(cnm2>=3||cnm<3)
{
System.out.println("\n Student id =>"+(i+1));
}
}
}
Here I am using break when I don't want the loop to increment and just repeat the loop statement. I know this can be done by also decrementing the loop control but that's not what my question is.
All I want to ask that is this behaviour defined in java or is it just a chance that this is its outcome.
This use of the break statement is perfectly legal, although it is unusual, and it doesn't do what you say you want.
JLS §14.15 says:
A break statement with label Identifier attempts to transfer control to the enclosing labeled statement (§14.7) that has the same Identifier as its label; this statement, which is called the break target, then immediately completes normally. In this case, the break target need not be a switch, while, do, or for statement.
The "labeled statement" in your example is the {..} block statement, which is the statement executed by the for loop. When you execute the break, that block statement completes, which returns control to the for loop, which continues by executing the increment i++, testing the condition i<25 and then getting on with the loop.
It has the same behavior as labeling the outer loop directly, and then using continue ol;.
The loop counter will still be incremented. If you want to prevent that, either counteract it with a manual i--; or move i++; out of the for loop header and to the end of the loop body.
Seems like you want the continue keyword instead of break. continue breaks the current iteration of the loop and execution jumps back to the evaluation stage where the looping continues if the evaluation passes. break breaks the current iteration of the loop and execution jumps to the first line after the end-of-loop closing brace.
EDIT: If you need the loop increment control to "not increment" when you continue looping, so that, for example, the same object is pulled from the list being looped over after continuing, then you need to roll your own solution.

Pausing a for loop in java

Is there a way to pause a for loop in java? So is there a way to only go forward one iteration when prompted? I read this http://answers.yahoo.com/question/index?qid=20100212201605AAazS73 and the solution seems like it could have some problems mostly because I don't fully understand the order the for loop checks its header. The only method I could think of that could accomplish something similar is the following
do {
if (FLAG) {
//Do procedure
i++;
FLAG = false;
}
} while ( i < 6);
When the flag is true the procedure is done and the counter moves forward one. I don't like this, though, because it will keep looping as long as the counter is below 6, if I am not mistaken. Any ideas?
-Sorry for the lack of clarity. The FLAG in my case would be a static boolean that could be called from another class. The procedure I allude to is dependent on i.
When iterating through a for loop, for example, the one below, it does the following
for (int i = 0; i < 6; i++) {
// Do stuff
}
It declares the variable i and assigns a value of 0.
It checks the conditional i < 6. If true, then proceed to step 3. Otherwise go to step 6.
Goes through the body of the loop.
Increment the variable i due to the i++ in the for loop header.
Go to step 2.
The loop ends.
As for your objective, I'm not sure what your objective is. Are you looking to pause using a blocking method call? If so, then something like this would work:
for (int i = 0; i < 6; i++) {
System.in.readLine();
}
Alternatively, you could use some sort of flag that polls to check whether the loop should proceed, such as:
for (int i = 0; i < 6; i++) {
while (paused) {
// An infinite loop that keeps on going until the pause flag is set to false
}
}
Hope this helped.
It's not clear what sort of "prompt" you mean. You could certainly do something like:
for (int i = 0; i < 6; i++) {
System.out.println("Press return to continue...");
System.in.readLine();
// Do the body of the loop
}
That's appropriate for a console app, but obviously not for (say) a Swing app. It also doesn't address the FLAG part of your sample code, because it's not clear what that's meant to mean. Are you trying to prompt the user for more information, or just confirmation to continue? If you could clarify what you're trying to achieve, that would really help.
For the sake of testability, if this is for non-throwaway code you may want to extract the idea of a user prompt, so you can test with an implementation which doesn't actually prompt the user, but just records that it would have done so.
This would involve blocking the Thread that the for loop occupies.
You can do this simply, but not very well, with this:
for(something)
while(!FLAG)
//Do procedure
Another way would be to have another Thread going on, and have the main thread wait for that other thread.
Here's some more information: How to make a Java thread wait for another thread's output?
Your goal is somewhat unclear. I think you want your program to keep running until you get six of a certain input and if so, that approach will work, though of course you'll need to get input from the user to move the loop forward.
If your concern is that the while loop would use a lot of system resources, that will not be a problem.
Well, you could use Thread.Sleep(); to pause for a little bit between flag checks, but what you are really looking for is a function that blocks while waiting for input, System.in.readline(); blocks if I recall correctly ;) Like so:
int i = 0
do
{
if(FLAG)
{
//Do stuff
i++;
//Clear Flag
}
Thread.Sleep(50); //Sleep for 50 ms
} while (i < 6);
or like so:
for(int i = 0; i < 6; i++) //Execute readline 6 times.
{
System.in.readLine();
}
Others have covered how to use System.in.readLine() to have the program explicitly require action from the user.
If what you need is not to have the program wait for the user, but allow you - the programmer - to slow the program down, in order to be able to find and fix a bug, you might want to consider using a debugger as this is exactly what it is designed for.
Any modern Java IDE has a debugger. The keys chosen to use it, just varies.
If you are using Eclipse, you are using either F11 or Ctrl-F11 (assuming Windows) to run your program. The difference is that F11 starts your program inside a debugger and Ctrl-F11 doesn't.
Put the cursor at the first line inside the for-loop, and choose Run->Toggle Breakpoint. A blue bullet will show to the left of the line. This indicates that the breakpoint is active - the debugger will now stop your program every time it reaches that line.
Now run your program in the debugger with F11. The program stops at the line, and you can investigate your variables in the Variables pane as needed, and continue execution with F8 whenever you are ready.

Source of Infinite Loop

Everytime I run this code, the console goes into an infinite loop printing "Please input a number". I do not understand why this is happening. Thanks in advance.
boolean check = true;
int temp = 0;
while(check==true){
try{
temp= asker.nextInt();
check = false;
}
catch(InputMismatchException e){
System.out.println("Please input a number.");
}
}
Edit: asker is a Scanner. The purpose of the code is to loop until an integer is inputted by the user.
The method asker.NextInt() is throwing an InputMismatchException, indicating that the input received from asker (assuming it's a Scanner) isn't actually an integer. This exception causes the loop to restart without setting check to false.
Print the exception within the catch block to get more information about the failure. But most likely, you're feeding your application something (lots and lots of something, if it's looping like that) that doesn't actually contain integer values.
You never want to actually "Use" try/catch--by that I mean don't use it as part of your program logic--this is what you are doing.
One big problem is that, like your app, you don't see the stack trace. Eating a stack trace in an exception is almost always wrong.
If you do have to catch an exception, handle it near the catch as well as you can, but it's better to set up your code so that the exception can't be thrown anyway.
Discard this advice if your teacher told you to do it this way, but remember in the back of your mind that it's poor form.
Also don't tell your teacher that it's poor form :) he either doesn't know in which case he won't understand why or he does know and is using this to show you how try/catch works.
What is asker, a Scanner? If nextInt() fails, it doesn't consume any input, so when you catch your exception and loop back around to try again, it ends up just reading the same bad input again.
You should do something in the catch block to consume the invalid input, so that the next time around, it can read some different input. Call asker.nextLine() maybe, and ignore the return value.
You need to break the loop and report why the loop occurs
boolean NotValid = true;
int temp = 0;
while(NotValid){
try{
temp= asker.nextInt();
NotValid = false;
break; // stop
}
catch(InputMismatchException e){
System.out.println("Please input a number. reason why:");
System.out.println(e);
NotValid = true;
}
}

How could the following Java library code ever exit the while(true) loop?

I was looking through the TimSort java code: Original Source
in particular lines 676 to 739 of the mergeLo function. It has (roughly) the following layout:
outer:
while (true) {
//Code here
break outer; //Code within a few if tests in the loop.
}
//Code here executes somehow.
I am confused as to how this function could ever stop running, because the only break statements go to the outer block (which should then fall back into the while(true), and there are no return statements.
My problem is that line 747 is executing and throwing an exception when I try and sort 184 or more elements, and I want to figure out how to fix it, any help would be greatly appreciated.
[Note]: This is the function being called by the collections.sort method for Java deployed on an android phone.
The label 'outer' is just an alias for the while loop. That is, the break statement breaks the loop and the control flow continues after the loop.
In contrast, continue outer would return to the top of the while loop.
outer is actually labeling the while loop, not the line before it, so it won't reenter after breaking... it isn't a goto. =)
break outer; causes you to leave the while(true) loop. It won't fall back into the loop. Are you confusing break with continue?
you should look at the syntax of break statements.
I think you are thinking of the break statement as a goto statement. They are two different things. The break statement with an included label breaks out of the statement that the label points to.
The link should be useful.

Categories

Resources