1. 如果一个细胞只有0或1个邻居,它将因为孤独而死;
2. 如果一个细胞有4到8个邻居,它将因为拥挤而死;
3. 如果一个细胞恰有2或者3个邻居,它将继续生存下去;
4. 如果一个空格子恰有3个邻居,将“生”出一个新细胞;
5. 其他的空格子继续维持原状。
Code using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
namespace ArtificialLife
{
public partial class FormMain : Form
{
int[,] Cells;
// 状态(1生,0死) int[,] CellCounts;
// 周边细胞数量(最大8个) int[,] Temp;
// 缓冲(切换生死状态) Bitmap memBitmap;
// 画布 Random rand =
new Random((
int)DateTime.Now.Ticks);
System.Windows.Forms.Timer updateTimer;
public FormMain()
{
InitializeComponent();
// 宽高 Width =
320;
Height =
240;
memBitmap =
new Bitmap(Width, Height);
Cells =
new int[memBitmap.Width, memBitmap.Height];
CellCounts =
new int[memBitmap.Width, memBitmap.Height];
// 初始化,随机决定 for (var x =
0; x < memBitmap.Width; x++)
for (var y =
0; y < memBitmap.Height; y++)
Cells[x, y] = rand.Next(memBitmap.Width) %
3 ==
0 ?
1 :
0;
Temp = (
int[,])Cells.Clone();
updateTimer =
new Timer();
updateTimer.Tick +=
new EventHandler(updateTimer_Tick);
updateTimer.Interval =
1000;
updateTimer.Start();
}
void updateTimer_Tick(
object sender, EventArgs e)
{
DoCalc();
DoDraw();
}
private void DoCalc()
{
/* 1. 如果一个细胞只有0或1个邻居,它将因为孤独而死; 2. 如果一个细胞有4到8个邻居,它将因为拥挤而死; 3. 如果一个细胞恰有2或者3个邻居,它将继续生存下去; 4. 如果一个空格子恰有3个邻居,将“生”出一个新细胞; */ int nCount =
0;
// 用以统计每个细胞周围的细胞个数 for (var x =
0; x < memBitmap.Width; x++)
for (var y =
0; y < memBitmap.Height; y++)
{
// 每个细胞的前后左右八个方向的 nCount =
0;
if (x >
0) nCount += Cells[x -
1, y];
if (x >
0 && y >
0) nCount += Cells[x -
1, y -
1];
if (x < memBitmap.Width -
1 && y < memBitmap.Height -
1) nCount += Cells[x +
1, y +
1];
if (y >
0) nCount += Cells[x, y -
1];
if (y >
0 && x < memBitmap.Width -
1) nCount += Cells[x +
1, y -
1];
if (x >
0 && y < memBitmap.Height -
1) nCount += Cells[x -
1, y +
1];
if (x < memBitmap.Width -
1) nCount += Cells[x +
1, y];
if (y < memBitmap.Height -
1) nCount += Cells[x, y +
1];
CellCounts[x, y] = nCount;
// 放入计数器 if (nCount <
2 || nCount >
3)
// 决定生死 Temp[x, y] =
0;
if (nCount ==
3)
Temp[x, y] =
1;
}
for (var x =
0; x < memBitmap.Width; x++)
for (var y =
0; y < memBitmap.Height; y++)
Cells[x, y] = Temp[x, y];
}
protected override void OnPaint(PaintEventArgs e)
{
DoDraw();
}
private void DoDraw()
{
// 开启编译选项 unsafe+ BitmapData bmData = memBitmap.LockBits(
new Rectangle(
0,
0, memBitmap.Width, memBitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bmData.Stride;
IntPtr Scan0 = bmData.Scan0;
unsafe {
byte* p = (
byte*)(
void*)Scan0;
int nOffset = stride - memBitmap.Width *
3;
for (
int y =
0; y < memBitmap.Height; ++y)
{
for (
int x =
0; x < memBitmap.Width; ++x)
{
// blue = p[0]; // green = p[1]; // red = p[2]; // 当周边细胞数越多则颜色越亮 p[
0] = p[
1] = p[
2] = (
byte)Math.Max(Math.Min(CellCounts[x, y] *
30,
255),
0);
if (Cells[x, y] ==
1) p[
0] =
255;
// 生存的细胞 p +=
3;
}
p += nOffset;
}
}
memBitmap.UnlockBits(bmData);
Graphics g =
this.CreateGraphics();
g.DrawImage(memBitmap, ClientRectangle);
g.Dispose();
}
}
}