Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way of avoiding this block of code?

Tags:

java

I am remaking minesweeper for practice, and wrote this bit of code to avoid IndexOutOfBounds errors. Is there a way of avoiding this so I don't have to explicitly write out an if statement every possible error? I thought of making each array 2 indexes larger, and just ignoring the first and last index. Am I missing something obvious?

        if (row > 0 && col > 0)
            ray[row - 1][col - 1] += 1;
        if (row > 0)
            ray[row - 1][col] += 1;
        if (row > 0 && col < height - 1)
            ray[row - 1][col + 1] += 1;
        if (col > 0)
            ray[row][col - 1] += 1;
        if (col < height - 1)
            ray[row][col + 1] += 1;
        if (row < width - 1 && col > 0)
            ray[row + 1][col - 1] += 1;
        if (row < width - 1)
            ray[row + 1][col] += 1;
        if (row < width - 1 && col < height - 1)
            ray[row + 1][col + 1] += 1;
like image 392
elodin Avatar asked Mar 18 '13 04:03

elodin


2 Answers

You can use a loop instead and define the bounds once. Something like:

int startRow = max(row - 1, 0);
int endRow = min(row + 1, width - 1);

int startCol = max(col - 1, 0);
int endCol = min(col + 1, height - 1);

for (int r = startRow; r <= endRow; r++)
   for (int c = startCol; c <= endCol; c++)
       if (r != row || c != col) //it looks like you want to skip this cell
           ray[r][c] += 1;

Alternatively, if the operation is reversible (as in this code, you are adding 1), you can simply reverse the operation for the middle cell after the loop. This would be more efficient since it eliminates (at most) 12 comparisons, provided the operation itself were simple:

int startRow = max(row - 1, 0);
int endRow = min(row + 1, width - 1);

int startCol = max(col - 1, 0);
int endCol = min(col + 1, height - 1);

for (int r = startRow; r <= endRow; r++)
   for (int c = startCol; c <= endCol; c++)
       ray[r][c] += 1;

//reverse the operation for the middle cell
ray[row][col] -= 1;
like image 191
lc. Avatar answered Sep 21 '22 08:09

lc.


You can simplify your code a bit by using nested if statements. (For instance, you wouldn't need to check that row > 0 more than once.)

However, I'd go with making the array 2 larger n each dimension, let row vary from 1 through height and col vary from 1 through width, and ignore what happens at the edges.

In your code, you seem to be pairing row with width and col with height, which seems backwards to me.

like image 38
Ted Hopp Avatar answered Sep 21 '22 08:09

Ted Hopp