I have written a program, based off of some examples, to simulate Conway's game of life.
Each cell in the game is either alive or dead and they are stored in an array of integers int[][]
this array is always at least 1000*1000, meaning that there are millions of cells.
Iterating through the array to find apply all of the different rules is fine, and is not particularly CPU intensive. However, the method used to draw these rectangles on a JFrame can lead to 90+% CPU usage on my Xeon E3 1246 V3 (I7 4770). On array sizes of 2000^2, it can lead to Windows 10 hard locking completely.
@Override
protected void paintComponent(Graphics g) {
liveCells = 0;
super.paintComponent(g);
Color gColor = g.getColor();
if(!backgroundWork || isPaused) {
for (int row = 0; row < grid.length; row++) {
for (int column = 0; column < grid[row].length; column++) {
//Checking if the cell is alive.
if (grid[row][column] == 1 ) {
liveCells++;
g.setColor(Color.red);
g.fillRect(column * UIScale, row * UIScale, UIScale, UIScale);
}
}
}
}
g.setColor(gColor);
if (isPaused) {
g.drawString("The game is paused", 0, 30);
g.drawString("Generation: " + generationCounter, 0, 10);
g.drawString("Living cells: " + liveCells, 150, 10);
} else { //If the game is running
g.drawString("Generation: " + generationCounter++, 0, 10);
g.drawString("Living cells: " + liveCells, 100, 10);
}
g.setColor(gColor);
try {
/* Sleep for some microseconds. */
TimeUnit.MICROSECONDS.sleep(sleepTimer);
} catch (InterruptedException ex) {
System.err.println("An InterruptedException was caught: " + ex.getMessage());
}
}
I can see quite clearly that the drawing of the cells is the problem, in order to allow the program to run faster, I had already added a way to change the variable backgroundWork, which disables updating the grid of rectangles. Turning this on or off results in differences of up to 80% in task manager CPU utilisation.
With the current method of drawing the grid, I don't see a way to make it much faster, as all the cells are independent of each other, and generally there won't be more than 3 which are red next to each other anyway, so there is no reason to implement a way to draw multiple at the same time.
Can anyone suggest a way to speed up the current process, or a different way of drawing the squares. Thanks for any help.