模拟一下细胞的繁殖
Posted jack_孟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模拟一下细胞的繁殖相关的知识,希望对你有一定的参考价值。
原贴地址
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();
}
}
}
我的实现:
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();
}
}
}
只所以用数组,是为了简单和执行效率;运行效果如图:
局部放大效果
源码(visual studio 2008 项目工程)
出处:http://www.cnblogs.com/Chinasf/archive/2008/11/26/1341399.html
以上是关于模拟一下细胞的繁殖的主要内容,如果未能解决你的问题,请参考以下文章