Matt Hinds' Open Source Game of Life project, written in Java.
I wanted to test out the wiki code importer, check it out below. From the Java Game of Life project.
package com.life.model; import java.awt.Dimension; import java.util.ArrayList; import com.life.constants.Constants; import com.life.model.event.ModelBoardResetEvent; import com.life.model.event.ModelBoardRuleSetEvent; import com.life.model.event.ModelBoardUpdateEvent; import com.life.rule.ILifeRule; import com.math.ArrayMath; public class LifeModel { protected ArrayList<IModelEventsListener> listeners = new ArrayList<IModelEventsListener>(); protected int xBounds = Constants.DEFAULT_X_BOUNDS; protected int yBounds = Constants.DEFAULT_Y_BOUNDS; protected boolean[][] board = null; protected ILifeRule currentRule = null; public int generation = 0; public LifeModel() { initializeModel(); } /** * initializes the lifeModel with the designated sizes * * @param x * @param y */ public LifeModel(int x, int y) { xBounds = x; yBounds = y; initializeModel(); } public boolean[][] getRawBoardCopy() { return ArrayMath.copy(board); } private LifeModel(int x, int y, boolean[][] board, ArrayList<IModelEventsListener> listeners, ILifeRule rule) { xBounds = x; yBounds = y; this.board = new boolean[board.length][board[0].length]; /* initialize board to all false */ for (int i = 0; i < xBounds; i++) { for (int j = 0; j < yBounds; j++) { this.board[i][j] = board[i][j]; } } this.currentRule = rule; this.listeners = listeners; } /** * Initializes the internal model components */ protected void initializeModel() { /* initialize the model to the correct size */ board = new boolean[xBounds + 2][yBounds + 2]; /* initialize board to all false */ reset(); /* initialize listener space */ listeners = new ArrayList<IModelEventsListener>( Constants.SMALL_COLLECTION_SIZE); } public void addModelEventsListener(IModelEventsListener listener) { listeners.add(listener); } public LifeModel deepCloneModel() { return new LifeModel(xBounds, yBounds, board, listeners, currentRule); } public Dimension getSize() { return new Dimension(xBounds, yBounds); } public boolean isAlive(int x, int y) { return getValue(x,y); } public void setAlive(int x, int y) { setValue(x, y, Constants.ALIVE); } public void setDead(int x, int y) { setValue(x, y, Constants.DEAD); } public boolean getValue(int x, int y) { if(isValid(x,y)) { return board[x + 1][y + 1]; } return false; } public void setValue(int x, int y, boolean val) { board[Math.max(0, (x + 1) % xBounds)][Math.max(0, (y + 1) % yBounds)] = val; } public void reset() { for (int i = 0; i < xBounds; i++) { for (int j = 0; j < yBounds; j++) { board[i][j] = Constants.DEAD; } } generation = 0; fireModelBoardResetEvent(); } public int getGenerationCount() { return generation; } public int getNeighborCount(int x, int y) { int boardX = x + 1; int boardY = y + 1; int returnVal = 0; /* cleaned up this code a little bit */ returnVal = returnVal + (getValue(x-1,y-1)?1:0); returnVal = returnVal + (getValue(x-1,y)?1:0); returnVal = returnVal + (getValue(x-1,y+1)?1:0); returnVal = returnVal + (getValue(x,y-1)?1:0); returnVal = returnVal + (getValue(x,y+1)?1:0); returnVal = returnVal + (getValue(x+1,y-1)?1:0); returnVal = returnVal + (getValue(x+1,y)?1:0); returnVal = returnVal + (getValue(x+1,y+1)?1:0); return returnVal; } @Override public String toString() { String returnVal = ""; for (int i = 0; i < xBounds; i++) { returnVal = returnVal + "|"; for (int j = 0; j < yBounds; j++) { if (isAlive(i, j)) { returnVal = returnVal + "X"; } else { returnVal = returnVal + "_"; } } returnVal = returnVal + "|\n"; } return returnVal; } public void fireOnUpdateEvent() { for (IModelEventsListener listener : listeners) { listener.modelBoardUpdated(new ModelBoardUpdateEvent(this)); } } public void runRule() { LifeModel newModel = currentRule.runRule(this); replaceBoard(newModel); generation++; this.fireOnUpdateEvent(); } public void replaceBoard(LifeModel newModel) { for (int i = 0; i < xBounds; i++) { for (int j = 0; j < yBounds; j++) { setValue(i, j, newModel.isAlive(i, j)); } } this.fireOnUpdateEvent(); } public void replaceRawBoard(boolean value[][], int gen) { for (int i = 0; i < xBounds; i++) { for (int j = 0; j < yBounds; j++) { if(value.length > i+1 && value[0].length > j+1) { setValue(i, j, value[i + 1][j + 1]); } } } generation = gen; this.fireOnUpdateEvent(); } public int getLifeCount() { int result = 0; for (int i = 0; i < xBounds; i++) { for (int j = 0; j < yBounds; j++) { result+=(isAlive(i,j))?1:0; } } return result; } public void adjustBoardSize(int width, int height) { boolean[][] oldBoard = board; int oldX = xBounds; int oldY = yBounds; int adjustX = 0; int adjustY = 0; adjustX = (width < xBounds) ? width : xBounds; adjustY = (height < yBounds) ? height : yBounds; System.out.println("adjustX:" + adjustX + "| adjustY:" + adjustY); xBounds = width; yBounds = height; board = new boolean[width + 2][height + 2]; reset(); for (int i = 0; i < adjustX; i++) { for (int j = 0; j < adjustY; j++) { setValue(i, j, oldBoard[i][j]); } } fireOnUpdateEvent(); } public ILifeRule getCurrentRule() { return currentRule; } public void fireModelBoardResetEvent() { ModelBoardResetEvent firedEvent = new ModelBoardResetEvent(this); for (IModelEventsListener listener : listeners) { listener.modelBoardReset(firedEvent); } } public void fireRuleSetEvent() { ModelBoardRuleSetEvent firedEvent = new ModelBoardRuleSetEvent(this); firedEvent.setRule(currentRule); for (IModelEventsListener listener : listeners) { listener.modelRuleSet(firedEvent); } } public void setCurrentRule(ILifeRule currentRule) { this.currentRule = currentRule; fireRuleSetEvent(); } /** * Checks if the specified cell is a valid coordinate on the board. * @param x * @param y * @return */ public boolean isValid(int x, int y) { //Normalize coordinates by adding 1. x+=1; y+=1; if(x>0 && y>0) { if(x<board.length && y<board[x].length) { return true; } } //not a valid game board position return false; } }
http://javagameoflife.googlecode.com/svn/LifeProject/com/life/model/LifeModel.java