A Game of Life application, with mouse clicks

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
8
down vote

favorite
1












I have a Game of Life program that has a grid array which is populated by Cell objects. If there's a cell in a grid square, that grid square is green. One can add the cells manually by clicking on the grid squares and turning them green.



When a Start Iterations button is pressed a startIterations() method starts, which makes use of AnimationTimer. It all runs in the single thread, until there are no alive cells left or until 10 seconds pass.



However, I still can interfer with that process by clicking on free squares and turning them green. Also I have a Stop Iterations button that invokes AnimationTimer's stop() method when pressed; I can access that button while the simulations are being run at it works OK. How is that possible, if there's only one thread?



Even though it works OK, I have a feeling it's wrong to have everything inside a single thread. What is the better approach? Put animation in a separate second thread?



enter image description here



Main class:



public class Main extends Application {
private static int gameWidth = 800;
private static int gameHeight = 600;

private static int gridSize = 20;
private static Cell grid = new Cell[gridSize][gridSize];

private static Scene scene;
private static Displayer gameDisplayer;

static SimpleIntegerProperty simulationCount = new SimpleIntegerProperty(0);
static int aliveCellsCount = 0;

private static boolean iterationsStatus = false;
@Override
public void start(Stage primaryStage) throws Exception
primaryStage.setTitle("Advanced Game of Life");

createGrid();

gameDisplayer = new Displayer(gameWidth, gameHeight, grid);

scene = gameDisplayer.getGameScene();
primaryStage.setScene(scene);
primaryStage.show();



public static void main(String args)
launch(args);



startIterations() method:



public static void startIterations() 
System.out.println("Starting iterations");
simulationCount.set(0);

final long startNanoTime = System.nanoTime();

new AnimationTimer()
private long lastUpdateTime = 0;

public void handle(long currentNanoTime) currentTime > 10
.start();

System.out.println("Finished iterations");



updateGrid() method:



public static int updateGrid() 
System.out.println("Updating grid");

int livingCount;

for (int i = 0; i < gridSize; i++)
for (int j = 0; j < gridSize; j++)
livingCount = 0;

livingCount += checkGrid(i - 1, j);
livingCount += checkGrid(i, j - 1);
livingCount += checkGrid(i + 1, j);
livingCount += checkGrid(i, j + 1);
livingCount += checkGrid(i - 1, j - 1);
livingCount += checkGrid(i + 1, j + 1);
livingCount += checkGrid(i - 1, j + 1);
livingCount += checkGrid(i + 1, j - 1);

if (livingCount == 3)
grid[i][j].setNextStatus(true);
else if (livingCount == 2 && grid[i][j].getStatus())
grid[i][j].setNextStatus(true);
else
grid[i][j].setNextStatus(false);


System.out.print("livingCount for (" + i + ", " + j + "): " + livingCount);
System.out.println(" => " + grid[i][j].getNextStatus());



int resultLivingCount = 0;

for (int i = 0; i < gridSize; i++)
for (int j = 0; j < gridSize; j++)
grid[i][j].setStatus(grid[i][j].getNextStatus());

resultLivingCount += grid[i][j].getStatus() ? 1 : 0;
// System.out.println("grid[" + i + "]["+j + "] is " + grid[i][j].getStatus());



return resultLivingCount;



handle() method inside Displayer class, that handles buttons clicks:



public void handle(ActionEvent event) 
if (event.getSource()==createCellButton)
Main.createCell();

else if (event.getSource() == deleteCellsButton)
Main.deleteCells();
cellsCountLabel.setText("Cells Count: " + (cellId + 1));
System.out.println("Cells deleted");

else if (event.getSource()==randomGridButton)
System.out.println("Calling random grid");

Main.generateRandomGrid();

else if (event.getSource() == updateGridButton)
Main.updateGrid();

else if (event.getSource() == startIterationsButton)
Main.setIterationsStatus(true);
Main.startIterations();

else if(event.getSource()==stopIterationsButton)
Main.setIterationsStatus(false);

else
System.out.println("Unknown button");








share|improve this question



























    up vote
    8
    down vote

    favorite
    1












    I have a Game of Life program that has a grid array which is populated by Cell objects. If there's a cell in a grid square, that grid square is green. One can add the cells manually by clicking on the grid squares and turning them green.



    When a Start Iterations button is pressed a startIterations() method starts, which makes use of AnimationTimer. It all runs in the single thread, until there are no alive cells left or until 10 seconds pass.



    However, I still can interfer with that process by clicking on free squares and turning them green. Also I have a Stop Iterations button that invokes AnimationTimer's stop() method when pressed; I can access that button while the simulations are being run at it works OK. How is that possible, if there's only one thread?



    Even though it works OK, I have a feeling it's wrong to have everything inside a single thread. What is the better approach? Put animation in a separate second thread?



    enter image description here



    Main class:



    public class Main extends Application {
    private static int gameWidth = 800;
    private static int gameHeight = 600;

    private static int gridSize = 20;
    private static Cell grid = new Cell[gridSize][gridSize];

    private static Scene scene;
    private static Displayer gameDisplayer;

    static SimpleIntegerProperty simulationCount = new SimpleIntegerProperty(0);
    static int aliveCellsCount = 0;

    private static boolean iterationsStatus = false;
    @Override
    public void start(Stage primaryStage) throws Exception
    primaryStage.setTitle("Advanced Game of Life");

    createGrid();

    gameDisplayer = new Displayer(gameWidth, gameHeight, grid);

    scene = gameDisplayer.getGameScene();
    primaryStage.setScene(scene);
    primaryStage.show();



    public static void main(String args)
    launch(args);



    startIterations() method:



    public static void startIterations() 
    System.out.println("Starting iterations");
    simulationCount.set(0);

    final long startNanoTime = System.nanoTime();

    new AnimationTimer()
    private long lastUpdateTime = 0;

    public void handle(long currentNanoTime) currentTime > 10
    .start();

    System.out.println("Finished iterations");



    updateGrid() method:



    public static int updateGrid() 
    System.out.println("Updating grid");

    int livingCount;

    for (int i = 0; i < gridSize; i++)
    for (int j = 0; j < gridSize; j++)
    livingCount = 0;

    livingCount += checkGrid(i - 1, j);
    livingCount += checkGrid(i, j - 1);
    livingCount += checkGrid(i + 1, j);
    livingCount += checkGrid(i, j + 1);
    livingCount += checkGrid(i - 1, j - 1);
    livingCount += checkGrid(i + 1, j + 1);
    livingCount += checkGrid(i - 1, j + 1);
    livingCount += checkGrid(i + 1, j - 1);

    if (livingCount == 3)
    grid[i][j].setNextStatus(true);
    else if (livingCount == 2 && grid[i][j].getStatus())
    grid[i][j].setNextStatus(true);
    else
    grid[i][j].setNextStatus(false);


    System.out.print("livingCount for (" + i + ", " + j + "): " + livingCount);
    System.out.println(" => " + grid[i][j].getNextStatus());



    int resultLivingCount = 0;

    for (int i = 0; i < gridSize; i++)
    for (int j = 0; j < gridSize; j++)
    grid[i][j].setStatus(grid[i][j].getNextStatus());

    resultLivingCount += grid[i][j].getStatus() ? 1 : 0;
    // System.out.println("grid[" + i + "]["+j + "] is " + grid[i][j].getStatus());



    return resultLivingCount;



    handle() method inside Displayer class, that handles buttons clicks:



    public void handle(ActionEvent event) 
    if (event.getSource()==createCellButton)
    Main.createCell();

    else if (event.getSource() == deleteCellsButton)
    Main.deleteCells();
    cellsCountLabel.setText("Cells Count: " + (cellId + 1));
    System.out.println("Cells deleted");

    else if (event.getSource()==randomGridButton)
    System.out.println("Calling random grid");

    Main.generateRandomGrid();

    else if (event.getSource() == updateGridButton)
    Main.updateGrid();

    else if (event.getSource() == startIterationsButton)
    Main.setIterationsStatus(true);
    Main.startIterations();

    else if(event.getSource()==stopIterationsButton)
    Main.setIterationsStatus(false);

    else
    System.out.println("Unknown button");








    share|improve this question























      up vote
      8
      down vote

      favorite
      1









      up vote
      8
      down vote

      favorite
      1






      1





      I have a Game of Life program that has a grid array which is populated by Cell objects. If there's a cell in a grid square, that grid square is green. One can add the cells manually by clicking on the grid squares and turning them green.



      When a Start Iterations button is pressed a startIterations() method starts, which makes use of AnimationTimer. It all runs in the single thread, until there are no alive cells left or until 10 seconds pass.



      However, I still can interfer with that process by clicking on free squares and turning them green. Also I have a Stop Iterations button that invokes AnimationTimer's stop() method when pressed; I can access that button while the simulations are being run at it works OK. How is that possible, if there's only one thread?



      Even though it works OK, I have a feeling it's wrong to have everything inside a single thread. What is the better approach? Put animation in a separate second thread?



      enter image description here



      Main class:



      public class Main extends Application {
      private static int gameWidth = 800;
      private static int gameHeight = 600;

      private static int gridSize = 20;
      private static Cell grid = new Cell[gridSize][gridSize];

      private static Scene scene;
      private static Displayer gameDisplayer;

      static SimpleIntegerProperty simulationCount = new SimpleIntegerProperty(0);
      static int aliveCellsCount = 0;

      private static boolean iterationsStatus = false;
      @Override
      public void start(Stage primaryStage) throws Exception
      primaryStage.setTitle("Advanced Game of Life");

      createGrid();

      gameDisplayer = new Displayer(gameWidth, gameHeight, grid);

      scene = gameDisplayer.getGameScene();
      primaryStage.setScene(scene);
      primaryStage.show();



      public static void main(String args)
      launch(args);



      startIterations() method:



      public static void startIterations() 
      System.out.println("Starting iterations");
      simulationCount.set(0);

      final long startNanoTime = System.nanoTime();

      new AnimationTimer()
      private long lastUpdateTime = 0;

      public void handle(long currentNanoTime) currentTime > 10
      .start();

      System.out.println("Finished iterations");



      updateGrid() method:



      public static int updateGrid() 
      System.out.println("Updating grid");

      int livingCount;

      for (int i = 0; i < gridSize; i++)
      for (int j = 0; j < gridSize; j++)
      livingCount = 0;

      livingCount += checkGrid(i - 1, j);
      livingCount += checkGrid(i, j - 1);
      livingCount += checkGrid(i + 1, j);
      livingCount += checkGrid(i, j + 1);
      livingCount += checkGrid(i - 1, j - 1);
      livingCount += checkGrid(i + 1, j + 1);
      livingCount += checkGrid(i - 1, j + 1);
      livingCount += checkGrid(i + 1, j - 1);

      if (livingCount == 3)
      grid[i][j].setNextStatus(true);
      else if (livingCount == 2 && grid[i][j].getStatus())
      grid[i][j].setNextStatus(true);
      else
      grid[i][j].setNextStatus(false);


      System.out.print("livingCount for (" + i + ", " + j + "): " + livingCount);
      System.out.println(" => " + grid[i][j].getNextStatus());



      int resultLivingCount = 0;

      for (int i = 0; i < gridSize; i++)
      for (int j = 0; j < gridSize; j++)
      grid[i][j].setStatus(grid[i][j].getNextStatus());

      resultLivingCount += grid[i][j].getStatus() ? 1 : 0;
      // System.out.println("grid[" + i + "]["+j + "] is " + grid[i][j].getStatus());



      return resultLivingCount;



      handle() method inside Displayer class, that handles buttons clicks:



      public void handle(ActionEvent event) 
      if (event.getSource()==createCellButton)
      Main.createCell();

      else if (event.getSource() == deleteCellsButton)
      Main.deleteCells();
      cellsCountLabel.setText("Cells Count: " + (cellId + 1));
      System.out.println("Cells deleted");

      else if (event.getSource()==randomGridButton)
      System.out.println("Calling random grid");

      Main.generateRandomGrid();

      else if (event.getSource() == updateGridButton)
      Main.updateGrid();

      else if (event.getSource() == startIterationsButton)
      Main.setIterationsStatus(true);
      Main.startIterations();

      else if(event.getSource()==stopIterationsButton)
      Main.setIterationsStatus(false);

      else
      System.out.println("Unknown button");








      share|improve this question













      I have a Game of Life program that has a grid array which is populated by Cell objects. If there's a cell in a grid square, that grid square is green. One can add the cells manually by clicking on the grid squares and turning them green.



      When a Start Iterations button is pressed a startIterations() method starts, which makes use of AnimationTimer. It all runs in the single thread, until there are no alive cells left or until 10 seconds pass.



      However, I still can interfer with that process by clicking on free squares and turning them green. Also I have a Stop Iterations button that invokes AnimationTimer's stop() method when pressed; I can access that button while the simulations are being run at it works OK. How is that possible, if there's only one thread?



      Even though it works OK, I have a feeling it's wrong to have everything inside a single thread. What is the better approach? Put animation in a separate second thread?



      enter image description here



      Main class:



      public class Main extends Application {
      private static int gameWidth = 800;
      private static int gameHeight = 600;

      private static int gridSize = 20;
      private static Cell grid = new Cell[gridSize][gridSize];

      private static Scene scene;
      private static Displayer gameDisplayer;

      static SimpleIntegerProperty simulationCount = new SimpleIntegerProperty(0);
      static int aliveCellsCount = 0;

      private static boolean iterationsStatus = false;
      @Override
      public void start(Stage primaryStage) throws Exception
      primaryStage.setTitle("Advanced Game of Life");

      createGrid();

      gameDisplayer = new Displayer(gameWidth, gameHeight, grid);

      scene = gameDisplayer.getGameScene();
      primaryStage.setScene(scene);
      primaryStage.show();



      public static void main(String args)
      launch(args);



      startIterations() method:



      public static void startIterations() 
      System.out.println("Starting iterations");
      simulationCount.set(0);

      final long startNanoTime = System.nanoTime();

      new AnimationTimer()
      private long lastUpdateTime = 0;

      public void handle(long currentNanoTime) currentTime > 10
      .start();

      System.out.println("Finished iterations");



      updateGrid() method:



      public static int updateGrid() 
      System.out.println("Updating grid");

      int livingCount;

      for (int i = 0; i < gridSize; i++)
      for (int j = 0; j < gridSize; j++)
      livingCount = 0;

      livingCount += checkGrid(i - 1, j);
      livingCount += checkGrid(i, j - 1);
      livingCount += checkGrid(i + 1, j);
      livingCount += checkGrid(i, j + 1);
      livingCount += checkGrid(i - 1, j - 1);
      livingCount += checkGrid(i + 1, j + 1);
      livingCount += checkGrid(i - 1, j + 1);
      livingCount += checkGrid(i + 1, j - 1);

      if (livingCount == 3)
      grid[i][j].setNextStatus(true);
      else if (livingCount == 2 && grid[i][j].getStatus())
      grid[i][j].setNextStatus(true);
      else
      grid[i][j].setNextStatus(false);


      System.out.print("livingCount for (" + i + ", " + j + "): " + livingCount);
      System.out.println(" => " + grid[i][j].getNextStatus());



      int resultLivingCount = 0;

      for (int i = 0; i < gridSize; i++)
      for (int j = 0; j < gridSize; j++)
      grid[i][j].setStatus(grid[i][j].getNextStatus());

      resultLivingCount += grid[i][j].getStatus() ? 1 : 0;
      // System.out.println("grid[" + i + "]["+j + "] is " + grid[i][j].getStatus());



      return resultLivingCount;



      handle() method inside Displayer class, that handles buttons clicks:



      public void handle(ActionEvent event) 
      if (event.getSource()==createCellButton)
      Main.createCell();

      else if (event.getSource() == deleteCellsButton)
      Main.deleteCells();
      cellsCountLabel.setText("Cells Count: " + (cellId + 1));
      System.out.println("Cells deleted");

      else if (event.getSource()==randomGridButton)
      System.out.println("Calling random grid");

      Main.generateRandomGrid();

      else if (event.getSource() == updateGridButton)
      Main.updateGrid();

      else if (event.getSource() == startIterationsButton)
      Main.setIterationsStatus(true);
      Main.startIterations();

      else if(event.getSource()==stopIterationsButton)
      Main.setIterationsStatus(false);

      else
      System.out.println("Unknown button");










      share|improve this question












      share|improve this question




      share|improve this question








      edited Feb 21 at 14:35









      200_success

      123k14143401




      123k14143401









      asked Jan 27 at 12:22









      woodStone

      763




      763




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          2
          down vote













          Normal case



          Applications with user-interfaces normally work with a single thread, commonly something like this:



          loop 
          handleEvents()
          updateWorld()
          renderWorld()



          It's a bit hard to tell since the code does not seem complete, but from your description it seems to be doing handleEvents()/renderWorld() in one thread (by Application itself) and updateWorld() in another (your AnimationTimer), that will give thread-conflicts.



          Two possible solutions (I recommend 1 in this case, 2 is useful when incoming events must be coming through its own thread):



          1. Don't start a separate thread, jack into the update thread of the Application instead, there most likely is one available to jack in to

          2. Create a queue of incoming events in handle() and process the queue in the updateWorld() thread.

          If you want multi-threading:



          Multithreading is easiest to achieve in the updateWorld() part. This can be done by splitting the work that needs to be done into multiple threads, waiting for all of them to finish their work and then exiting updateWorld() so render() can commence.



          Another way would be to run updateWorld() in the background while renderWorld() is running, but the synchronization of that can be tricky to handle.



          Multithreading renderWorld() is beyond my capabilities.






          share|improve this answer





















            Your Answer




            StackExchange.ifUsing("editor", function ()
            return StackExchange.using("mathjaxEditing", function ()
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            );
            );
            , "mathjax-editing");

            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "196"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );








             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186123%2fa-game-of-life-application-with-mouse-clicks%23new-answer', 'question_page');

            );

            Post as a guest






























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            2
            down vote













            Normal case



            Applications with user-interfaces normally work with a single thread, commonly something like this:



            loop 
            handleEvents()
            updateWorld()
            renderWorld()



            It's a bit hard to tell since the code does not seem complete, but from your description it seems to be doing handleEvents()/renderWorld() in one thread (by Application itself) and updateWorld() in another (your AnimationTimer), that will give thread-conflicts.



            Two possible solutions (I recommend 1 in this case, 2 is useful when incoming events must be coming through its own thread):



            1. Don't start a separate thread, jack into the update thread of the Application instead, there most likely is one available to jack in to

            2. Create a queue of incoming events in handle() and process the queue in the updateWorld() thread.

            If you want multi-threading:



            Multithreading is easiest to achieve in the updateWorld() part. This can be done by splitting the work that needs to be done into multiple threads, waiting for all of them to finish their work and then exiting updateWorld() so render() can commence.



            Another way would be to run updateWorld() in the background while renderWorld() is running, but the synchronization of that can be tricky to handle.



            Multithreading renderWorld() is beyond my capabilities.






            share|improve this answer

























              up vote
              2
              down vote













              Normal case



              Applications with user-interfaces normally work with a single thread, commonly something like this:



              loop 
              handleEvents()
              updateWorld()
              renderWorld()



              It's a bit hard to tell since the code does not seem complete, but from your description it seems to be doing handleEvents()/renderWorld() in one thread (by Application itself) and updateWorld() in another (your AnimationTimer), that will give thread-conflicts.



              Two possible solutions (I recommend 1 in this case, 2 is useful when incoming events must be coming through its own thread):



              1. Don't start a separate thread, jack into the update thread of the Application instead, there most likely is one available to jack in to

              2. Create a queue of incoming events in handle() and process the queue in the updateWorld() thread.

              If you want multi-threading:



              Multithreading is easiest to achieve in the updateWorld() part. This can be done by splitting the work that needs to be done into multiple threads, waiting for all of them to finish their work and then exiting updateWorld() so render() can commence.



              Another way would be to run updateWorld() in the background while renderWorld() is running, but the synchronization of that can be tricky to handle.



              Multithreading renderWorld() is beyond my capabilities.






              share|improve this answer























                up vote
                2
                down vote










                up vote
                2
                down vote









                Normal case



                Applications with user-interfaces normally work with a single thread, commonly something like this:



                loop 
                handleEvents()
                updateWorld()
                renderWorld()



                It's a bit hard to tell since the code does not seem complete, but from your description it seems to be doing handleEvents()/renderWorld() in one thread (by Application itself) and updateWorld() in another (your AnimationTimer), that will give thread-conflicts.



                Two possible solutions (I recommend 1 in this case, 2 is useful when incoming events must be coming through its own thread):



                1. Don't start a separate thread, jack into the update thread of the Application instead, there most likely is one available to jack in to

                2. Create a queue of incoming events in handle() and process the queue in the updateWorld() thread.

                If you want multi-threading:



                Multithreading is easiest to achieve in the updateWorld() part. This can be done by splitting the work that needs to be done into multiple threads, waiting for all of them to finish their work and then exiting updateWorld() so render() can commence.



                Another way would be to run updateWorld() in the background while renderWorld() is running, but the synchronization of that can be tricky to handle.



                Multithreading renderWorld() is beyond my capabilities.






                share|improve this answer













                Normal case



                Applications with user-interfaces normally work with a single thread, commonly something like this:



                loop 
                handleEvents()
                updateWorld()
                renderWorld()



                It's a bit hard to tell since the code does not seem complete, but from your description it seems to be doing handleEvents()/renderWorld() in one thread (by Application itself) and updateWorld() in another (your AnimationTimer), that will give thread-conflicts.



                Two possible solutions (I recommend 1 in this case, 2 is useful when incoming events must be coming through its own thread):



                1. Don't start a separate thread, jack into the update thread of the Application instead, there most likely is one available to jack in to

                2. Create a queue of incoming events in handle() and process the queue in the updateWorld() thread.

                If you want multi-threading:



                Multithreading is easiest to achieve in the updateWorld() part. This can be done by splitting the work that needs to be done into multiple threads, waiting for all of them to finish their work and then exiting updateWorld() so render() can commence.



                Another way would be to run updateWorld() in the background while renderWorld() is running, but the synchronization of that can be tricky to handle.



                Multithreading renderWorld() is beyond my capabilities.







                share|improve this answer













                share|improve this answer



                share|improve this answer











                answered Apr 12 at 17:31









                DHa

                1314




                1314






















                     

                    draft saved


                    draft discarded


























                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186123%2fa-game-of-life-application-with-mouse-clicks%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    Popular posts from this blog

                    Chat program with C++ and SFML

                    Function to Return a JSON Like Objects Using VBA Collections and Arrays

                    Will my employers contract hold up in court?