Archive for June, 2009

Cellular automaton in .NET

Tuesday, June 30th, 2009

What is a cellular automata (CA). A cellular automaton is a discrete model studied in computability theory, mathematics, theoretical biology and microstructure modeling. It consists of a regular grid ofcells, each in one of a finite number of states, such as “On” and “Off” (1 nad 0, alive or death). The grid can be in any finite number of dimensions. For each cell, a set of cells called its neighborhood (usually including the cell itself) is defined relative to the specified cell. For example, the neighborhood of a cell might be defined as the set of cells a distance of 2 or less from the cell.

Some specific CA are:

Here is an sample of Conway’s Game of Life in C#. This is a pattern for Game of Life:

Every cell interacts with its eight neighbours, which are the cells that are directly horizontally, vertically, or diagonally adjacent. At each step in time, the following transitions occur:

  1. Any live cell with fewer than two live neighbours dies, as if caused by underpopulation.
  2. Any live cell with more than three live neighbours dies, as if by overcrowding.
  3. Any live cell with two or three live neighbours lives on to the next generation.
  4. Any dead cell with exactly three live neighbours becomes a live cell.
We will create abstract class: RuleSet
class: RuleSet
using System;
using System.Collections.Generic;
using System.Text;

namespace GameOfLife
{
    public abstract class RuleSet
    {
        protected int _maxX = 0;
        protected int _maxY = 0;
        protected int[,] _field;

        public RuleSet(int [,] field, int maxX, int maxY)
        {
            _field = field;
            _maxX = maxX;
            _maxY = maxY;
        }

        protected int  GetNumberOfNeighbors(int x, int y)
        {

            int neighbors = 0;
            int xPos;
            int yPos;
            for (xPos= x -1; xPos < = x +1; xPos ++)
            {
                for (yPos= y -1; yPos <= y +1; yPos ++)
                {
                    if(xPos == x && yPos == y) continue;

                    if (xPos < _maxX &&  xPos >=0 && yPos < _maxY && yPos >=0 & _field[xPos, yPos] == 1)
                    {
                        neighbors++;
                    }     

                }
            }

            return neighbors;
        }

        public void GetNewState()
        {
            int [,] field2 = NewStateAlgorithm();
            Array.Copy(field2, _field, field2.Length);
        }

        protected abstract int[,] NewStateAlgorithm();
    }
}

Then we create our concrete class for “Game of Live” inherited from base class:
class: ConwaysGameOfLife

using System;
using System.Collections.Generic;
using System.Text;

namespace GameOfLife
{
    public class ConwaysGameOfLife : RuleSet
    {
       public ConwaysGameOfLife(int[,] field, int maxX, int maxY)
            : base(field, maxX, maxY)
        {

        }

        protected override int[,] NewStateAlgorithm()
        {
            int[,] field2 = new int[_maxX, _maxY];

            for (int y = 0; y < _maxY; y++)
            {
                for (int x = 0; x < _maxX; x++)
                {
                    int neighbors = GetNumberOfNeighbors(x, y);
                    if (neighbors == 3)
                    {
                        // cell is born.
                        field2[x, y] = 1;
                        continue;
                    }

                    if (neighbors == 2 || neighbors == 3)
                    {
                        // cell continues.
                        field2[x, y] = _field[x, y];
                        continue;
                    }

                    // cell dies.
                    field2[x, y] = 0;
                }
            }

            return field2;
        }
    }
}

And we have all we need. Now create Simple Windows Console application to run this:

using System;
using System.Collections.Generic;
using System.Text;

namespace GameOfLife
{
    class Program
    {
        private const char cellImage = 'o';
        private const int maxWidth = 80;
        private const int maxHeight = 60;
        private static int[,] field = new int[maxWidth, maxHeight];

        static void DrawCell()
        {
            Console.CursorLeft = 0;
            Console.CursorTop = 0;

            for( int y = 0; y < maxHeight; y ++)
            {
                for( int x = 0; x < maxWidth; x ++)
                {
                    Console.Write(field[x, y] == 1 ? cellImage : ' ');
                }
                Console.WriteLine();
            }
        }

        static void Main(string[] args)
        {

            int startX = maxWidth / 2;
            int startY = maxHeight / 2;

            Console.SetWindowSize(maxWidth + 10, maxHeight + 10);
            Console.SetWindowPosition(0, 0);

           for (int x = 0; x < maxWidth; x++)
            {
                field[x, startY] = 1;
            }
            for (int y = 0; y < maxHeight; y++)
            {
                field[startX, y] = 1;
            }

            RuleSet gameOfLife = new ConwaysGameOfLife(field, maxWidth, maxHeight);
            for (int i = 0; i < 5000; i++)
            {
                DrawCell();
                gameOfLife.GetNewState();
                Console.WriteLine(i);
            }

        }
    }
}

and here is result. This is initila state for our “automata”.
Cellular Automata - Game of Live, Initial state
and this is how it looks after 10 iterations:
Cellular Automata - Game of Life after 10 iterations.

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in