Background: I am making a chess game. It works almost completely, just missing the check for checkmate, but I am refining some code for readability, etc.
Right now, I am recoding a method I had to check the path from any piece, to another location on the board. It returns true if there is a piece blocking the path and false if there is not one.
Note: I do not need to check the spot of the last location because my game will check to make sure that you do not occupy the spot you are trying to move to.
Also note that I have researched this question and I have found that the consensus, mainly on here, is that breaking is the correct solution. This is preferred over having a boolean variable initialized outside the loop and set true or false and breaking the loop on that value. However, I have two conditions in my loop that may make my code return true or return false so I can't do that completely.
Current Code
public boolean isPathClear(Location l1, Location l2) {
int atx = l1.getX();
int aty = l1.getY();
int xdiff = 0, ydiff = 0;
int endx = l2.getX(), endy = l2.getY();
if(l1.getX() > l2.getX()) {
xdiff = 1;
}
if(l1.getX() < l2.getX()) {
xdiff = -1;
}
if(l1.getY() > l2.getY()) {
ydiff = 1;
}
if(l1.getY() < l2.getY()) {
ydiff = -1;
}
while(true) {
atx += xdiff;
aty += ydiff;
if(atx == endx && aty == endy) {
return true
}
if(board[atx][aty].getType() != ' ') {
return false;
}
}
Problem: Since breaking is the preferred method, that is what I planned to do. But, I came into a problem, if I use break in one of the if statements, it looks like I have to return in the other. Like:
while(true) {
atx += xdiff;
aty += ydiff;
if(atx == endx && aty == endy) {
break;
}
if(board[atx][aty].getType() != ' ') {
return false;
}
}
return true;
Question: This seems like a sort of mix that could be confusing. So with my situation, would this still be the preferred method over this code:
boolean clear;
while(true) {
atx += xdiff;
aty += ydiff;
if(atx == endx && aty == endy) {
clear = true;
break;
}
if(board[atx][aty].getType() != ' ') {
clear = false;
break;
}
}
return clear;
Yes, returning early is normally preferred rather than having to finish iterating over the entire collection when it's not needed, unless there's something else going on that warrants a complete iteration (finding the minimum/maximum value, etc.)
Overusing break statements is also bad practice because it introduces more exit points. We generally want to keep exit points to a minimum since multiple exit points complicate our logic and make it more difficult to comprehend code.
To break out of a for loop, you can use the endloop, continue, resume, or return statement. endfor; If condition is true, statementlist2 is not executed in that pass through the loop, and the entire loop is closed.
To break out of a while loop, you can use the endloop, continue, resume, or return statement. endwhile; If the name is empty, the other statements are not executed in that pass through the loop, and the entire loop is closed.
Instead of while(true)
, you can try to handle your actual conditions inside the while
loop and you don't need additional break
statements:
public boolean isPathClear(Location l1, Location l2) {
int atx = l1.getX(), aty = l1.getY();
int endx = l2.getX(), enxy = l2.getY();
int xdiff = Integer.signum(endx - atx);
int ydiff = Integer.signum(endy - aty);
do{
atx += xdiff;
aty += ydiff;
} while(!(atx == endx && aty == endy) && board[atx][aty].getType() == ' ');
return atx == endx && aty == endy;
}
If you want to do it using break
- it doesn't really matter - but I prefer this:
boolean notObstructed = true;
while(notObstructed) {
atx += xdiff;
aty += ydiff;
if(atx == endx && aty == endy)
break;
if(board[atx][aty].getType() != ' ')
notObstructed = false;
}
return notObstructed;
This way there's only one return statement whose value is configured based on the while
loop and if
statements.
Mostly I'd say it's a subjective thing.
One objective advantage to your last code sample is that it gives you a single point of exit from the method, which is frequently useful for debugging. A guy I used to work with who did military software previously said it was a requirement they had to work to: A method must only have a single exit point. His claim was that it was a robustness/reliability/maintainability thing. I just like having that easy "here's where it leaves" thing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With