天天看点

模拟一下细胞的繁殖(CSDN号召帖)

1. 如果一个细胞只有0或1个邻居,它将因为孤独而死;

2. 如果一个细胞有4到8个邻居,它将因为拥挤而死;

3. 如果一个细胞恰有2或者3个邻居,它将继续生存下去;

4. 如果一个空格子恰有3个邻居,将“生”出一个新细胞;

5. 其他的空格子继续维持原状。

提示:

细胞,可以用对象来存储, 属性是: 编号随机不重复,死,活,邻居数量,邻居集合

( 用链表来存放其他细胞集合) 开始输入随机个细胞和邻居随机组合,然后每1秒一个周期,演示发展结果

我的实现:

模拟一下细胞的繁殖(CSDN号召帖)
模拟一下细胞的繁殖(CSDN号召帖)

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()

/*

*/

int nCount = 0;//用以统计每个细胞周围的细胞个数

//每个细胞的前后左右八个方向的

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;

Cells[x, y] = Temp[x, y];

protected override void OnPaint(PaintEventArgs e)

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();

只所以用数组,是为了简单和执行效率;运行效果如图:

局部放大效果

源码(visual studio 2008 项目工程)

<a href="http://files.cnblogs.com/Chinasf/ArtificialLife.rar">/Files/Chinasf/ArtificialLife.rar</a>

本文转自suifei博客园博客,原文链接:http://www.cnblogs.com/Chinasf/archive/2008/11/26/1341399.html,如需转载请自行联系原作者

继续阅读