1. 如果一个细胞只有0或1个邻居,它将因为孤独而死;
2. 如果一个细胞有4到8个邻居,它将因为拥挤而死;
3. 如果一个细胞恰有2或者3个邻居,它将继续生存下去;
4. 如果一个空格子恰有3个邻居,将“生”出一个新细胞;
5. 其他的空格子继续维持原状。
提示:
细胞,可以用对象来存储, 属性是: 编号随机不重复,死,活,邻居数量,邻居集合
( 用链表来存放其他细胞集合) 开始输入随机个细胞和邻居随机组合,然后每1秒一个周期,演示发展结果.
------解决方案--------------------
- C# code
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Drawing.Drawing2D; namespace ArtificialLife { public partial class FormMain : Form { const int MAX_X = 50; const int MAX_Y = 50; int[,] Cells = new int[MAX_X, MAX_Y]; int[,] Temp = new int[MAX_X, MAX_Y]; PaintEventArgs param; Random rand = new Random((int)DateTime.Now.Ticks); System.Windows.Forms.Timer updateTimer; System.Windows.Forms.Timer drawTimer; public FormMain() { InitializeComponent(); param = new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle); DoubleBuffered = true; for (var x = 0; x < MAX_X; x++) for (var y = 0; y < MAX_Y; y++) { Cells[x, y] = rand.Next(6) % 2 == 0 ? 1 : 0; Temp[x, y] = Cells[x, y]; } updateTimer = new Timer(); updateTimer.Tick += new EventHandler(updateTimer_Tick); updateTimer.Interval = 1000; updateTimer.Start(); drawTimer = new Timer(); drawTimer.Tick += new EventHandler(drawTimer_Tick); drawTimer.Interval = 100; drawTimer.Start(); } void drawTimer_Tick(object sender, EventArgs e) { Invalidate(); } void updateTimer_Tick(object sender, EventArgs e) { DoCalc(); } private void DoCalc() { /* 1. 如果一个细胞只有0或1个邻居,它将因为孤独而死; 2. 如果一个细胞有4到8个邻居,它将因为拥挤而死; 3. 如果一个细胞恰有2或者3个邻居,它将继续生存下去; 4. 如果一个空格子恰有3个邻居,将“生”出一个新细胞; */ int nCount = 0;//用以统计每个细胞周围的细胞个数 for (var x = 0; x < MAX_X; x++) for (var y = 0; y < MAX_Y; y++) { //每个细胞的前后左右的 nCount = 0; if (x > 0) nCount += Cells[x - 1, y]; if (y > 0) nCount += Cells[x, y - 1]; if (x < MAX_X - 1) nCount += Cells[x + 1, y]; if (y < MAX_Y - 1) nCount += Cells[x, y + 1]; if (nCount < 2 || nCount > 3) Temp[x, y] = 0; if (nCount == 3) Temp[x, y] = 1; } for (var x = 0; x < MAX_X; x++) for (var y = 0; y < MAX_Y; y++) Cells[x, y] = Temp[x, y]; } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); DoDraw(param); } private void DoDraw(PaintEventArgs e) { e.Graphics.FillRectangle(Brushes.Black, e.ClipRectangle); Rectangle cellRect = new Rectangle(); cellRect.X = 0; cellRect.Y = 0; cellRect.Width = e.ClipRectangle.Width / MAX_X; cellRect.Height = e.ClipRectangle.Height / MAX_Y; for (var x = 0; x < MAX_X; x++) for (var y = 0; y < MAX_Y; y++) { cellRect.X = cellRect.Width * x + cellRect.Width; cellRect.Y = cellRect.Height * y + cellRect.Height; e.Graphics.FillRectangle(new LinearGradientBrush(cellRect, (Cells[x, y] == 1 ? Color.Red : Color.Green), Color.White, 0f), cellRect); } } } }