zoukankan      html  css  js  c++  java
  • 模拟一下细胞的繁殖

    原贴地址 
    原帖:

    1. 如果一个细胞只有0或1个邻居,它将因为孤独而死;
    2. 如果一个细胞有4到8个邻居,它将因为拥挤而死;
    3. 如果一个细胞恰有2或者3个邻居,它将继续生存下去;
    4. 如果一个空格子恰有3个邻居,将“生”出一个新细胞;
    5. 其他的空格子继续维持原状。

    提示:

    细胞,可以用对象来存储, 属性是: 编号随机不重复,死,活,邻居数量,邻居集合
    ( 用链表来存放其他细胞集合) 开始输入随机个细胞和邻居随机组合,然后每1秒一个周期,演示发展结果

    我的实现:


    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(00, 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] * 30255), 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 项目工程)

     ArtificialLife.rar

    出处:http://www.cnblogs.com/Chinasf/archive/2008/11/26/1341399.html

  • 相关阅读:
    批量修改Linux文件夹下所有文件大小写
    如何使用malloc申请一个二位数组
    CenOS 配置C/C++语言
    C++类定义,.h文件与.cpp文件之间的关系以及条件编译
    Error while building/deploying project...When executing step "qmake"——Qt Creator快速排错
    Hello World!
    HDU1262:寻找素数对
    NOIP1998复赛:2的幂次方表示
    HDU1002 : A + B Problem II
    Open Judge2748:全排列
  • 原文地址:https://www.cnblogs.com/mq0036/p/7228028.html
Copyright © 2011-2022 走看看