A Game of Life application, with mouse clicks
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
8
down vote
favorite
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?
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");
java thread-safety concurrency game-of-life javafx
add a comment |Â
up vote
8
down vote
favorite
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?
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");
java thread-safety concurrency game-of-life javafx
add a comment |Â
up vote
8
down vote
favorite
up vote
8
down vote
favorite
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?
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");
java thread-safety concurrency game-of-life javafx
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?
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");
java thread-safety concurrency game-of-life javafx
edited Feb 21 at 14:35
200_success
123k14143401
123k14143401
asked Jan 27 at 12:22
woodStone
763
763
add a comment |Â
add a comment |Â
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):
- 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
- 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.
add a comment |Â
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):
- 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
- 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.
add a comment |Â
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):
- 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
- 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.
add a comment |Â
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):
- 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
- 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.
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):
- 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
- 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.
answered Apr 12 at 17:31
DHa
1314
1314
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password