|
//
// 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.
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.