0

i have an up and running version of the game of life, but one thing i can not figure out is how to wrap around the Grid or Board, i am guessing is has to be something to do with the neighbor counts and the grid, i need a way to indicate that the array wraps.

The rules :

The universe of the Game of Life is an infinite two-dimensional orthogonal grid of square cells,

each of which is in one of two possible states, live or dead.

Every cell interacts with its eight neighbors, which are the cells that are directly horizontally,

vertically, or diagonally adjacent. At each step in time, the following transitions occur:

1.Any live cell with fewer than two live neighbours dies, as if caused by underpopulation.

2.Any live cell with more than three live neighbours dies, as if by overcrowding.

3.Any live cell with two or three live neighbours lives on to the next generation.

4.Any dead cell with exactly three live neighbours becomes a live cell.

The initial pattern constitutes the seed of the system. The first generation is created by applying the above rules simultaneously to every cell in the seed—births and deaths happen simultaneously.

Here's some of the code that will be relating to the grid/board; Called CellsGrid Cells;

  GameOfLife2(int nbRow, int nbCol) {

            super(" New GameOfLife");

            setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);



            // create the labels (2 more on each size) these wont be shown

            // but will be used in calculating the cells alive around

            Cells = new CellsGrid[nbRow+2][nbCol+2];

            for(int r = 0; r < nbRow+2; r++) {

                for(int c = 0; c < nbCol+2; c++) {

                    Cells[r][c] = new CellsGrid();

                }

            }

for(int r = 1; r < nbRow+1; r++) {

            for(int c = 1; c < nbCol+1; c++) {

                panel.add(Cells[r][c]);

                Cells[r][c].addNeighbour(Cells[r-1][c]);    // North

                Cells[r][c].addNeighbour(Cells[r+1][c]);    // South

                Cells[r][c].addNeighbour(Cells[r][c-1]);    // West

                Cells[r][c].addNeighbour(Cells[r][c+1]);    // East

                Cells[r][c].addNeighbour(Cells[r-1][c-1]);  // North West

                Cells[r][c].addNeighbour(Cells[r-1][c+1]);  // North East

                Cells[r][c].addNeighbour(Cells[r+1][c-1]);  // South West

                Cells[r][c].addNeighbour(Cells[r+1][c+1]);  // South East

            }


        }

 if(!gameRunning)

            return;

        ++generation;

        CellsIteration.setText("Generation: " + generation);

        for(int r = 0; r < Cells.length; r++) {

            for(int c = 0; c < Cells[r].length; c++) {

                Cells[r][c].checkState();

            }

        }

        for(int r = 0; r < Cells.length; r++) {

            for(int c = 0; c < Cells[r].length; c++) {

                Cells[r][c].updateState();

            }

        }

    }



void checkState() {



  // number alive around

    int NumNeighbours = 0; // number alive neighbours

    // see the state of my neighbour

    for(int i = 0; i < numNeighbours; i++)

        NumNeighbours += neighbour[i].state;

    // newState

    if(state == 1) {                // if alive

        if(NumNeighbours < 2)              // 1.Any live cell with fewer than two live neighbours dies

            newState = 0;

        if(NumNeighbours > 3)              // 2.Any live cell with more than three live neighbours dies

            newState = 0;

    }

    else {

        if(NumNeighbours == 3)            // 4.Any dead cell with exactly three live neighbours becomes a live cell

            newState = 1;

    }

}

full code:

package com.ggl.life;
import java.awt.*;

import java.awt.event.*;
import java.util.Random;

import javax.swing.*;


public class GameOfLife2 extends JFrame implements ActionListener {

    /**
     * 
     */
    public static Random random  = new Random();

    private static final long serialVersionUID = 1L;

    static final Color[] color = {Color.YELLOW, Color.BLACK};

    // size in pixel of every label

    static final int size = 15;

    static final Dimension dim = new Dimension(size, size);

    static final int GenDelay = 200;

    // the cells labels
    private CellsGrid[][] Cells;

    // timer that fires the next generation

    private Timer timer;

    // generation counter

    private int generation = 0;

    private JLabel CellsIteration = new JLabel("Generation: 0");

    // the 3 buttons

    private JButton clearBtn = new JButton("Clear"),

                    PauseBtn = new JButton("Pause"),

                    StartBtn = new JButton("Start");

    // the slider for the speed


    // state of the game (running or pause)

    private boolean gameRunning = false;

    // if the mouse is down or not

    private boolean mouseDown = false;



    GameOfLife2(int nbRow, int nbCol) {

        super(" New GameOfLife");

        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);



        // create the labels (2 more on each size) these wont be shown

        // but will be used in calculating the cells alive around

        Cells = new CellsGrid[nbRow+2][nbCol+2];

        for(int r = 0; r < nbRow+2; r++) {

            for(int c = 0; c < nbCol+2; c++) {

                Cells[r][c] = new CellsGrid();

            }


        }


        // panel in the center with the labels

        JPanel panel = new JPanel(new GridLayout(nbRow, nbCol, 1, 1));

        panel.setBackground(Color.BLACK);

        panel.setBorder(BorderFactory.createLineBorder(Color.BLACK));



        // add each label (not the one on the border) to the panel and add to each of them its neighbours

        for(int r = 1; r < nbRow+1; r++) {

            for(int c = 1; c < nbCol+1; c++) {

                panel.add(Cells[r][c]);

                Cells[r][c].addNeighbour(Cells[r-1][c]);
                //Cells[r][c].addNeighbour(getCellSafe(r-1, c)); // North

                Cells[r][c].addNeighbour(Cells[r+1][c]);    // South
              //Cells[r][c].addNeighbour(getCellSafe(r+1, c));

                Cells[r][c].addNeighbour(Cells[r][c-1]);    // West
              //Cells[r][c].addNeighbour(getCellSafe(r, c-1));

                Cells[r][c].addNeighbour(Cells[r][c+1]);    // East
              //Cells[r][c].addNeighbour(getCellSafe(r, c+1));

                Cells[r][c].addNeighbour(Cells[r-1][c-1]);  // North West
              //Cells[r][c].addNeighbour(getCellSafe(r-1, c-1));

                Cells[r][c].addNeighbour(Cells[r-1][c+1]);  // North East
              //Cells[r][c].addNeighbour(getCellSafe(r-1, c+1));

                Cells[r][c].addNeighbour(Cells[r+1][c-1]);  // South West
              //Cells[r][c].addNeighbour(getCellSafe(r+1, c-1));

               Cells[r][c].addNeighbour(Cells[r+1][c+1]);  // South East
              //Cells[r][c].addNeighbour(getCellSafe(r+1, +c));

            }


        }



        // now the panel can be added

        add(panel, BorderLayout.CENTER);



        // the bottom panel with the buttons the generation label and the slider

        // this panel is formed grid panels

        panel = new JPanel(new GridLayout(1,3));

       // another panel for the 3 buttons

        JPanel buttonPanel = new JPanel(new GridLayout(1,3));

        clearBtn.addActionListener(this);

        buttonPanel.add(clearBtn);

        PauseBtn.addActionListener(this);

        PauseBtn.setEnabled(false);           // game is pause the pause button is disabled

        buttonPanel.add(PauseBtn);

        StartBtn.addActionListener(this);

        buttonPanel.add(StartBtn);

        // add the 3 buttons to the panel

        panel.add(buttonPanel);

        // the generation label

        CellsIteration.setHorizontalAlignment(SwingConstants.CENTER);

        panel.add(CellsIteration);


        // in the JFrame

        add(panel, BorderLayout.NORTH);

        // put the frame on

        setLocation(20, 20);

        pack(); // adjust to the window size
        setVisible(true);

        // start the thread that run the cycles of life

        timer = new Timer(GenDelay , this);

    }

    private CellsGrid getCellSafe(int r0, int c0) {
        int r = r0  % Cells.length; // Cells.length is effectively nbRow
        if (r < 0) r += Cells.length; // deal with how % works for negatives
        int c = c0  % Cells[0].length; // Cells[0].length is effectively nbCol
        if (c < 0) c += Cells[0].length; // deal with how % works for negatives
        return Cells[r][c];
   }

//end of game of life

    // called by the Timer and the JButtons

    public synchronized void actionPerformed(ActionEvent e) {

        // test the JButtons first

        Object o = e.getSource();

        // the clear button

        if(o == clearBtn) {

            timer.stop();                   // stop timer

            gameRunning = false;            // flag gamme not running

            PauseBtn.setEnabled(false);       // disable pause button

            StartBtn.setEnabled(true);           // enable go button

            // clear all cells

            for(int r = 1; r < Cells.length ; r++) {

                for(int c = 1; c < Cells[r].length ; c++) {

                    Cells[r][c].clear();

                }

            }

            // reset generation number and its label

            generation = 0;

            CellsIteration.setText("Generation: 0");

            return;

        }

        // the pause button

        if(o == PauseBtn) {

            timer.stop();                   // stop timer

            gameRunning = false;            // flag not running

            PauseBtn.setEnabled(false);       // disable myself

            StartBtn.setEnabled(true);           // enable go button

            return;

        }

        // the go button

        if(o == StartBtn) {

            PauseBtn.setEnabled(true);                // enable pause button

            StartBtn.setEnabled(false);                  // disable myself

            gameRunning = true;                     // flag game is running

            timer.setDelay(GenDelay);

            timer.start();

           return;

        }

        // not a JButton so it is the timer

        // set the delay for the next time

        timer.setDelay(GenDelay);

        // if the game is not running wait for next time

        if(!gameRunning)

            return;

        ++generation;

        CellsIteration.setText("Generation: " + generation);

        for(int r = 0; r < Cells.length; r++) {

            for(int c = 0; c < Cells[r].length; c++) {

                Cells[r][c].checkState();

            }

        }

        for(int r = 0; r < Cells.length; r++) {

            for(int c = 0; c < Cells[r].length; c++) {

                Cells[r][c].updateState();

            }

        }

    }
    //end of action


    // to start the whole thing as a Java application

    public static void main(String[] arg) {

      SwingUtilities.invokeLater(new Runnable() {

            public void run() {

                new GameOfLife2(50, 50);

            }

        });

    }



    // A class that extends JLabel but also check for the neigbour

    // when asked to do so

    class CellsGrid extends JLabel implements MouseListener {

        /**
         * 
         */
        private static final long serialVersionUID = 1L;

        private int state, newState;

        private int numNeighbours;

        private CellsGrid[] neighbour = new CellsGrid[8]; // array of total neighbours with possibility of 8




        CellsGrid() {

            state = newState = 0;           // Dead

            setOpaque(true);                // so color will be showed

            setBackground(color[0]);        //set colour of dead cell

            addMouseListener(this);         // to select new LIVE cells

            this.setPreferredSize(dim);     //set size a new cells

        }

        // to add a neighbour

        void addNeighbour(CellsGrid n) {

            neighbour[numNeighbours++] = n;

        }

        // to see if I should live or not

        void checkState() {

            // number alive around

            int NumNeighbours = 0; // number alive neighbours

            // see the state of my neighbour

            for(int i = 0; i < numNeighbours; i++)

                NumNeighbours += neighbour[i].state;

            // newState

            if(state == 1) {                // if alive

                if(NumNeighbours < 2)              // 1.Any live cell with fewer than two live neighbours dies

                    newState = 0;

                if(NumNeighbours > 3)              // 2.Any live cell with more than three live neighbours dies

                    newState = 0;

            }

            else {

                if(NumNeighbours == 3)            // 4.Any dead cell with exactly three live neighbours becomes a live cell

                    newState = 1;

            }

        }

        // after the run switch the state to new state

        void updateState() {

            if(state != newState) {     // do the test to avoid re-setting same color for nothing  

                state = newState;

                setBackground(color[state]);

            }

        }



        // called when the game is reset/clear

        void clear() {

            if(state == 1 || newState == 1) {

               state = newState = 0;

                setBackground(color[state]);

            }

        }

        @Override

        public void mouseClicked(MouseEvent arg0) {

        }

        // if the mouse enter a cell and it is down we make the cell alive

        public void mouseEntered(MouseEvent arg0) {

            if(mouseDown) {

                state = newState = 1;

                setBackground(color[1]);               

            }

        }

        @Override

        public void mouseExited(MouseEvent arg0) {

        }

        // if the mouse is pressed on a cell you register the fact that it is down

        // and make that cell alive

        public void mousePressed(MouseEvent arg0) {

            mouseDown = true;

            state = newState = 1;

            setBackground(color[1]);

        }

        // turn off the fact that the cell is down

        public void mouseReleased(MouseEvent arg0) {

            mouseDown = false;

        }      

    }

}
Bart123
  • 45
  • 2
  • 11

1 Answers1

0

As UnholySheep you need to learn % operator. % is the way to calculate reminder of division aka modulo. See https://en.wikipedia.org/wiki/Modulo_operation

The simplest way to apply it here is something like this. First introduce method getCellSafe

 private CellsGrid getCellSafe(int r0, int c0) {
      int r = r0  % Cells.length; // Cells.length is effectively nbRow
      if (r < 0) r += Cells.length; // deal with how % works for negatives
      int c = c0  % Cells[0].length; // Cells[0].length is effectively nbCol
      if (c < 0) c += Cells[0].length; // deal with how % works for negatives
      return Cells[r][c];
 }

and then use this method instead direct access such as

     Cells[r][c].addNeighbour(getCellSafe(r-1, c);    // North

and also get rid of your + 2 in your nbCol and nbRow


Update: Fix for L-shape

The bug for "L-shape" is in your copy of line for "South East" where you converted c+1 into +c

          Cells[r][c].addNeighbour(Cells[r+1][c+1]);  // South East
          //Cells[r][c].addNeighbour(getCellSafe(r+1, +c));


Bigger improvements

Generally your code is pretty bad. There are a lot of logic duplications (see DRY principle) and other bad code such as huge ActionListener. Here is my attempt to clean it up a bit:

public class GameOfLife2 extends JFrame
{
    /**
     *
     */
    public static Random random = new Random();

    static final Color[] color = {Color.YELLOW, Color.BLACK};

    // size in pixel of every label
    static final int cellSize = 15;

    static final Dimension cellDim = new Dimension(cellSize, cellSize);

    static final int GenDelay = 200;

    // the cells labels
    private CellsGrid[][] Cells;

    // that fires the next generation

    private Timer timer;

    // generation counter

    private int generation = 0;

    private JLabel CellsIteration = new JLabel("Generation: 0");

    // the 3 buttons

    private JButton clearBtn = new JButton("Clear");

    private JButton PauseBtn = new JButton("Pause");

    private JButton StartBtn = new JButton("Start");

    private JButton StepBtn = new JButton("Step");

    // the slider for the speed


    // state of the game (running or pause)

    private boolean gameRunning = false;


    GameOfLife2(int nbRow, int nbCol)
    {

        super("New GameOfLife");

        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        Cells = new CellsGrid[nbRow][nbCol];

        for (int r = 0; r < nbRow; r++)
        {
            for (int c = 0; c < nbCol; c++)
            {
                Cells[r][c] = new CellsGrid();
            }
        }


        // panel in the center with the labels

        JPanel panel = new JPanel(new GridLayout(nbRow, nbCol, 1, 1));
        panel.setBackground(Color.BLACK);
        panel.setBorder(BorderFactory.createLineBorder(Color.BLACK));


        // add each label (not the one on the border) to the panel and add to each of them its neighbours

        for (int r = 0; r < nbRow; r++)
        {
            for (int c = 0; c < nbCol; c++)
            {
                CellsGrid curCell = Cells[r][c];
                panel.add(curCell);

                for (int dr = -1; dr <= 1; dr++)
                {
                    for (int dc = -1; dc <= 1; dc++)
                    {
                        CellsGrid neighbor = getCellSafe(r + dr, c + dc);
                        if (neighbor != curCell)
                            curCell.addNeighbour(neighbor);
                    }
                }
            }
        }


        // now the panel can be added

        add(panel, BorderLayout.CENTER);

        // the bottom panel with the buttons the generation label and the slider

        Box headerPanel = Box.createHorizontalBox();
        Box buttonPanel = Box.createHorizontalBox();

        // old pre-Java 8 syntax
        //clearBtn.addActionListener(new ActionListener()
        //{
        //  @Override
        //  public void actionPerformed(ActionEvent e)
        //  {
        //      clearGame();
        //  }
        //});
        clearBtn.addActionListener((e) -> clearGame()); // holy Java 8 lambda syntax
        buttonPanel.add(clearBtn);

        PauseBtn.addActionListener((e) -> stopGame());
        buttonPanel.add(PauseBtn);

        StartBtn.addActionListener((e) -> startGame());
        buttonPanel.add(StartBtn);

        StepBtn.addActionListener((e) -> stepToNextGeneration());
        buttonPanel.add(StepBtn);

        // the generation label
        CellsIteration.setHorizontalAlignment(SwingConstants.CENTER);

        headerPanel.add(Box.createHorizontalStrut(10));
        headerPanel.add(buttonPanel);
        headerPanel.add(Box.createHorizontalStrut(10));
        headerPanel.add(Box.createHorizontalGlue());
        headerPanel.add(Box.createHorizontalStrut(10));
        headerPanel.add(CellsIteration);
        headerPanel.add(Box.createHorizontalGlue()); // if you want "generation" label closer to center
        headerPanel.add(Box.createHorizontalStrut(10));


        // in the JFrame
        add(headerPanel, BorderLayout.NORTH);

        // put the frame on
        setLocation(20, 20);

        gameRunning = false;
        generation = 0;
        updateGenerationTitle();
        updateButtonsState();


        pack(); // adjust to the window size
        setMinimumSize(new Dimension(600, 500));
        setVisible(true);

        // start the thread that run the cycles of life
        timer = new Timer(GenDelay, (e) -> onTimerStep());
    }

    private CellsGrid getCellSafe(int r0, int c0)
    {
        int r = r0 % Cells.length; // Cells.length is effectively nbRow
        if (r < 0) r += Cells.length; // deal with how % works for negatives
        int c = c0 % Cells[0].length; // Cells[0].length is effectively nbCol
        if (c < 0) c += Cells[0].length; // deal with how % works for negatives
        return Cells[r][c];
    }


    private void updateButtonsState()
    {
        PauseBtn.setEnabled(gameRunning);
        StartBtn.setEnabled(!gameRunning);
        StepBtn.setEnabled(!gameRunning);
    }

    private void updateGenerationTitle()
    {
        CellsIteration.setText("Generation: " + generation);
    }

    private void startGame()
    {
        gameRunning = true;                     // flag game is running
        updateButtonsState();
        timer.setDelay(GenDelay);
        timer.start();
    }

    private void stopGame()
    {
        timer.stop();                   // stop timer
        gameRunning = false;            // flag not running
        updateButtonsState();
    }

    private void clearGame()
    {
        stopGame();
        // clear all cells

        for (int r = 0; r < Cells.length; r++)
        {
            for (int c = 0; c < Cells[r].length; c++)
            {
                Cells[r][c].clear();
            }
        }

        // reset generation number and its label

        generation = 0;
        updateGenerationTitle();
    }

    private void stepToNextGeneration()
    {
        ++generation;
        updateGenerationTitle();

        for (int r = 0; r < Cells.length; r++)
        {
            for (int c = 0; c < Cells[r].length; c++)
            {
                Cells[r][c].checkState();
            }
        }

        for (int r = 0; r < Cells.length; r++)
        {
            for (int c = 0; c < Cells[r].length; c++)
            {
                Cells[r][c].updateState();
            }
        }
    }

    private void onTimerStep()
    {
        if (gameRunning)
            stepToNextGeneration();
    }

    // to start the whole thing as a Java application
    public static void main(String[] arg)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new GameOfLife2(50, 50);
            }
        });
    }


    // A class that extends JLabel but also check for the neigbour

    // when asked to do so

    static class CellsGrid extends JLabel implements MouseListener
    {
        private boolean alive = false;
        private boolean newAlive = false;

        private final ArrayList<CellsGrid> neighbours = new ArrayList<>(8); // array of total neighbours with possibility of 8


        CellsGrid()
        {
            setOpaque(true);                // so color will be showed
            addMouseListener(this);         // to select new LIVE cells
            setPreferredSize(cellDim);     //set size a new cells

            updateColor();
        }

        // to add a neighbour

        void addNeighbour(CellsGrid n)
        {
            neighbours.add(n);
        }

        // to see if I should live or not

        void checkState()
        {
            // number alive around
            int NumNeighbours = 0; // number alive neighbours

            // see the state of my neighbour
            for (CellsGrid neighbour : neighbours)
                NumNeighbours += neighbour.alive ? 1 : 0;

            // 1. Any live cell with fewer than two live neighbours dies
            // 2. Any live cell with two or three live neighbours lives on to the next generation.
            // 3. Any live cell with more than three live neighbours dies
            // 4. Any dead cell with exactly three live neighbours becomes a live cell
            if (alive)
            {
                newAlive = (NumNeighbours == 2) || (NumNeighbours == 3);
            }
            else
            {
                newAlive = (NumNeighbours == 3);
            }
        }

        // after the run switch the state to new state
        void updateState()
        {
            alive = newAlive;
            updateColor();
        }


        // called when the game is reset/clear
        void clear()
        {
            alive = newAlive = false;
            updateColor();
        }

        private void updateColor()
        {
            setBackground(color[alive ? 1 : 0]);
        }


        @Override
        public void mouseClicked(MouseEvent arg0)
        {
        }

        // if the mouse enter a cell and it is down we make the cell alive
        @Override
        public void mouseEntered(MouseEvent e)
        {
            boolean mouseDown = (e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) != 0;
            if (mouseDown)
            {
                alive = newAlive = true;
                updateColor();
            }
        }

        @Override
        public void mouseExited(MouseEvent e)
        {
        }

        @Override
        public void mousePressed(MouseEvent arg0)
        {
            //              state = newState = true;
            alive = newAlive = !newAlive; //invert state is more useful, so you can clear something
            updateColor();
        }

        @Override
        public void mouseReleased(MouseEvent arg0)
        {
        }
    }
}

This code seems to work including Glider flying diagonally with wrapping around the field.

Some notes:

  • I split your single ActionListener into independent ones for each thing and used Java 8 syntax to make them short and nice at registration
  • I introduced a few updateXyz and stepToNextGeneration methods to drastically reduce code duplication
  • MouseEvent already provides information whether button is down or not.
  • I added "Step" button that was needed for me to debug your code.
  • There are other layouts besides GridLayout
  • There is not much sense in defining serialVersionUID in UI (JComponent) classes as they are effectively not serializable (although they do implement Serializable interface). See also Swing components and serialization


Update with more answers for comments

If I wanted to have some pre-made initial state, I'd made a simple class (more like structute) Point with just two fields row and column and had a List or array of them, then did clear and iterated over the collection to make alive those cells that are in the list. If I wanted to go even further, I'd probably added one more wrapping class (structure) SavedGame or something to save width and height and a collection of Points; and made whole UI dynamic instead of building it once in constructor; and then added ability to save/read such configuration from some file

As for random, there is a java.util.Random class with useful int nextInt(int n) method. So I'd ask the user how many random cells should be made alive and then run a loop till that number and using Random generated new alive cells by generating row and column. Note that if you want to fill significant portion of cells, you might need to check if the next randomly cell you selected is already alive and if yes, "roll the dice" one more time. If you want to fill even more, you'll need to change algorithm to more complicated or filling 90% of cells might take forever. One idea might be to generated single cell index in range (0; row * height - count of already alive cells) rather than independent row and column and then just go through cells starting from top-left to bottom-right counting only dead cells and making alive corresponding cell. In such way you make sure that each new alive cell takes the same amount of time to generate.

Community
  • 1
  • 1
SergGr
  • 23,570
  • 2
  • 30
  • 51
  • dealing with negatives doesnt really make the grid wrap around it?, – Bart123 Mar 16 '17 at 17:58
  • also, for some reason removing the +2 breaks the code, and i dont know why, i managed to do it before now i cant figure out what it was – Bart123 Mar 16 '17 at 17:59
  • @Bart123, have you really replaced all access to `Cells` except for `Cells[r][c]` where both `r` and `c` comes from loop with my `getCellSafe`? What is stack strace for exception? What if you replace that access with `getCellSafe`? – SergGr Mar 16 '17 at 18:03
  • As for "deal with how % works for negatives" comment, it is unfortunate that `-1 % 5` in Java is still `-1` rather than `4` and this is what those `if` should fix – SergGr Mar 16 '17 at 18:04
  • when replaced all, the cells form shapes that all turn into "L" shapes, – Bart123 Mar 16 '17 at 18:17
  • the expection looks like this : Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 50 at com.ggl.life.GameOfLife2.(GameOfLife2.java:113) at com.ggl.life.GameOfLife2$1.run(GameOfLife2.java:362) – Bart123 Mar 16 '17 at 18:17
  • So what's the line 113 of GameOfLife2? Also when you removed `+ 2` from the first for, don't you forget to remove `+1` from the second fors. They should be `0 to nbRow` and `0 to nbCol`. As for "all turn into "L" shapes" I don't understand what you mean at all – SergGr Mar 16 '17 at 18:19
  • is there anyway i can pm you to send you the full project, so you could see for urself what i mean, its hard to explain – Bart123 Mar 16 '17 at 18:25
  • @Bart123, If we spam a bit more in comments, there would be a link to start a chat. As for sending source, you can put it anywhere with public access. I sometimes use http://dropmefiles.com/ (you don't have to fill in e-mail to get URL for download) – SergGr Mar 16 '17 at 18:31
  • i cant chat coz of my reputation? xD lol who though of that, im gonna edit the code so that the full code is there – Bart123 Mar 16 '17 at 19:11
  • @Bart123, You've made a copy-paste mistake. See my update – SergGr Mar 16 '17 at 20:44
  • thank you :) i will check it out in the morning, can u tell me what the ? symbol means, because i didnt see it being an operator ive seen – Bart123 Mar 17 '17 at 00:10
  • `(condition) ? valueForTrue : valueForFalse` is a [ternary operator](https://en.wikipedia.org/wiki/%3F:) - a short version for simple `if/else` – SergGr Mar 17 '17 at 00:16
  • that is awesome ;d i learnt a lot with your help ;D if i could ask you to explain one more thing for me, if i wanted to populate the starting screen with cells, using something like Cells[12][3] = alive/1, or make them come to life, what would the structure look like? as im just getting familiar with it and i wanted the starting screen to make a random arrangement of alive and dead cells – Bart123 Mar 17 '17 at 14:20
  • @Bart123, those answers go far beyond simple comment but I tried to describe some ideas in update to my answer. – SergGr Mar 17 '17 at 14:55