1. 如果一个细胞只有0或1个邻居,它将因为孤独而死;
2. 如果一个细胞有4到8个邻居,它将因为拥挤而死;
3. 如果一个细胞恰有2或者3个邻居,它将继续生存下去;
4. 如果一个空格子恰有3个邻居,将“生”出一个新细胞;
5. 其他的空格子继续维持原状。
提示:
细胞,可以用对象来存储, 属性是: 编号随机不重复,死,活,邻居数量,邻居集合
( 用链表来存放其他细胞集合) 开始输入随机个细胞和邻居随机组合,然后每1秒一个周期,演示发展结果.
0<=X<=1死亡
X=2生存
X=3繁殖1个
4<=X<=8死亡
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
namespace ArtificialLife
{
public partial class FormMain : Form
{
const int MAX_X = 50;
const int MAX_Y = 50;
int[,] Cells = new int[MAX_X, MAX_Y];
int[,] Temp = new int[MAX_X, MAX_Y];
PaintEventArgs param;
Random rand = new Random((int)DateTime.Now.Ticks);
System.Windows.Forms.Timer updateTimer;
System.Windows.Forms.Timer drawTimer;
public FormMain()
{
InitializeComponent();
param = new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle);
DoubleBuffered = true;
for (var x = 0; x < MAX_X; x++)
for (var y = 0; y < MAX_Y; y++)
{
Cells[x, y] = rand.Next(6) % 2 == 0 ? 1 : 0;
Temp[x, y] = Cells[x, y];
}
updateTimer = new Timer();
updateTimer.Tick += new EventHandler(updateTimer_Tick);
updateTimer.Interval = 1000;
updateTimer.Start();
drawTimer = new Timer();
drawTimer.Tick += new EventHandler(drawTimer_Tick);
drawTimer.Interval = 100;
drawTimer.Start();
}
void drawTimer_Tick(object sender, EventArgs e)
{
Invalidate();
}
void updateTimer_Tick(object sender, EventArgs e)
{
DoCalc();
}
private void DoCalc()
{
/*
1. 如果一个细胞只有0或1个邻居,它将因为孤独而死;
2. 如果一个细胞有4到8个邻居,它将因为拥挤而死;
3. 如果一个细胞恰有2或者3个邻居,它将继续生存下去;
4. 如果一个空格子恰有3个邻居,将“生”出一个新细胞;
*/
int nCount = 0;//用以统计每个细胞周围的细胞个数
for (var x = 0; x < MAX_X; x++)
for (var y = 0; y < MAX_Y; y++)
{
//每个细胞的前后左右的
nCount = 0;
if (x > 0) nCount += Cells[x - 1, y];
if (y > 0) nCount += Cells[x, y - 1];
if (x < MAX_X - 1) nCount += Cells[x + 1, y];
if (y < MAX_Y - 1) nCount += Cells[x, y + 1];
if (nCount < 2 || nCount > 3)
Temp[x, y] = 0;
if (nCount == 3)
Temp[x, y] = 1;
}
for (var x = 0; x < MAX_X; x++)
for (var y = 0; y < MAX_Y; y++)
Cells[x, y] = Temp[x, y];
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
DoDraw(param);
}
private void DoDraw(PaintEventArgs e)
{
e.Graphics.FillRectangle(Brushes.Black, e.ClipRectangle);
Rectangle cellRect = new Rectangle();
cellRect.X = 0;
cellRect.Y = 0;
cellRect.Width = e.ClipRectangle.Width / MAX_X;
cellRect.Height = e.ClipRectangle.Height / MAX_Y;
for (var x = 0; x < MAX_X; x++)
for (var y = 0; y < MAX_Y; y++)
{
cellRect.X = cellRect.Width * x + cellRect.Width;
cellRect.Y = cellRect.Height * y + cellRect.Height;
e.Graphics.FillRectangle(new LinearGradientBrush(cellRect, (Cells[x, y] == 1 ? Color.Red : Color.Green), Color.White, 0f), cellRect);
}
}
}
}