Checking for neighbours more elegantly in Conway's Game of Life My method for counting neighbors in my soon-to-be Game of Life implementation is very repetitive and I was wondering if this could be done more elegantly:

static int countNeighbours(Board b, int x, int y) {
    int count = 0;
    if (b.getTile(x - 1, y - 1)) {
        ++count;
    }
    if (b.getTile(x, y - 1)) {
        ++count;
    }
    if (b.getTile(x + 1, y - 1)) {
        ++count;
    }
    if (b.getTile(x + 1, y)) {
        ++count;
    }
    if (b.getTile(x + 1, y + 1)) {
        ++count;
    }
    if (b.getTile(x, y + 1)) {
        ++count;
    }
    if (b.getTile(x - 1, y + 1)) {
        ++count;
    }
    if (b.getTile(x - 1, y)) {
        ++count;
    }
    return count;
}


Because officially the board should be infinite, I don't need out-of-bounds checks in this code - I assume the board is infinite here -, but my Board implementation secretly looks like this:

// TODO: make the board 'infinite'
public boolean getTile(int x, int y) {
    if (x &lt; 0 || y &lt; 0 || x &gt; getWidth() - 1 || y &gt; getHeight() -1) return false;
    return tiles[y][x];
}

public void setTile(int x, int y, boolean val) {
    if (x &lt; 0 || y &lt; 0 || x &gt; getWidth() - 1 || y &gt; getHeight() -1) return;
    tiles[y][x] = val;
}


(Just to save you the time it costs to type 'your code will cause an IndexOutOfBoundsException for the tile on (0,0)'. This question is on the implementation of static int countNeighbours(Board, int, int).)

I'm stuck with Java 6 by the way.
You're right, there's an alternate way to do this, but, first, some Java standards:


1-liners should have braces. This is a code-style that is common to many langauges because it is more maintainable, and leads to fewer future bugs. Lines like:


if (x &lt; 0 || y &lt; 0 || x &gt; getWidth() - 1 || y &gt; getHeight() -1) return;



should be:

if (x &lt; 0 || y &lt; 0 || x &gt; getWidth() - 1 || y &gt; getHeight() -1) {
    return;
}

Don't use arithmetic when you can use a simpler operator. Back to:


if (x &lt; 0 || y &lt; 0 || x &gt; getWidth() - 1 || y &gt; getHeight() -1) { ... }



Which can be simplified to:

if (x &lt; 0 || y &lt; 0 || x &gt;= getWidth() || y &gt;= getHeight()) { ...}

Use plain booleans when they make sense (again, back to...):


if (x &lt; 0 || y &lt; 0 || x &gt;= getWidth() || y &gt;= getHeight()) { ...}



which can be put in a function like (transformed to uses &amp;&amp; instead):

public boolean getTile(int x, int y) {
    return x &gt;= 0 &amp;&amp; y &gt;= 0 &amp;&amp; x &lt; getWidth() &amp;&amp; y &lt; getHeight() &amp;&amp; tile[y][x];
}


Note, how the standard boolean short-circuit evaluation ensures that the x and y are valid before the tile[y][x] is used.


OK, about that code duplication. A trick with these sorts of problems is to use an array of offsets. Consider your grid, which has 8 neighbours (in a relative y,x format):

-1,-1     -1,0    -1,+1

 0,-1     *us*     0,+1

+1,-1     +1,0    +1,+1


We can put these neighbour offsets in to an array:

private static final int[][] NEIGHBOURS = {
    {-1, -1}, {-1, 0}, {-1, +1},
    { 0, -1},          { 0, +1},
    {+1, -1}, {+1, 0}, {+1, +1}};


Then, your check method becomes:

static int countNeighbours(Board b, int x, int y) {
    int cnt = 0;
    for (int[] offset : NEIGHBOURS) {
        if (b.getTile(x + offset[1], y + offset[0]) {
           cnt++;
        }
    }
    return cnt;
 }