博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
模拟一下细胞的繁殖(CSDN号召帖)
阅读量:6207 次
发布时间:2019-06-21

本文共 3218 字,大约阅读时间需要 10 分钟。

原帖:

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

2. 如果一个细胞有4到8个邻居,它将因为拥挤而死;
3. 如果一个细胞恰有2或者3个邻居,它将继续生存下去;
4. 如果一个空格子恰有3个邻居,将“生”出一个新细胞;
5. 其他的空格子继续维持原状。
提示:
细胞,可以用对象来存储, 属性是: 编号随机不重复,死,活,邻居数量,邻居集合
( 用链表来存放其他细胞集合) 开始输入随机个细胞和邻居随机组合,然后每1秒一个周期,演示发展结果

我的实现:

ContractedBlock.gif
ExpandedBlockStart.gif
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();
}
}
}

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

局部放大效果

源码(visual studio 2008 项目工程)

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

你可能感兴趣的文章
10 进制转 2 进制、16 进制
查看>>
Wordpress中显示页面当前位置
查看>>
HTML比较常用的标签
查看>>
【Spring】使用Spring和AMQP发送接收消息(下)
查看>>
SQL注入
查看>>
iOS UITableView 移除单元格选中时的高亮状态
查看>>
java中单例模式的3种实现
查看>>
openssl创建私有ca
查看>>
为什么我从 Git Flow 开发模式切换到了 Trunk Based 开发模式?
查看>>
mysql 数据库授权(给某个用户授权某个数据库)
查看>>
使用curl登陆上网账号
查看>>
将博客搬至CSDN
查看>>
Java技术中的三大特性
查看>>
Cloud Native 介绍
查看>>
linux下添加用户并赋予root权限
查看>>
linux 内核配置过程中遇到的问题
查看>>
linux程序莫名异常怎么查
查看>>
ping得通外网,上得了QQ,游戏,却打不开网页。
查看>>
genymotion 极速模拟器
查看>>
我的友情链接
查看>>