Showing posts with label Global Day of Code Retreat. Show all posts
Showing posts with label Global Day of Code Retreat. Show all posts

Thursday, November 20, 2014

Refactoring Conway's Game of Life in Clojure

In the previous post I presented a solution of Conway's Game of Life in Clojure.

I've refactored that code in order to eliminate some duplication from the game rules.

First of all, I coded using TDD a new function will-have-a-cell? that later substituted both will-go-on-being-a-cell? and will-be-a-cell?.

These are the tests for the game rules after deleting the obsolete functions (will-go-on-being-a-cell? and will-be-a-cell?):

and this is the new function's code:

Once I had the new function I used it inside both keep-being-cells and new-cells functions to highlight the duplication between them:

Then I eliminated that duplication by using will-have-a-cell? directly in next-cells function, which made both keep-being-cells and new-cells obsolete:

Notice how will-have-a-cell? is used to filter all the possible locations (the current cells and their neighbors) which are given by the new all-neighbors-locations function.

Then I eliminated all the obsolete functions and their tests and did some renaming of the remaining functions, local bindings and parameters.

These are the resulting tests:

and this is the resulting code:

which is slightly shorter than the one in the previous version.

As usual I commited the code after every passing test and every refactor.

You will notice a problem I had with Midje :autotest not reacting properly after some of the renamings I did. I had to restart it so that it could take into account the changes.

If you want to follow the whole process, you can find the commits step by step here.

You can also find the resulting code in GitHub.

Wednesday, November 19, 2014

Kata: Conway's Game of Life in Clojure

Last Saturday I attended the Global Day of Code Retreat in Zaragoza where I had a great time practicing with other kindred spirits.

Today I did a version of Conway's Game of Life in Clojure having in mind some of the ideas I took home from the code retreat.

These are the resulting tests using Midje:

and this is the code:

When I have some more time and learn more Clojure, I'd like to make it configurable to change the geometry of the game and its rules using different versions of the neighbors, will-go-on-being-a-cell? and will-be-a-cell? functions.

I did another version of Conway's Game of Life in Java some time ago which could be configured in that manner.

I used a mix of TDD and REPL-driven development to solve it.

I commited the code after every passing test and every refactor. I also commited the tiny tests and spikes I did on the REPL.

If you want to follow the process, you can find the commits step by step here.

You can also find the resulting code in GitHub.

Thanks to all the colleagues from Zaragoza!

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.