Game of Life in Java I wrote John Conway's Game of Life in Java:

class GameOfLife {
    static int countSurrounding(int[][] board, int a, int b) {
        int count = 0;
        int[][] surrounding = {{a - 1, b - 1},
                               {a - 1, b    },
                               {a - 1, b + 1},
                               {a    , b - 1},
                               {a    , b + 1},
                               {a + 1, b - 1},
                               {a + 1, b    },
                               {a + 1, b + 1}};
        for (int i[]: surrounding) {
            try {
                if (board[i[0]][i[1]] == 1) {
                    count++;
                }
            }
            catch (ArrayIndexOutOfBoundsException e) {}
        }
        return count;
    }

    static void printBoard(int[][] board) {
        for (int[] i: board) {
            for (int j: i) {
                if (j == 1) {
                    System.out.print("#");
                }
                else {
                    System.out.print(".");
                }
            }
            System.out.println();
        }
        System.out.println();
    }

    public static void main(String[] args) {
        int[][] nextBoard = {{0, 0, 0, 0, 0, 0, 0, 0, 0},
                              {0, 0, 0, 1, 0, 0, 0, 0, 0},
                              {0, 1, 0, 1, 0, 0, 0, 0, 0},
                              {0, 0, 1, 1, 0, 0, 0, 0, 0},
                              {0, 0, 0, 0, 0, 0, 0, 0, 0},
                              {0, 0, 0, 0, 0, 0, 0, 0, 0},
                              {0, 0, 0, 0, 0, 0, 0, 0, 0},
                              {0, 0, 0, 0, 0, 0, 0, 0, 0},
                              {0, 0, 0, 0, 0, 0, 0, 0, 0}};
        int[][] board = new int[nextBoard.length][nextBoard[0].length];
        for (int gen = 0; gen &lt; 25; gen++) {
            for (int i = 0; i &lt; nextBoard.length; i++) {
                for (int j = 0; j &lt; nextBoard[i].length; j++) {
                    board[i][j] = nextBoard[i][j];
                }
            }
            printBoard(board);
            for (int i = 0; i &lt; board.length; i++) {
                for (int j = 0; j &lt; board[i].length; j++) {
                    if (board[i][j] == 1 &amp;&amp; !(countSurrounding(board, i, j) == 2 || countSurrounding(board, i, j) == 3)) {
                        nextBoard[i][j] = 0;
                    }
                    else if    (board[i][j] == 0 &amp;&amp; countSurrounding(board, i, j) == 3) {
                        nextBoard[i][j] = 1;
                    }
                }
            }
        }
    }
}


How can I improve and optimize it?
A few suggestions:


Each cell in the Game of Life has exactly two states: dead or alive. Unless you plan to implement -1 as undead, I'd suggest you use booleans instead of integers to indicate the state.
The int i[] is a bit odd; i is normally used for indices, not for whole rows.
In countSurrounding you are using Exceptions to count the surrounding living cells. This is wasteful and unnecessary; we can determine the correct bounds ourself.

Given an index i in an array row, we can get the lower index min and the upper index max by

int minRow = i == 0 ? 0 : i - 1;
int maxRow = i == (row.length - 1) ? (row.length - 1) : i + 1;


The same thing for columns (j index in an array column):

int minCol = j == 0 ? 0 : j - 1;
int maxCol = j == (column.length - 1) ? (column.length - 1) : j + 1;


This itself assumes that i and j always are inside the bounds. We can then loop over the surrounding cells like

for (int row_idx = minRow; row_idx &lt;= maxRow; row_idx++) {
   for (int idx = minCol; idx &lt;= maxCol; idx++) {
     if (board[row_idx][idx] &amp;&amp; !(row_idx == i &amp;&amp; idx == j)) { // assumes board is implemented with booleans
        count++
     }
   }
}


While this is longer, this doesn't abuse exceptions for something totally non-exceptional.
The printBoard is fine, except for my first two criticisms. The if/else can be condensed to a ternary; I'd find this easier to read:

for (boolean row[] : board) {
   for (boolean cell : row) {
      System.out.print( cell ? "#" : "." );
   }
   System.out.println();
}

In main, you initialize nextBoard with the initial board, then copy it over into board. This is slightly useless. I'd propose to refactor your main into a method boolean[][] nextGeneration(boolean[][] board). Your main would then look like

int[][] initialBoard = ...;
public static void main(String[] args) {
   int[][] board = new int[nextBoard.length][nextBoard[0].length];
   // copy over the initial board
   for (int i = 0; i &lt; initialBoard.length; i++) {
      for (int j = 0; j &lt; initalBoard[i].length; j++) {
         board[i][j] = initialBoard[i][j];
      }
   }
   // loop over 25 generations
   printBoard(board);
   for (int gen = 0; gen &lt; 25; gen++) {
      System.out.println("\nGeneration " + gen);
      board = nextGeneration(board);
      printBoard(board);
   }
}

Now something is becoming obvious: We have collected a few static methods that operate on our board array. This is a sign that we should create a seperate class:

Board
========
- board: boolean[][]
--------
- countSurrounding(i: int, j: int): int
+ toString(): String
+ nextGeneration(): Board


The class could be easily extended to have a static default board, or a constructor that creates a random board.
Each “Game of Life” can be described by a ruleset like 23/3. The digits before the slash determine when a living cell stays alive, the digits after the slash determine when a new cell is born. Generalizing nextGeneration to be able to play with all possible rules is a nice exercise.

private boolean nextCellState(int i, int j) {
   int count = countSurrounding(i, j);
   int rules[] = board[i][j] ? stayAlive : birthNew;
   for (int rule : rules) {
      if (rule == count) {
         return true;
      }
   }
   return false;
}


then

public Board nextGeneration() {
   boolean next[][] = new boolean[board.length][board[0].length];
   int rows = board.length;
   int cols = board.[0].length;
   for (int i = 0; i &lt; rows; i++) {
      for (int j = 0; j &lt; cols; j++) {
         next[i][j] = nextCellState(i, j);
      }
   }
   return new Board(next);
}