Click here to Skip to main content
15,896,154 members
Articles / Programming Languages / C#

LINQ to Life

Rate me:
Please Sign up or sign in to vote.
4.94/5 (69 votes)
6 Mar 2008CPOL7 min read 119K   442   138  
Using LINQ to improve everyday code
//
// MainForm.cs
//
// -------------------------------------------------------------------
// History:
//  2008-02-23	Kwak		Original File 
// -------------------------------------------------------------------

using System;
using System.Drawing;
using System.Windows.Forms;
using GameOfLife.Core;
using System.Linq;

namespace GameOfLife.WinUi
{
    /// <summary>
    /// Drawing surface for the game
    /// </summary>
    public partial class MainForm : Form
    {

        #region Constants
        // These could be defined at runtime of in the config 
        private const int GridWidth = 50;
        private const int GridHeight = 50;
        private const int CellDim = 10;
        private const int AdultAge = 10;
        private const int AdolescentAge = 1;
        #endregion

        #region Fields
        private long _generationCount = 0;
        private int _ageLimit = 0;
        private PetriDish _grid;
        #endregion

        #region Initialization/Setup
        public MainForm()
        {
            InitializeComponent();
        }
        #endregion

        #region Control Events/Overloads

        /// <summary>
        /// The load event starts the timers.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void OnLoad(object sender, EventArgs e)
        {
            _grid = new PetriDish(GridWidth, GridHeight);
            _grid.Reset();
            setGenerationsPerSecond();
            setAgeLimit();
        }

        /// <summary>
        /// The way the grid is drawn
        /// </summary>
        /// <param name="e">A <see cref="T:System.Windows.Forms.PaintEventArgs"/> that contains the event data.</param>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            drawGrid(e.Graphics);
        }

        private void ageLimitText_TextChanged(object sender, EventArgs e)
        {
            setAgeLimit();
        }

        private void frameTimer_Tick(object sender, EventArgs e)
        {
            _generationCount++;
            _grid.NextGeneration();
            generationText.Text = _generationCount.ToString();
            this.Invalidate();
        }

        private void generationsPerSecond_ValueChanged(object sender, EventArgs e)
        {
            setGenerationsPerSecond();
        }

        private void resetButton_Click(object sender, EventArgs e)
        {
            _grid.Reset();
            _generationCount = 0;
        }

        #endregion


        #region Private Methods
        private void checkForDeadGrid()
        {
            // every 100 generations check for a dead grid
            if (_generationCount % 100 == 0)
            {
                if (_grid.NumberOfLivingCells == 0)
                {
                    _grid.Reset();
                }
            }
        }

        private Brush chooseCellColor(Cell aCell)
        {
            // This is fairly hard coded but good enough
            // for my demonstration purposes.
            Brush result = Brushes.White;
            if (aCell.Age > 0)
            {
                if (aCell.Age >= _ageLimit)
                {
                    result = Brushes.LightGreen;
                }
                else if (aCell.Age > AdultAge)
                {
                    result = Brushes.LightSteelBlue;
                }
                else if (aCell.Age > AdolescentAge)
                {
                    result = Brushes.LightBlue;
                }
                else
                {
                    result = Brushes.LightSkyBlue;
                }
            }
            return result;
        }

        private void drawGrid(Graphics surface)
        {

            checkForDeadGrid();

            Enumerable
                .Range(0, GridHeight * GridWidth)
                .Each(position => drawCell(position, surface));

        }

        private void drawCell(int position, Graphics surface)
        {
            int margin = CellDim;

            int row = position / GridWidth;
            int col = position % GridWidth;

            Cell aCell = _grid[row, col];
            float x = margin + CellDim * col;
            float y = margin + CellDim * row;
            surface.FillEllipse(
                chooseCellColor(aCell),
                x,
                y,
                CellDim,
                CellDim);
        }


        private void setAgeLimit()
        {
            int tmp = 0;
            if (int.TryParse(ageLimitText.Text, out tmp))
            {
                if (tmp.IsOutOfRange(3, 1000))
                {
                    invalidAgeError.SetError(ageLimitText, "The age limit must be between 3 and 1000");
                }
                else
                {
                    invalidAgeError.Clear();
                    _ageLimit = tmp;
                    _grid.AgeLimit = _ageLimit;
                }
            }
        }

        private void setGenerationsPerSecond()
        {
            frameTimer.Enabled = false;
            if (generationsPerSecond.Value > 0)
            {
                frameTimer.Interval =
                    (int)(1 / (double)generationsPerSecond.Value * 1000);
                frameTimer.Enabled = true;
            }
        }
        #endregion

    }
}

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
United States United States
Jeff Kwak (a.k.a., FutureTurnip) is an open minded software developer/architect on top of the .net stack. He's coded in everything from 8-bit assembly language to C#. Currently, he's into big architecture, organizing software teams/process, emerging web technologies (like Silverlight and MS MVC), languages, ... all things software and related to software.

Comments and Discussions