JFreeman
JFreeman

Reputation: 1004

Java change long if statement into for loop

I have an if statement that looks like this:

                if (pan[x + 1][y + 1].getBackground() == TeamColor &&
                        pan[x + 1][y].getBackground() == TeamColor &&
                        pan[x + 1][y -1].getBackground() == TeamColor &&
                        pan[x][y - 1].getBackground() == TeamColor &&
                        pan[x - 1][y - 1].getBackground() == TeamColor &&
                        pan[x - 1][y].getBackground() == TeamColor &&
                        pan[x - 1][y + 1].getBackground() == TeamColor &&
                        pan[x][y + 1].getBackground() == TeamColor) {

                        // do something
                }

The goal is to check every item (in a 2d array) around the current x and y values and make sure they are the correct color.

I assume there is a simple way to do such. I would assume creating a for loop would solve the problem by iterating through each item but unfortunately was not able to think of a way to do this because the items are not all in sequence.

NOTE: i found many other posts on stackoverflow that where titled "solution for very long if statement" unfortunately they were in different programing languages (such as python, android and javascript)

NOTE 2: this is Not a duplicate of this post. It was a question of strings and regex and unfortunately not the solution to my problem

Hopefully someone will have an answer!

Upvotes: 1

Views: 446

Answers (3)

davidxxx
davidxxx

Reputation: 131456

I can propose two ways :

1) Full object way

You could introduce a custom class Coordinate that holds two values : the x and y coordinates.
Create a List of Coordinate where you had the Coordinate element you want to test and iterate on it to achieve your need.

public class Coordinate{

  private final int x;
  private final int y;

  public Coordinate(int x, int y){
     this.x = x;
     this.y = y;
  }

  public getX(){
    return x;
  }

  public getY(){
    return y;
  }
}

And you can use it :

List<Coordinate> coordinates = new ArrayList<>();

coordinates.add(new Coordinate(1,1));
coordinates.add(new Coordinate(1,0));
coordinates.add(new Coordinate(1,-1));
coordinates.add(new Coordinate(0,-1));
coordinates.add(new Coordinate(-1,-1));
coordinates.add(new Coordinate(-1,0));
coordinates.add(new Coordinate(-1,1));
coordinates.add(new Coordinate(0,1)); 

// you can also init them with a loop     

boolean isMatched = true;
for (Coordinate coordinate : coordinates){
    if (pan[x + coordinate.getX()][y + coordinate.getY()].getBackground() != TeamColor){
      isMatched = false;
      break;
    }
}

The object way is more verbose but it has the advantage to expose rules.
So you can read and change it easily.
Suppose, the rules to check become more complex, it becomes very valuable.

2) Shorter code way

It is the same logical even by inlining values of Coordinate and by ignoring the specific case that you don't want to test (no change case).

boolean isMatched = true;
for (int xDelta = -1; xDelta <=1; xDelta++){
   for (int yDelta = -1; yDelta <=1; yDelta++){
      // as you don't want to test if no change
      if (yDelta == 0 && xDelta ==0){
          continue;
      }
      if (pan[x + xDelta][y + yDelta ].getBackground() != TeamColor){
        isMatched = false;
        break;
      }
}

Upvotes: 1

Mac
Mac

Reputation: 14791

Try something like this:

boolean match = true;
for (int dx = -1; match && (dx < 2); ++dx) {
    for (int dy = -1; match && (dy < 2); ++dy) {
        if (dx != 0 || dy != 0) {
            match = pan[x+dx][y+dy].getBackground() == TeamColour;
        }
    }
}
if (match) {
    // do something
}

Basically, you want to check offsets -1, 0 and 1 in each direction, so we have two for loops, each producing those offsets in one dimension. We then check the array element corresponding to each offset, and keep track using the match variable.

Note though that, like the original code, this will fail near boundaries (e.g. if x == 0). This can be fixed if necessary.

It is possible, of course, to instead have the loops run over the actual indices to check (e.g. for (int x2 = x-1; x2 < x+2; ++x)). It's much the same in the end.

Upvotes: 3

Zedee.Chen
Zedee.Chen

Reputation: 212

for (int a = x-1;a <= x+1;a++)
{
   if (a < 0 || a >= pan.length) continue;
   for (int b = y-1; b <= y+1; b++)
   {
        if (b < 0 || b >= pan[a].length) continue;
        if (a == x && b == y) continue;
        if (pan[a][b].getBackground() != TeamColor)
             return false;
   }
}
return true;

Upvotes: 1

Related Questions