0

As part of some procedural generation code, I have a function that checks if a cell in a grid has any neighbouring cells.

The grid is a 2D array, if it was printed it would look like this (# = cell and . = empty and the # around the edge is a border):

 0123456789
0##########
1#........#
2#........#
3#........#
4#........#
5#....##..#
6#........#
7#........#
8#........#
9##########

So, for example, my code returns true if it checks cell 5,5.

The code I have written for checking for neighbouring cells works, but does not take into account if the cell it is checking is at the "edge" (eg. 0,0 or 0,1 or 10,10) and will create out of bound errors if it does check cells at the edge. I'm unsure of how to go about writing code that does take this into account, any advice would be appreciated.

This is my code so far:

public static bool HasNeighbour(int[,] array, int CellX, int CellY)
{

    if (array[CellX + 1, CellY] == 1)
    {
        return true;
    }

    if (array[CellX - 1, CellY] == 1)
    {
        return true;
    }

    if (array[CellX, CellY + 1] == 1)
    {
        return true;
    }

    if (array[CellX, CellY - 1] == 1)
    {
        return true;
    }

    if (array[CellX + 1, CellY + 1] == 1)
    {
        return true;
    }

    if (array[CellX + 1, CellY - 1] == 1)
    {
        return true;
    }

    if (array[CellX - 1, CellY + 1] == 1)
    {
        return true;
    }

    if (array[CellX - 1, CellY - 1] == 1)
    {
        return true;
    }
    return false;
}

Also, is there a more efficient version of my code?

Thanks

user9993
  • 5,833
  • 11
  • 56
  • 117

1 Answers1

1

Try this code (bounds check included):

public static bool HasNeighbour(int[,] array, int CellX, int CellY) {
  for (int i = -1; i <= 1; ++i)
    for (int j = -1; j <= 1; ++j)
      if ((i != 0) && (j != 0)) {
        int x = CellX + i;

        if ((x < 0) || (x >= array.GetLength(0)))
          continue;

        int y = CellY + j;

        if ((y < 0) || (y >= array.GetLength(1)))
          continue; 

        if (array[x, y])
          return true;
      }

  return false;
}
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • Hi, thanks for the reply. Could you explain which part is the bound checks, I'm guessing it's the parts with "array.GetLength()"? – user9993 Jul 28 '13 at 14:36
  • yes, you are quite right: x should be within [0..array.GetLength(0) - 1] when y should be within [0..array.GetLength(1)] – Dmitry Bychenko Jul 28 '13 at 14:42
  • Ok thanks. Could you explain the two for loops, I'm not clear of what they are for? Thanks – user9993 Jul 28 '13 at 15:37
  • well, x should be in [CellX - 1..CellX + 1] range, while y should be in [CellY - 1..CellY + 1] range - that's loop origin. Sure, array[CellX, CellY] is not a neighbour, it's a position itself, that's why I check "if ((i != 0) && (j != 0))" – Dmitry Bychenko Jul 29 '13 at 05:44