I have Grid of labels (size n*n) and I want to fill with color its irregular part. I wrote a method
private void fill(int j){
while(board[j].getName().equals("s")){
board[j].setBackground(Color.yellow);
try{
fill(j-1);
} catch (ArrayIndexOutOfBoundsException e){}
try{
fill(j+1);
} catch (ArrayIndexOutOfBoundsException e){}
try{
fill(j+n);
} catch (ArrayIndexOutOfBoundsException e){}
try{
fill(j-n);
} catch (ArrayIndexOutOfBoundsException e){}
}
}
and I'm still getting StackOverflowError. I'm not using big parts (my n is max 20), I've tried to replace while with if, but didn't work too. Is it too big for a stack or might be there infinite loop? How I can fix that?
Lets say that for some reason for
j and j-1 condition in while will are satisfied,
for rest values like j-2 not
So if you invoke fill(j) program will
test while condition for j (pass)
enter while loop
setBackground for j
invoke fill(j-1);.
Now before program will invoke fill(j+1), program will have to finish fill(j-1) so flow of control will be moved to fill(j-1) level and program will
test while condition for j-1 (pass)
you enter while loop
setBackground for j-1
invoke fill((j-1)-1); in other words fill(j-2).
And again before fill((j-1)+1) flow of control will be moved to fill(j-2) so program will
test while condition for j-2 (fail)
program cant enter loop so will return return from fill(j-2)
invoke fill((j-1)+1) which is the same as fill(j)
So your application will try to repeat the same scenario, but this time on different stack level which will lead to StackOverwlow.
To prevent this situation maybe change condition to also test if you already been at this position, like
while(board[j].getName().equals("s") && board[j].getBackground() != Color.yellow)
You can/should also change while to if.
board[j].setName("bgSet")
after
board[j].setBackground(Color.yellow)
this might solve the problem, otherwise your while is always true.
Related
I have a challenge with automating a click action and I'm struggling to understand what's wrong with the logic in my solution.
My challenge is that I need to click one of a number of different radio buttons.
Each radio button has an id of "r" + a_number.
I don't know, for any given test, what the available "r" + a_number options there will be, so I wrote this while loop, which is intended to click the first available radio button:
int counter = 0;
while(true) {
counter++;
try {
driver.findElement(By.id("r" + counter)).click();
} catch (NoSuchElementException e) {
continue;
}
break;
}
This isn't working as intended - could someone help me understand what's wrong?
Note: I'm a novice with Java
Update
My aim is to click the first existing radio button, so the while loop increments the counter var, let's say r=1, then attempts to click a radio button with id "r1". If there is no such element with id "r1", a NoSuchElementException is thrown, in which case the current while loop iteration should stop and start the next iteration (r = 2, try to click element "r2", if does not exist, start next while loop cycle).
Suppose we get to element "r20" and this element does in fact exist, then the button should be clicked, the exception is not thrown and so the while loop continues and hits the break command, and the while loop is terminated.
The current behaviour, however, is that the exception does not get handled even when the element does not exist, the while loop terminates, but nothing has been clicked.`
There are two issues with the code:
Loop running only once- You are breaking the loop using break statement, after the first iteration itself.
No exception thrown- You are not logging the exception. You are only executing a 'continue' statement in the catch block. You do not need the statement because the loop will go to next iteration anyway (well after you remove the break statement).
You should use this code:
int counter = 0;
boolean foundElement = false;
while(!foundElement) {
counter++;
try {
driver.findElement(By.id("r" + counter)).click();
foundElement = true;
} catch (NoSuchElementException e) {
//assuming you want to log exception. Otherwise you can leave the catch block empty.
System.out.println(e);
}
}
Not sure and may need little more information however, I would do it little differently
int counter = 0;
boolean ifNotFound = true;
while(ifNotFound) {
counter++;
try {
driver.findElement(By.id("r" + counter)).click();
ifNotFound = false;
} catch (NoSuchElementException e) {
System.out.println("exception caught");
}
}
I am just trying to click and if it is successful then will set the while loop to false and it will break.
It may be possible that the exception you are catching is not the one is being thrown so you may try to change it to generic Exception and if that works then you can catch more specific one or more than one if you need to.
Please use this:
int counter = 0;
while(true) {
counter++;
boolean elementFound = false;
try {
driver.findElement(By.id("r" + counter)).click();
elementFound = true;
} catch (NoSuchElementException e) {
continue;
}
if (elementFound){
break;
}
}
My program is coded in Java. I have an IF() check in run() method (in a Thread). In the IF check, if the condition is satisfied, it shows a Window dialog (using JOptionPane.showMessageDialog) with OK button. However, it shows infinitely. When I click OK it pops up again and again. How can I end the if check after the user click OK. Or when the condition is met, it only shows once ?
This is my method()
public void danhHoiWumpus()
{
if ((GameScreen.bg[x[0] + 1][y[0]] == 2) || (GameScreen.bg[x[0] + 2][y[0]] == 2) || (GameScreen.bg[x[0] + 3][y[0]] == 2) || (GameScreen.bg[x[0]][y[0]+1] == 2) || (GameScreen.bg[x[0]][y[0]+2] == 2) || (GameScreen.bg[x[0]][y[0]+3] == 2))
{
JOptionPane.showMessageDialog(this, "Có mùi wumpus ! \n Bạn được học bổng 40%");
}
}
This is my run() method
public void run()
{
while(true)
{
hunter.update();
hunter.danhHoiWumpus();
// i++;
repaint();
// System.out.println("Gia tri cua y la " +i);
try {
thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
The idea of this action is. When the RED square is going near the YELLOW square, it will pop up a dialog "I smell Wumpus". When the user click OK. They will choose to shot the wumpus (I will do this later).
And here is my full source code (for reference):
https://www.mediafire.com/?wkp6hyq32nq23mp
Thank you in advance.
Your code is executing in an infinite while loop
while(true)
// I am infinite
}
The term you are looking for is hit detection. There are a myriad of ways to achieve it. Look up hit detection in Java for some pointers.
What you have isn't necessarily wrong though.
while (true) // I'm not always bad!
is used in a lot of applications. However, while your code isn't completely posted, I don't see anywhere you break from this. You may be interested in the
java.util.Timer
and the
java.util.TimerTask
Both of those have wide application in Java game development
Your sleep time is too low (20 nanoseconds). Increase the time, otherwise it will happen too quick for you to understand it.
You are potentially triggering this if condition many many times.
You need some 'rising edge trigger' logic in order to only trigger when the new value goes from false to true, instead of triggering whenever it's true.
currentValue = bigLongLogicCheck;
if(!oldvalue&¤tValue) {alert()}
oldvalue = currentValue
I am developing a small game, (Java, LibGdx) where the player fills cloze-style functions with predefined lines of code. The game would then compile the code and run a small test suite to verify that the function does the stuff it is supposed to.
Compiling and running the code already works, but I am faced with the problem of detecting infinite loops. Consider the following function:
// should compute the sum of [1 .. n]
public int foo(int n) {
int i = 0;
while (n > 0) {
i += n;
// this is the place where the player inserts one of many predefined lines of code
// the right one would be: n--;
// but the player could also insert something silly like: i++;
}
return i;
}
Please note that the functions actually used may be more complex and in general it is not possible to make sure that there cannot be any infinite loops.
Currently I am running the small test suite (provided for every function) in a Thread using an ExecutorService, setting a timeout to abort waiting in case the thread is stuck. The problem with this is, that the threads stuck in an endless loop will run forever in the background, which of course will at some point have a considerable impact on game performance.
// TestClass is the compiled class containing the function above and the corresponding test suite
Callable<Boolean> task = new Callable<Boolean>() {
#Override
public Boolean call() throws Exception {
// call the test suite
return new TestClass().test();
}
};
Future<Boolean> future = executorService.submit(task);
try {
Boolean result = future.get(100, TimeUnit.MILLISECONDS);
System.out.println("result: " + (result == null ? "null" : result.toString()));
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
future.cancel(true);
}
My question is now: How can I gracefully end the threads that accidentally spin inside an endless loop?
*EDIT To clarify why in this case, preventing infinite loops is not possible/feasable: The functions, their test suite and the lines to fill the gaps are loaded from disk. There will be hundrets of functions with at least two lines of code that could be inserted. The player can drag any line into any gap. The effort needed to make sure no combination of function gap/code line produces something that loops infinitely or even runs longer than the timeout grows exponentially with the number of functions. This quickly gets to the point where nobody has the time to check all of these combinations manually. Also, in general, determining, whether a function will finish in time is pretty much impossible because of the halting problem.
There is no such thing as "graceful termination" of a thread inside the same process. The terminated thread can leave inconsistent shared-memory state behind it.
You can either organize things so that each task is started in its own JVM, or make do with forceful termination using the deprecated Thread.stop() method.
Another option is inserting a check into the generated code, but this would require much more effort to implement properly.
The right way is to change the design and avoids never ending loops.
For the time being, inside your loop you could check if the thread is interrupted some way by: isInterrupted() or even isAlive().
And if it is you just exit.
It is not normal to have a never ending loop if it not wanted.
To solve the problem You can add a counter in the loop and if you reach a limit you can exit.
int counter = 0;
while (n > 0) {
counter++;
if (counter > THRESHOLD) {
break;
}
i += n;
// this is the place where the player inserts one of many predefined lines of code
// the right one would be: n--;
// but the player could also insert something silly like: i++;
}
I have been experimenting with try-catch and have been confused on specifically how it works.
try // x is array of 10 doubles set to 0
{
for (int a = 0; a < 11; a+= 2)
x[a] = 5;
}
catch(Exception e)
{
System.out.println("error");
}
In this instance, all values in the array can be reached, but the code breaks at x[10]. So, have all the values been set to 5?
try // x is array of 10 doubles set to 0
{
for (int a = -1; a < 11; a+= 2)
x[a] = 5;
}
catch(Exception e)
{
System.out.println("error");
}
In this instance, it will try x[-1] and catch the error. So, will it not go back and complete the loop (x[0], x[1], ... x[9] )? So, all values still remain 0?
Is this how the try-catch works?
Any help would be appreciated.
Thank you.
Yeah, both examples would throw ArrayIndexOutOfBoundsException.
So,
The try block contains a block of program statements within which an exception might occur. A try block is always followed by a catch block, which handles the exception that occurs in associated try block. A try block must followed by a Catch block or Finally block or both.
A catch block must be associated with a try block. The corresponding catch block executes if an exception of a particular type occurs within the try block. For example if an arithmetic exception occurs in try block then the statements enclosed in catch block for arithmetic exception execute.
try
{
//statements that may cause an exception
}
catch (exception(type) e(object))
{
//error handling code
}
If an exception occurs in try block then the control of execution is passed to the catch block from try block. The exception is caught up by the corresponding catch block. A single try block can have multiple catch statements associated with it, but each catch block can be defined for only one exception class. The program can also contain nested try-catch-finally blocks.
After the execution of all the try blocks, the code inside the finally block executes. It is not mandatory to include a finally block at all, but if you do, it will run regardless of whether an exception was thrown and handled by the try and catch blocks.
Try-Catch
The code within the try block is code that will run but if the code in the try block throws an exception/error then it is caught in catch block.
The issue with your code is you are using the x as an array and you may not be able to set a specific spot in an array, to set that you could do something like x.push or x.put I am not sure on the specific property as I do not know java well. The other issue could be that your index is out of bounds, which means that you may have an array of 10 items that is zero based and you are trying to access an 11th item. so your loop should be something like:
{
for (int a = 0; a < x.length; a+= 2)
x[a] = 5;
}
When a statement throws an exception inside of a try block, the next statement is the first statement of the catch block.
In the first example, the first few iterations of the for loop happen as normal and elements 0, 2, 4, 6, and 8 are set to 5. On the iteration where a is 10, the attempt to access x[10] the runtime throws an ArrayIndexOutOfBoundsException and jumps to the first statement of the catch block. The rest of x is unmodified.
In the second example, the first iteration of the for loop causes the runtime to throw an ArrayIndexOutOfBoundsException (due to the attempt to access x[-1]) and jump to the first statement of the catch block. The effect is that x is completely unmodified.
For more information about exceptions in Java, read the The Java Tutorials: Exceptions.
So I was wondering if there was anyway I could implement this code so that it pauses on each loop iteration. Currently, when I run the code, the program will stop for n seconds (n being the amount of loop iterations) and then display everything at once. However, I wish for it to display one item, wait one second and display the next item. I hope this is clear.
while(x > 0 || y > 0){
Try{
Thread.sleep(1000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
// Print x and y
//Change x and y vals
}
}
First, don't suppress InterruptedException. If there's nothing to be done about it, simply don't catch it at all, or convert it into a RuntimeException e.g.
throw new RuntimeException(ie);
Second, it sounds like you're describing a flushing problem, which can be addressed by adding calls to:
System.out.flush();
After you print your values. As mentioned in the linked question however, System.out and System.err auto-flush whenever a new line is printed; are you not printing to stdout, or not printing new lines?
You should have a Thread.sleep() call wherever you need the program to pause, so if you need to pause between printing x and y, add another Thread.sleep() between them.
Suggestion: separate the thread sleep in a method to do the job without rewriting all this code.
Suggestion 2: search aroung if thread sleep is the best solution for you
Try this:
public void waitSeconds(int seconds){
try{
Thread.sleep(seconds*1000l);
} catch(Exception e) {
e.printStackTrace(); //ugly but enough to explain
};
}
public void yourMethod(){
while(x > 0 || y > 0){
waitSeconds(1);
print x
waitSeconds(1);
print y
//Change x and y vals
}
}
It's really strange. Try this way:
while(x > 0 || y > 0) {
// Print old values
// Change your x and y
// Print new values
try {
TimeUnit.SECONDS.sleep(y);
} catch(InterruptedException ex) {}
}