2
\$\begingroup\$

As it currently stands the code works fine. Is there a way to optimize the code in the class Neighbours? What I have done was to copy the code for each of the adjacent 8 neighbours of the cell and implemented a try catch ArrayIndexOutOfBoundsException. Is there a way to optimize it by use of arrays or a different method? Is there a way to remove the try catch block?

/////// THIS IS A PROGRAM FOR CONWAY'S GAME OF LIFE FOR MORE INFORMATION ON THE GAME VISIT http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life  //////////
/////// rulues of the game //////
/*1. A filled cell with fewer than two filled neighbors dies through loneliness and is empty in the next generation.

2. A filled cell with more than three filled neighbors dies through over-crowding, and is empty in the next generation.

3. An empty cell with exactly three filled neighbors ‘gives birth’ and is filled in the next generation.

4. Filled cells with two or three neighbors live on to the next generation. */

import java.awt.*;
import javax.swing.*;
import java.util.*;
import java.util.Timer;

public  class GameOfLife extends Canvas {

    public static void printf(String text) { // shortening System.out.println() to just printf() for easy access and faster typing

        System.out.println(text);

    }

    private static final long serialVersionUID = 1L;
    Scanner scan = new Scanner(System.in);
    int num = scan.nextInt();
    int[][] oldGen = new int[num][num]; // array for the old generation
    int[][] newGen = new int[num][num]; // array for the new generation
    // int[][] Old and int[][] New constantly change to display the update for the "living cells"

    public GameOfLife() { // filling int[][] Old with the data for the x coordinate and cell status
        Random rand = new Random();
        for (int xCoord = 0; xCoord < num; xCoord++) {
            for (int status = 0; status < num; status++) {
                oldGen[xCoord][status] = rand.nextInt(2);
            }
        }
    }

    public void paint(Graphics graphics) { // creating the graphical representation 
        for (int xCoord = 0; xCoord < num; xCoord++) {
            for (int status = 0; status < num; status++) {
                if (oldGen[xCoord][status] == 1) {
                    Color color = new Color(255, 0, 0);
                    graphics.setColor(color);
                    graphics.fillOval(xCoord * 10, status * 10, 10, 10);
                } else {
                    graphics.clearRect(xCoord * 10, status * 10, 10, 10);
                }
            }
        }
    }

    public void Generations() {
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new Neighbours(), 200, 200); // timer for refreshing the grid
    }

    class Neighbours extends TimerTask { // cheking the status of the neighbouring cells
        public void run() 
        {
            int neighbour1;
            int neighbour2;
            int neighbour3;
            int neighbour4;
            int neighbour5;
            int neighbour6;
            int neighbour7;
            int neighbour8;
            int neighbours;

            for (int xCoord=0; xCoord < num; xCoord++) {
                for (int yCoord=0; yCoord < num; yCoord++) {
                    //Get the eight adjacent squares to the square being checked
                    try {
                        neighbour1 = oldGen[xCoord-1][yCoord-1];
                    }
                    catch (ArrayIndexOutOfBoundsException e) {
                        neighbour1 = 0;
                    }
                    try {
                        neighbour2 = oldGen[xCoord-1][yCoord];
                    }
                    catch (ArrayIndexOutOfBoundsException e) {
                        neighbour2 = 0;
                    }                    
                    try {
                        neighbour3 = oldGen[xCoord-1][yCoord+1];
                    }
                    catch (ArrayIndexOutOfBoundsException e) {
                        neighbour3 = 0;
                    }                   
                    try {
                        neighbour4 = oldGen[xCoord][yCoord+1];
                    }
                    catch (ArrayIndexOutOfBoundsException e) {
                        neighbour4 = 0;
                    }               
                    try {
                        neighbour5 = oldGen[xCoord+1][yCoord+1];
                    }
                    catch (ArrayIndexOutOfBoundsException e) {
                        neighbour5 = 0;
                    }
                    try {
                        neighbour6 = oldGen[xCoord+1][yCoord];
                    }
                    catch (ArrayIndexOutOfBoundsException e) {
                        neighbour6 = 0;
                    }
                    try {
                        neighbour7 = oldGen[xCoord+1][yCoord-1];
                    }
                    catch (ArrayIndexOutOfBoundsException e) {
                        neighbour7 = 0;
                    }
                    try {
                        neighbour8 = oldGen[xCoord][yCoord-1];
                    }
                    catch (ArrayIndexOutOfBoundsException e) 
                    {
                        neighbour8 = 0;
                    } 

                    neighbours = neighbour1 + neighbour2 + neighbour3 + neighbour4 + neighbour5 + neighbour6 + neighbour7 + neighbour8;           

                    if (oldGen[xCoord][yCoord] == 1 & (neighbours == 2 | neighbours == 3)) 
                    {
                        newGen[xCoord][yCoord] = 1;
                    }
                    else if (oldGen[xCoord][yCoord] == 0 & neighbours == 3) 
                    {
                        newGen[xCoord][yCoord] = 1;
                    }
                    else 
                    {
                        newGen[xCoord][yCoord] = 0;
                    }
                }
            }
            for (int xCoord=0; xCoord < num; xCoord++) {
                {
                    for (int yCoord=0; yCoord < num; yCoord++) {
                        {
                            oldGen[xCoord][yCoord] = newGen[xCoord][yCoord];
                        }
                    }

                    repaint();    
                }}

        }}
    public static void main(String[] args) {

        printf("Enter a value to set the size of the grid: ");
        GameOfLife canvas = new GameOfLife();
        JFrame frame = new JFrame();


        frame.setTitle("CONWAY'S GAME OF LIFE");
        frame.setSize(500, 500);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(canvas);
        frame.setVisible(true);
        canvas.Generations();
    }

}

Here is the modified class Neighbours. I am receiving the same output as before. All I am doing is simply counting the neighbours.

class Neighbours extends TimerTask { // cheking the status of the neighbouring cells
    public void run() //throws ArrayIndexOutOfBoundsException
    {

        int neighboursCount = 0;    

        for (int xCoord=0; xCoord < gridSize; xCoord++) {
            for (int yCoord=0; yCoord < gridSize; yCoord++) {

                neighboursCount++;           

                if (oldGen[xCoord][yCoord] == 1 & (neighboursCount == 2 | neighboursCount == 3)) 
                {
                    newGen[xCoord][yCoord] = 1;
                }
                else if (oldGen[xCoord][yCoord] == 0 & neighboursCount == 3) 
                {
                    newGen[xCoord][yCoord] = 1;
                }
                else 
                {
                    newGen[xCoord][yCoord] = 0;
                }
            }
        }
        for (int xCoord=0; xCoord < gridSize; xCoord++) {
            {
                for (int yCoord=0; yCoord < gridSize; yCoord++) {
                    {
                        oldGen[xCoord][yCoord] = newGen[xCoord][yCoord];
                    }
                }

                repaint();    
            }}

    }}
\$\endgroup\$
  • \$\begingroup\$ Have you considered making your array bigger by two cells in each direction and filling the edges with zeroes? You still only operate on the actual cells from 1..num and only draw those cells. But that way you don't have to worry about array bounds. \$\endgroup\$ – JS1 Nov 26 '14 at 4:03
1
\$\begingroup\$

Here's an alternative. Suppose we have a class Point that has x- and y-coordinates.

Represent the offsets of neighbours using an array of Points. Something like this

private final Point[] offsets = new Point[] {
  new Point(-1, -1), new Point(0, -1), new Point(1, -1),
  new Point(-1,  0),                   new Point(1,  0),
  new Point(-1,  1), new Point(0,  1), new Point(1,  1)
};

Now add each offset to the given point and check if that's in the grid

private int getNeighbourCount(int x0, int y0, int[][] oldGen) {
  int neighbours = 0;
  for (Point offset : offsets) {
    int x = x0 + offset.x;
    int y = y0 + offset.y;
    if (x >= 0 && x < gridSize && y >= 0 && y < gridSize) {
      neighbours += oldGen[x][y];
    }
  }

  return neighbours;
}

Also, it seems that elements of oldGen and newGen are only assigned the values 0 and 1, in which case I would recommend changing from int to bool.

\$\endgroup\$
  • \$\begingroup\$ That is one way to do it. Thanks. But is there a way that I can do it just by modifying my class Neighbours? Since the one modification I tried to do and have shown above gave me a interesting output. \$\endgroup\$ – Emil Zahariev Nov 26 '14 at 1:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.