I've been working on a basic implementation of Conway's Game of Life over the last day, and I've just finished a 'playable' version.
If anyone has the time, would you mind making any suggestions on code improvements that I can make?
Thanks!
GameOfLife.java
package robbie.gameoflife.main;
import java.awt.Dimension;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
import robbie.gameoflife.cells.Cell;
import robbie.gameoflife.cells.CellManager;
public class GameOfLife {
private static final String TITLE = "Game of Life";
public static final int CELL_SIZE = 10, CELL_AMOUNT = 50;
public static final int WIDTH = CELL_SIZE * CELL_AMOUNT, HEIGHT = WIDTH;
public static final Dimension DIMENSIONS = new Dimension(WIDTH, HEIGHT);
private static final boolean RUNNING = true;
public static final Cell[][] CELLS = new Cell[CELL_AMOUNT][CELL_AMOUNT];
public static void main(String[] args) {
JFrame frame = new JFrame(TITLE);
frame.setSize(DIMENSIONS);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
GameCanvas canvas = new GameCanvas();
frame.add(canvas);
canvas.createBufferStrategy(3);
loadCells();
CELLS[10][10].setAlive(true);
CELLS[10][11].setAlive(true);
CELLS[10][12].setAlive(true);
CELLS[11][10].setAlive(true);
CELLS[12][10].setAlive(true);
CELLS[12][11].setAlive(true);
CELLS[12][12].setAlive(true);
CELLS[11][12].setAlive(true);
startGameLoop(canvas);
}
private static void loadCells() {
for (int x = 0; x < CELLS.length; x++) {
for (int y = 0; y < CELLS[x].length; y++) {
if (CELLS[x][y] == null)
CELLS[x][y] = new Cell(x, y);
}
}
}
private static void startGameLoop(GameCanvas canvas) {
Timer timer = new Timer();
if (RUNNING) {
timer.schedule(new TimerTask() {
@Override
public void run() {
CellManager.updateCells();
canvas.repaint();
}
}, 1000, 1000);
}
}
}
GameCanvas.java
package robbie.gameoflife.main;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
import robbie.gameoflife.cells.Cell;
public class GameCanvas extends Canvas {
public GameCanvas() {
super();
this.setSize(GameOfLife.WIDTH, GameOfLife.HEIGHT);
this.setBackground(Color.WHITE);
this.setFocusable(true);
this.setVisible(true);
}
public void paint(Graphics g) {
Graphics graphics = this.getGraphics();
graphics.clearRect(0, 0, GameOfLife.WIDTH, GameOfLife.HEIGHT);
Random random = new Random();
graphics.setColor(new Color(random.nextFloat(), random.nextFloat(), random.nextFloat()));
for (Cell[] cells : GameOfLife.CELLS) {
for (Cell cell : cells) {
if (cell.isAlive()) {
int size = GameOfLife.CELL_SIZE;
int x = cell.getX() * size;
int y = cell.getY() * size;
graphics.fillRect(x, y, size, size);
}
}
}
}
}
Cell.java
package robbie.gameoflife.cells;
public class Cell {
private int x, y;
private boolean alive = false;
public Cell(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public boolean isAlive() {
return alive;
}
public void setAlive(boolean alive) {
this.alive = alive;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void toggleAlive() {
this.alive = !this.alive;
}
}
CellManager.java
package robbie.gameoflife.cells;
import java.util.ArrayList;
import robbie.gameoflife.main.GameOfLife;
public class CellManager {
public static ArrayList<Cell> getNeighbourCells(Cell cell) {
ArrayList<Cell> neighbourCells = new ArrayList<Cell>();
int cellX = cell.getX();
int cellY = cell.getY();
for (int x = cellX - 1; x <= cellX + 1; x++) {
for (int y = cellY - 1; y <= cellY + 1; y++) {
if (x < 0 || x >= GameOfLife.CELL_AMOUNT || y < 0 || y >= GameOfLife.CELL_AMOUNT)
continue;
Cell neighbourCell = GameOfLife.CELLS[x][y];
if (neighbourCell.equals(cell))
continue;
if (neighbourCell.isAlive())
neighbourCells.add(neighbourCell);
}
}
return neighbourCells;
}
public static int getNeighbourCount(Cell cell) {
return getNeighbourCells(cell).size();
}
public static void updateCells() {
ArrayList<Cell> deadCells = new ArrayList<Cell>();
ArrayList<Cell> aliveCells = new ArrayList<Cell>();
for (Cell[] cells : GameOfLife.CELLS) {
for (Cell cell : cells) {
int neighbourCount = CellManager.getNeighbourCount(cell);
if (neighbourCount < 2 || neighbourCount > 3)
deadCells.add(cell);
else if (cell.isAlive() && (neighbourCount == 2 || neighbourCount == 3))
aliveCells.add(cell);
else if (!cell.isAlive() && neighbourCount == 3)
aliveCells.add(cell);
}
}
for (Cell cell : aliveCells)
cell.setAlive(true);
for (Cell cell : deadCells)
cell.setAlive(false);
}
}