Crystal, TDD and Conway’s Game of Life.

Anderson Dias
Little programming joys
5 min readJun 21, 2017

How I learned a new programming language having fun and using tests.

Example of rendering of the game

The Game of Life is a cellular automation devised by the British mathematician John Horton Conway in 1970.

I’ve been using it as a challenge to learn and teach programming languages in the past 5 years.

My game implementations

My first Game of Life implementation was writen in Javascript.

I was learning how to use Jasmine to test JS code and decided to implement the game using TDD.

The good thing about using JS is that you can actually play the game by opening the index.html file in a browser. So, have fun!

Afterward, I’ve started another implementation using Ruby and RSpec. Unfortunately, it stills incomplete.

This was the base project I’ve used to teach Ruby and TDD in my classes.

The game rules

Let’s talk about the game.

The “game” is a zero-player game, meaning that its evolution is determined by its initial state, requiring no further input. One interacts with the Game of Life by creating an initial configuration and observing how it evolves.

So, the only thing “the player” is able to do is to evoke the next generation and see what happens.

The universe of the Game of Life is an infinite two-dimensional orthogonal grid of square cells, each of which is in one of two possible states, alive or dead. Every cell interacts with its eight neighbours, which are the cells that are horizontally, vertically, or diagonally adjacent. At each step in time, the following transitions occur:

  • Any live cell with fewer than two live neighbours dies, as if caused by under-population.
  • Any live cell with two or three live neighbours lives on to the next generation.
  • Any live cell with more than three live neighbours dies, as if by overcrowding.
  • Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.

The initial pattern constitutes the seed of the system. The first generation is created by applying the above rules simultaneously to every cell in the seed — births and deaths occur simultaneously, and the discrete moment at which this happens is sometimes called a tick (in other words, each generation is a pure function of the preceding one). The rules continue to be applied repeatedly to create further generations.

Using Crystal and TDD

Crystal is a Ruby alike compiled programming language. I’ve been studying it since the day I met with its creators at RubyConfBr 2016.

It’s blazing fast if compared to the same implementation in pure Ruby. Conway’s Game of Life is the best way to figure out language features like class structure, variables scopes, etc.

The final project can be found here:

If you want to understand how I had evolved into the final solution I suggest you to walk through the commit history. Each commit explains what I’ve made and learned in order to make a new improvement towards the 4 rules to be implemented.

Installing Crystal

The project has only one dependency: Crystal. In order to install it you must follow it’s official installation guide.

Writing a test, making it fail and getting it fixed

I decided to follow through the game rules and implement them one by one.

The first thing to do is to write a test to the first rule and see it breaking.

Crystal has an internal spec suite with a rspec alike structure (describe, context and it blocks).

You can run the specs via crystal spec command.

I ran the specs and bang! I got a syntax error!

Crystal uses double quoted strings. Single quoted strings are used to char literals. Ok. Let’s fix it and move to the next error.

Now we have Cell class with a dead? method returning false. It looks like it’s ok. But, I realised I’ve missed the project namespace in this class and added it in the next commit.

The code isn’t that good. It looks like I’ve coded enought to make the spec pass but it doesn’t seems to fix the whole rule to pass.

It’s time to introduce the concept of Population to our challenge. A population is a group of cells.

It fails because there are many differences between Crystal::Spec and RSpec structure. Callbacks like before/after_each are pretty different and do not share scope with it blocks as in Ruby.

A new learning in every commit

Ok. Let’s stop for now.

I do not pretent to explain each commit. The project is 38 commits long. Each of them explains what I’m trying to do, the errors I’ve ran into and how to fix them.

My point here is: this is how I use TDD to learn a new language.

  1. Have a challenge
  2. Setup your environment
  3. Write a test, see what is wrong and fix it.
  4. Move to next problem and keep this cycle until you’re done.
The TDD Lyfecycle

Conclusion

Learning something new may be fun.

Crystal is really easy to learn if you are fluent in Ruby. It has a few gotchas in the beginning, but, as soon as you realise how it works, it’s awesome.

The languange is evolving in fast pace and I hope it reachs production ready state soon, so we can safely use it in real projects.

Also, I hope you enjoy Conway’s challenge and use it to improve your programming skills as I do.

Have fun!

--

--