Reputation: 209
I'm trying to write a program that checks neighbouring entries of the matrix. Problem is the entry might be at an edge, in which case trying to get next entry will throw an exception. That's why I've added an empty catch block to ignore it, but after catch block it returns true. I want the program to check every single entry and ignore exception. I could do this with many if statements, but is there a better way?
private static boolean ShipSunk(char letter, int col) {
try {
int row = letter - 'A' + 1;
if (
matrix[row + 1][col].equals("O") ||
matrix[row - 1][col].equals("O") ||
matrix[row][col + 1].equals("O") ||
matrix[row][col - 1].equals("O")
) {
return false;
}
} catch (ArrayIndexOutOfBoundsException e) {
}
return true;
}
Upvotes: 1
Views: 863
Reputation: 209
Thanks for the suggestions. This is how I've rewritten my code:
private static boolean ShipSunk(char letter, int col) {
int row = letter - 'A' + 1;
if (row + 1 < matrix.length) {
if (matrix[row + 1][col].equals("O")) return false;
}
if (row > 0) {
if (matrix[row - 1][col].equals("O")) return false;
}
if (col + 1 < matrix[0].length) {
if (matrix[row][col + 1].equals("O")) return false;
}
if (col > 0) {
if (matrix[row][col - 1].equals("O")) return false;
}
return true;
}
This is not as sophisticated as other answers, but it's simple and it works correctly (I think).
Upvotes: 0
Reputation: 6905
You could do something like this...
private static boolean ShipSunk(char letter, int col) {
int row = letter - 'A' + 1;
if (squareEqualsO(row + 1, col) ||
squareEqualsO(row - 1, col) ||
squareEqualsO(row, col + 1) ||
squareEqualsO(row, col - 1)
) {
return false;
}
return true;
}
private static boolean squareEqualsO(int row, int col) {
if ((row >= matrix.length) || (row < 0)) {
return false;
} else if ((col >= matrix[row].length) || (col < 0)) {
return false;
} else {
return matrix[row][col].equals("O");
}
}
Upvotes: 3
Reputation: 5166
You can continue if you are in a for
loop:
private static boolean ShipSunk(char letter, int col) {
int row = letter - 'A' + 1;
int r = 2;
int c = 1;
for (int i = 0; i < 4; i++) {
try {
if (matrix[row + r % 2][col + c % 2].equals("O")) {
return false;
}
} catch (ArrayIndexOutOfBoundsException e) {
continue;
} finally {
r -= 1;
c -= 1;
}
}
return true;
}
The sequence of r
is [2, 1, 0, -1]
, then, the sequence of r % 2
is [0, 1, 0, -1].
The sequence of c
is [1, 0, -1, -2]
, then, the sequence of c % 2
is [1, 0, -1, 0]
.
Thus, the sequence of (r % 2, c % 2)
is [(0, 1), (1, 0), (0, -1), (-1, 0)]
You can check all neighbors through the for
loop.
Upvotes: 1
Reputation: 1027
You're actually trying to solve two problems inside of one function - 1) validating the input 2) checking if something was hit. Therefore you're doing better using one function per problem. If you're knowing upfront the limits of your grid, check if the input is inside the range. A basic approach could roughly look like this:
private boolean isInputValid(char letter, int col) {
if(col < 0 || col > MAX_COL) return false;
if(letter > MAX_LETTER || letter < MIN_LETTER) return false;
}
private static boolean ShipSunk(char letter, int col) {
if(isInputValid(letter,col) {
/* check if hit */
} else {
/* React to invalid input; e.g. count it as always miss */
}
}
There are other, also better approaches - like throwing a new IllegalArgumentException("your error message")
for an invalid coordinate. But this is something you should consider how to approach upfront.
P.S.
Please remember, that convention says you should pick lowercase names for your functions. You can save yourself and basically everyone you will be working with ever a lot of headaches.
Upvotes: 0