Showing posts with label Conway's Game of Life. Show all posts
Showing posts with label Conway's Game of Life. Show all posts

Monday, January 26, 2015

Refactoring Conway's Game of Life in Java

I've recently revisited the Java version of Conway's Game of Life that I did nearly a year ago, to refactor it using some of the ideas I used in my more recent Clojure version.

This is the UML for the refactored design:


I eliminated the LivingCells class that appeared in the previous design.

I pushed a lot of code from the GameOfLife class into Generation to eliminate a bit of feature envy. This is GameOfLife's code now:

and this is Generation's one:

I also refactored the tests eliminating all the checks based on strings and using constructors with variadic parameters.

Following the idea in the Clojure version I managed to simplify the Rules interface a lot:

Most of the other changes are just renaming of methods, variables and parameters.

This new code keeps the functionality and characteristics of the previous version but it's much simpler.

Saturday, February 8, 2014

My path to JavaScript: JavaScript Code Retreat Valencia

Today I participated in the JavaScript Code Retreat in Valencia.

It was a great experience because limiting the possible languages to just one, JavaScript, (that we all knew at least enough to work on the kata) made our practice even more focused.
By not having to switch between languages and test frameworks (we all used Jasmine), we could just concentrate in doing our best to craft good code under the constraints of each iteration.

It's been fun and I learned a lot again revisiting Conway's Game of Life. I recently coded a complete solution of this game in Java, but today I tried different approaches with my partners and also focused even more in naming.

I'd like to thank Ricardo Borillo, Wolfram Kriesing and peerTransfer for making it possible.

Sunday, February 2, 2014

Conway's Game of Life in Java

Last December I attended the Global Day of Code Retreat in Valencia.

It was a lot of fun and we thought and discussed a lot about the problem. Thanks to all the participants and the organizers for the great time.

When I came back to Barcelona I decided to go on practicing by developing a full solution to Conway's Game of Life on my own.

I wanted the solution to include several of the ideas that we had been discussing during the code retreat:
  • Tracking only living cells. 
  • Open/Closed with regard to the rules based on the number of neighbors. 
  • Open/Closed with regard to the number and location of a cell's neighbors. 
  • Open/Closed with regard to the dimensions of the grid (2D, 3D, 4D, etc).

It took me several rewrites but finally I came up with this solution that respects all the previous ideas.



- Tracking only living cells 
A Generation has a collection of cells that are alive, LivingCells, and a set of Rules.

This way the "state of the cell" concept we tried in some iterations of the code retreat becomes pointless and it requires less space to store the current generation.

I also made Generation immutable.

To generate the next Generation of LivingCells (produceNextGeneration method), it first adds the surviving cells (addSurvivors method) and then the newly born cells (addNewCells method).


- Open/Closed with regard to the rules based on the number of neighbors.
Rules is an interface with two methods, shouldStayAlive and shouldBeBorn, that you can implement the way you wish.

The rules are still based on the number of neighbors which is the parameter passed to both methods.

In this case, I only implemented the rules of the Conway's Game of Life: ConwaysRules class, but more rules based on the number of neighbors might be added.


- Open/Closed with regard to the number and location of a cell's neighbors and Open/Closed with regard to the dimensions of the grid (2D, 3D, 4D, etc).
This two are possible thanks to the Cell interface. It has only a method, getNeighbors, which returns the neighbors of a cell. It's up to the cell to know which are its neighbors.

In this way each implementation of Cell can have a different dimension and a different number of neighbors which can be located following different stencils.

In this case, I implemented several types of cells: ConwaysCell, CellX2D, CellCross3D and CellCross2D. The code that is common to all 2D cells is in the Cell2D abstract class, whereas the one that is common to all 3D cells is in the Cell3D abstract class.

You can have a look at the code on GitHub.

Update: I refactored this code making it much simpler. Take a look at the new version.