Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Practice for breaking or returning in a loop

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;
like image 988
Matt C Avatar asked Dec 19 '13 17:12

Matt C


People also ask

Is it a good practice to return from loop?

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.)

Is it bad practice to use break in a for loop?

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.

How do you break in a for loop?

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.

How do you break a repeat loop?

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.


3 Answers

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;
}
like image 139
bcorso Avatar answered Sep 19 '22 12:09

bcorso


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.

like image 29
asaini007 Avatar answered Sep 17 '22 12:09

asaini007


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.

like image 29
T.J. Crowder Avatar answered Sep 20 '22 12:09

T.J. Crowder