0

I have a 2D array which acts as a game board and the user can make moves into certain cells etc and each user has a specific id e.g. player 1 replaces the cells in the array with their playerId = 1.

I am trying to create a method to find out when the user's playerId gets stuck. They get stuck when they are surrounded by another a value which is not 0.

For example, if player 1 is in the cell 2,5 then P(which represents a 0) is the possible moves they can make. However, if the player was surrounded by other values then they should not be able to make a move (return false).

xxxPPPxxxx
xxxP1Pxxxx
xxxPPPxxxx
xxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx

Method:

public boolean checkBlocked(int[][] array,List<Coordinates> track,int playerId)
{
    boolean blocked = false;
    int trueCount = 0;
    for (Coordinates cells: track)
    {
        int x = cells.getX();
        int y = cells.getY();
        if(array[x-1][y-1] == 0 ) trueCount++; //topleft
        if(array[x-1][y] == 0) trueCount++; //top
        if(array[x-1][y+1] == 0) trueCount++;//topright
        if(array[x][y+1] == 0) trueCount++;//right
        if(array[x][y-1] == 0) trueCount++;//left
        if(array[x+1][y-1] == 0) trueCount++;//bottomleft
        if(array[x+1][y] == 0) trueCount++;//bottom
        if(array[x+1][y+1] == 0) trueCount++; //bottomright
    }

    if (trueCount == 0)
    {
        blocked = true;
    }
    return blocked;
}

I tried to do this method, but then this doesn't work because the 2D array is 6x10 and then if the cell is 1,1 or 6,1 then it gives an ArrayIndexOutOfBoundsException.

Is there an easier way that I can do this check or a way around the exception?

JameshGong
  • 155
  • 10
  • well you can check for the length of the array before accessing the position – JacksOnF1re Nov 29 '18 at 15:33
  • Just for the record: A) the name "array" is not telling anything to the reader B) that param playerId isn't use in that method, so dont put it into the signature. Instead of having a separate "trueCount" ... simply return false for all places that say trueCount++, and return true (once, in the end of your method). – GhostCat Nov 29 '18 at 15:36
  • 1
    @GhostCat will change that up, thanks for the advice. – JameshGong Nov 29 '18 at 15:41

2 Answers2

0

Three solutions

  • Make the array larger in all directions (and make walls that are invisible/impenetrable) -- This has the highest performance and is my favorite trick for image processing.
  • Make a method like getBoardSquare that does the bounds checking for you and returns a special value (or 'wall' value) for out-of-bound coordinates -- this has the best 'code readability'
  • Do manual extensive bounds checking wherever you access the array -- not recommended
Mark Jeronimus
  • 9,278
  • 3
  • 37
  • 50
0

You have to check that surround cells are in the board. To do so you could add additional checks to all of the if. E.g.:

if(x > 0 && y > 0 && array[x-1][y-1] == 0) trueCount++;
if(x > 0 && array[x-1][y] == 0) trueCount++;
if(x > 0 && y < array[x-1].length - 1 && array[x-1][y+1] == 0) trueCount++;

I think, it is better to create separate method with internal check:

private static int get(int[][] array, int row, int col) {
    return row < 0 || row >= arr.length || col < 0 || col >= array[row].length ? 0 : array[row][col];
}

and us it in your if:

if(get(array, x-1, y-1) == 0) trueCount++;
if(get(array, x-1, y) == 0) trueCount++;
if(get(array, x-1, y+1) == 0) trueCount++;

Finally, I think it's better to encapsulate Board logic into separate class:

public class Board {

    private final int[][] board;

    public Board(int row, int col) {
        board = new int[row][col];
    }

    public boolean isBlocked(int row, int col) {
        if (cell(row - 1, col - 1) == 0 || cell(row - 1, col) == 0 || cell(row - 1, col + 1) == 0)
            return false;
        if (cell(row, col + 1) == 0 || cell(row, col - 1) == 0)
            return false;
        if (cell(row + 1, col - 1) == 0 || cell(row + 1, col) == 0 || cell(row + 1, col + 1) == 0)
            return false;

        return true;
    }

    private int cell(int row, int col) {
        return row < 0 || row >= board.length || col < 0 || col >= board[row].length ? 0 : board[row][col];
    }

}

P.S.

Check your x and y. x - column and y - row, so it means arr[y][x] but not arr[x][y]!

Oleg Cherednik
  • 17,377
  • 4
  • 21
  • 35