Click here to Skip to main content
15,886,199 members
Articles / Desktop Programming / WPF

Conway's Game of Life - A Rule Framework and Implementation

Rate me:
Please Sign up or sign in to vote.
5.00/5 (11 votes)
15 Apr 2013CPOL5 min read 27.1K   1.4K   36  
A rule engine based approach to add and remove rules to play Conway's Game of Life
using System.Collections.Generic;

namespace gameOfLife.Framework
{
    /// <summary>
    /// Cell object
    /// </summary>
    public class Cell
    {
        private int xPos;
        private int yPos;
        private uint age;
        private bool isAlive;

        private IList<Cell> neighbouringLocations = null;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="x">x</param>
        /// <param name="y">y</param>
        public Cell(int x, int y)
        {
            xPos = x;
            yPos = y;

            age = 0;
            isAlive = true;
        }

        /// <summary>
        /// X Position
        /// </summary>
        public int X
        {
            get { return xPos; }
        }

        /// <summary>
        /// Y Position
        /// </summary>
        public int Y
        {
            get { return yPos; }
        }

        /// <summary>
        /// Alive or not
        /// </summary>
        public bool IsAlive
        {
            get
            {
                return isAlive;
            }
        }

        /// <summary>
        /// How old is this cell
        /// </summary>
        public uint Age
        {
            get
            {
                return age;
            }
        }

        /// <summary>
        /// Kill the cell. A cell object can killed but still exist in 
        /// the domain until the domain cleans itself of dead cells
        /// </summary>
        public void Kill()
        {
            isAlive = false;
        }

        /// <summary>
        /// Increase age by one
        /// </summary>
        public void Grow()
        {
            age++;
        }

        /// <summary>
        /// The a list of proxy neighbouring cells of this cell (surrounding 8 cells)
        /// The set of proxy neighbouring cells have no meaning in the problem domain
        /// </summary>
        public IList<Cell> NeighbouringLocations
        {
            get
            {
                if (neighbouringLocations == null)
                {
                    neighbouringLocations = new List<Cell>();

                    // need a mechanism to generate all cells
                    neighbouringLocations.Add(new Cell(X - 1, Y - 1));
                    neighbouringLocations.Add(new Cell(X + 0, Y - 1));
                    neighbouringLocations.Add(new Cell(X + 1, Y - 1));
                    neighbouringLocations.Add(new Cell(X + 1, Y + 0));
                    neighbouringLocations.Add(new Cell(X + 1, Y + 1));
                    neighbouringLocations.Add(new Cell(X + 0, Y + 1));
                    neighbouringLocations.Add(new Cell(X - 1, Y + 1));
                    neighbouringLocations.Add(new Cell(X - 1, Y + 0));
                }

                return neighbouringLocations;
            }
        }

        /// <summary>
        /// Equals overload
        /// </summary>
        /// <param name="cellobj"></param>
        /// <returns></returns>
        public override bool Equals(object cellobj)
        {
            if (cellobj == null)
            {
                return false;
            }

            Cell cell = cellobj as Cell;

            if (cell == null)
            {
                return false;
            }

            return cell.X == X && cell.Y == Y;
        }

        /// <summary>
        /// Overridden GetHasCode() for warnings. Might be used if added to a hashmap
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            // return base.GetHashCode();
            return X * 10000 + Y;
        }
    }

    /// <summary>
    /// List extensions
    /// </summary>
    public static class ListExtensions
    {
        /// <summary>
        /// Remove certain specified cells from a list
        /// </summary>
        /// <param name="list1">base list</param>
        /// <param name="list2">cells to be removed</param>
        /// <returns></returns>
        public static IList<Cell> Filter(this IList<Cell> list1, IList<Cell> list2)
        {
            IList<Cell> result = new List<Cell>();

            foreach (var cell in list1)
            {
                if (!list2.Contains(cell))
                {
                    result.Add(cell);
                }
            }

            return result;
        }

        /// <summary>
        /// Get intersection
        /// </summary>
        /// <param name="list1">base list</param>
        /// <param name="list2">to be matched</param>
        /// <returns></returns>
        public static IList<Cell> Match(this IList<Cell> list1, IList<Cell> list2)
        {
            IList<Cell> result = new List<Cell>();

            foreach (var cell in list2)
            {
                if (list1.Contains(cell))
                {
                    result.Add(cell);
                }
            }

            return result;
        }
    } 
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
India India
is a poor software developer and thinker. Presently working on a theory of "complementary perception". It's a work in progress.

Comments and Discussions