Game of Life in Silverlight
Every now and then you start on something that is so addictive that you just can't leave the code. I've experienced that today, and it was meant to be a day off work!
I've known about the 'Game of Life' for a long time - the cellular automation devised by John Conway in 1970. However, after a recent conversation, I began reading up on it. This blog post and the resulting game in Silverlight are the result.
The game hooks you in when you start researching it. The rules are incredibly simple. A simple algorithm can be created in a couple of lines. However, the beauty comes when viewing the many 'life forms' that can exist. There are only 4 rules in the game of live, but countless lifeforms.
Writing the game of life in Silverlight was not too taxing. I've built a simple GoL class to perform the actual game logic, A set of Lifeform classes (all inheriting from the abstract Lifeform class) which represent different patterns. I've only selected a few of the many available. A full life lexicon gives more information about the patterns.
Points of Interest
1. The cells are stored internally using BitArrays. BitArrays are well suited to this type of data, and include bitwise operators to enable changes to cells to be calculated.
2. There are generally two ways to handle the edge of the game area. The first way is to 'kill' cells as they hit the edge. However, this has the effect of prematurely killing the remainder of the shape. The other way is to wrap the cells left-right and top-bottom. This is the approach I have taken. The only problem with this is that some shapes come back in on themselves and interfere with other cells. However, you should be able to see how most lifeforms grow before this happens.
3. Optimisation - I have included a simple GoL optimisation. Looping through each cell, and counting its neighbors is very inefficient. The process can be 'inverted'. In my routine, I maintain an int array, representing the number of live neighbors at each cell. I loop through each cell, and when I hit a live cell, I add 1 to each of the neighbor's count cells. In this fashion, I can completely ignore empty cells. This has proven to be a simple and effective optimisation. I also began looking into bit-shifting in the hope to remove looping completely. I had some limited success, but could not bring the performance up beyond my intial optimisation - this was partly due to me not being able to create bit-rotated versions of the starting BitArray at each generation. the BitArray does not appear to support any bit rotation methods, and my home-spun version involved copying whole arrays in memory - probably not the most efficient way of shifting bits.
4. The display is handled using a WriteableBitmap. This is a new class in Silverlight 3.0, and has already been used in a number of emulators. The WriteableBitmap enables you to set individual bits at run-time.
I may add more creatures over time. But for now, I hope you find this enjoyable to watch. If you're interested, you can also grab the source code.
David Barone, 23 July, 2009, 8:31 pm
Last Modified: 23 July, 2009, 8:31 pm

Comments: