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