细胞自动机

今天发奇想,想试试康威生命游戏。规则非常简单:

每个细胞有两种状态 - 存活或死亡,每个细胞与以自身为中心的周围八格细胞产生互动。(如图,黑色为存活,白色为死亡)
当前细胞为存活状态时,当周围低于2个(不包含2个)存活细胞时, 该细胞变成死亡状态。(模拟生命数量稀少)
当前细胞为存活状态时,当周围有2个或3个存活细胞时, 该细胞保持原样。
当前细胞为存活状态时,当周围有3个以上的存活细胞时,该细胞变成死亡状态。(模拟生命数量过多)
当前细胞为死亡状态时,当周围有3个存活细胞时,该细胞变成存活状态。 (模拟繁殖)

用C#实现起来也是非常顺滑,只在那个嵌套for循环的地方为了避免O(n*8)复杂度过大做了一个catch处理。一个winform就可以了:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Threading.Tasks;
  9 using System.Windows.Forms;
 10
 11 namespace Cell
 12 {
 13     public partial class Form1 : Form
 14     {
 15         public Form1()
 16         {
 17             InitializeComponent();
 18             this.Width = m_kXCount * m_kGridSize + m_kGridSize;
 19             this.Height = m_kYCount * m_kGridSize + m_kGridSize;
 20             DoubleBuffered = true;
 21             StartPosition = FormStartPosition.CenterScreen;
 22             BackColor = Color.White;
 23             initGrids();
 24             initTimer();
 25         }
 26
 27         //网格对象
 28         class Grid
 29         {
 30             public Rectangle rect;
 31             public bool alive;
 32             public bool next;
 33             public Point pos;//topleft
 34         }
 35
 36         const int m_kGridSize = 20;
 37         const int m_kXCount = 100;
 38         const int m_kYCount = 60;
 39         const int m_kAntCount = 1;
 40
 41         Grid[,] m_allGrids = new Grid[m_kXCount, m_kYCount];
 42         void initGrids()
 43         {
 44             for (int x = 0; x < m_kXCount; x++)
 45             {
 46                 for (int y = 0; y < m_kYCount; y++)
 47                 {
 48                     m_allGrids[x, y] = new Grid
 49                     {
 50                         alive = false,
 51                         pos = new Point(x, y),
 52                         rect = new Rectangle(x * m_kGridSize, y * m_kGridSize, m_kGridSize, m_kGridSize),
 53                     };
 54                 }
 55             }
 56         }
 57
 58         //细胞
 59         List<Grid> m_allCells = new List<Grid>();
 60
 61         //定时器
 62         Timer m_timer = new Timer();
 63         void initTimer()
 64         {
 65             m_timer.Interval = 100;//蚂蚁移动速度
 66             m_timer.Tick += onTimerTick;
 67             m_timer.Enabled = false;
 68         }
 69
 70         Size[] m_8offset = new Size[8]
 71         {
 72             new Size(-1,-1),
 73             new Size(0,-1),
 74             new Size(1,-1),
 75             new Size(-1,0),
 76             new Size(1,0),
 77             new Size(-1,1),
 78             new Size(0,1),
 79             new Size(1,1)
 80         };
 81
 82         private void onTimerTick(object sender, EventArgs e)
 83         {
 84             //每个细胞有两种状态 - 存活或死亡,每个细胞与以自身为中心的周围八格细胞产生互动。(如图,黑色为存活,白色为死亡)
 85             //当前细胞为存活状态时,当周围低于2个(不包含2个)存活细胞时, 该细胞变成死亡状态。(模拟生命数量稀少)
 86             //当前细胞为存活状态时,当周围有2个或3个存活细胞时, 该细胞保持原样。
 87             //当前细胞为存活状态时,当周围有3个以上的存活细胞时,该细胞变成死亡状态。(模拟生命数量过多)
 88             //当前细胞为死亡状态时,当周围有3个存活细胞时,该细胞变成存活状态。 (模拟繁殖)
 89
 90             List<Grid> newCells = new List<Grid>();
 91             List<Grid> checkedCell = new List<Grid>();
 92             foreach(var cell in m_allCells)
 93             {
 94                 int cnt = 0;
 95                 foreach(var s in m_8offset)
 96                 {
 97                     var p = cell.pos + s;
 98                     if (p.X < 0) p.X = m_kXCount - 1;
 99                     if (p.Y < 0) p.Y = m_kYCount - 1;
100                     if (p.X == m_kXCount) p.X = 0;
101                     if (p.Y == m_kYCount) p.Y = 0;
102
103                     var _cell = m_allGrids[p.X, p.Y];
104                     if (_cell.alive)
105                     {
106                         cnt++;
107                     }
108                     else
109                     {
110                         if (checkedCell.Contains(_cell))
111                             continue;
112
113                         checkedCell.Add(_cell);
114
115                         //死亡状态的细胞
116                         int _cnt = 0;
117                         foreach(var _s in m_8offset)
118                         {
119                             var _p = _cell.pos + _s;
120                             if (_p.X < 0) _p.X = m_kXCount - 1;
121                             if (_p.Y < 0) _p.Y = m_kYCount - 1;
122                             if (_p.X == m_kXCount) _p.X = 0;
123                             if (_p.Y == m_kYCount) _p.Y = 0;
124
125                             var __cell = m_allGrids[_p.X, _p.Y];
126                             if (__cell.alive)
127                             {
128                                 _cnt++;
129                             }
130                         }
131                         if (_cnt == 3)
132                         {
133                             _cell.next = true;
134                             newCells.Add(_cell);
135                         }
136                     }
137                 }
138                 if (cnt < 2 || cnt > 3)
139                     cell.next = false;
140                 else
141                     cell.next = true;
142             }
143             foreach(var cell in m_allCells)
144             {
145                 cell.alive = cell.next;
146             }
147             foreach(var cell in newCells)
148             {
149                 cell.alive = cell.next;
150             }
151             m_allCells.RemoveAll(c => !c.alive);
152             m_allCells.AddRange(newCells);
153             Invalidate();
154         }
155
156         //鼠标选择活细胞
157         protected override void OnMouseClick(MouseEventArgs e)
158         {
159             base.OnMouseClick(e);
160             if (m_isRunning) return;
161             //计算位置
162             int x = e.X / m_kGridSize;
163             int y = e.Y / m_kGridSize;
164             var grid = m_allGrids[x, y];
165             grid.alive = true;
166             m_allCells.Add(grid);
167
168             Invalidate();
169         }
170
171         bool m_isRunning = false;
172         //键盘控制启动暂停
173         protected override void OnKeyDown(KeyEventArgs e)
174         {
175             base.OnKeyDown(e);
176             if (e.KeyCode == Keys.Space)
177             {
178                 m_isRunning = !m_isRunning;
179                 m_timer.Enabled = !m_timer.Enabled;
180             }
181         }
182
183         Pen m_gridPen = new Pen(Color.Black, 1);
184         protected override void OnPaint(PaintEventArgs e)
185         {
186             base.OnPaint(e);
187             var g = e.Graphics;
188
189             //绘制网格
190             for (int x = 0; x < m_kXCount; x++)
191             {
192                 for (int y = 0; y < m_kYCount; y++)
193                 {
194                     var grid = m_allGrids[x, y];
195                     if (grid.alive)
196                     {
197                         g.FillRectangle(Brushes.Brown, grid.rect);
198                     }
199                     g.DrawRectangle(m_gridPen, grid.rect);
200                 }
201             }
202         }
203
204     }
205 }

定时器默认是关闭的,用鼠标点选一个初始形状作为种子,按空格键开始/暂停。我尝试了一个3*3的十字,每次死循环之后按空格暂停,在中间继续画十字,可以得到非常有趣的图案。尽管尝试吧。。

时间: 2024-10-11 11:46:20

细胞自动机的相关文章

中国MOOC_面向对象程序设计——Java语言_期末考试编程题_1细胞自动机

期末考试编程题 返回 这是期末考试的编程题 温馨提示: 1.本次考试属于Online Judge题目,提交后由系统即时判分. 2.学生可以在考试截止时间之前提交答案,系统将取其中的最高分作为最终成绩. 1 细胞自动机(30分) 题目内容: 这是细胞自动机的非图形版本.细胞自动机是指在一个二维网格内,每一个网格是一个细胞.每个细胞有活和死两种状态. 初始时刻,有些细胞是活的,有些细胞是死的.自动机的每一步,根据每个细胞周围8个格子内的其他细胞的生存情况决定这个细胞下一步是否存活.具体的规则如下:

生命游戏&amp;一维细胞自动机 笔记

de 生命游戏是一种简单的聚合模型,展示了事物是如何聚合的,是自动机(CA)模型的一种.由剑桥大学约翰康威发明,其规则为: 1. 每个细胞拥有八个邻居,细胞状态只有存活(黑)和死亡(白)两种: 2.处于死亡状态的细胞可以在有三个存活邻居的情况下复活: 3.存活状态的细胞在相邻有2个一下或三个以上存活细胞的情况下会死去,2-3个相邻细胞存活时会继续存活: 从而产生了信号灯.闪光灯.滑翔机.警示灯等经典的变换. 遵循简单规则的简单图像聚合一起可以形成复杂图像,甚至如活物一般能进行空间平移(自组织模型

细胞自动机【转】

另类科学的核心技术是细胞自动机. 乌尔姆(Stanislaw M. Ulam)和冯·诺伊曼(John von Neumann)为了研究机器人自我复制的可能性,在上个世纪50年代提出一种叫做细胞自动机(Cellular Automaton)的离散型动力系统(Discrete Dynamical Systems).细胞自动机是研究复杂系统行为的理论框架之一,也是人工智能在这个领域的雏形之一. 在一个平面上(这里以平面为例,但不限于二维平面)纵横相交的多条直线构成了许多网格,每一个网格被看作一个细胞.

混沌,细胞自动机与生命游戏

混沌,细胞自动机与生命游戏 1.康威生命游戏的规则 生命游戏中,对于任意细胞,规则如下:每个细胞有两种状态-存活或死亡,每个细胞与以自身为中心的周围八格细胞产生互动. Ⅰ. A live square with two or three live neighbors survives (survival).Ⅱ. A dead square with exactly three live neighbors becomes a live cell (birth).Ⅲ. In all other c

CellularAutomation(细胞自动机)

CellularAutomation(细胞自动机) 细胞自动机(英语:Cellular automaton),又称格状自动机.元胞自动机,是一种离散模型,在可算性理论.数学及理论生物学都有相关研究.它是由无限个有规律.坚硬的方格组成,每格均处于一种有限状态.整个格网可以是任何有限维的.同时也是离散的.每格于t时的态由 t-1时的一集有限格(这集叫那格的邻域)的态决定. 每一格的"邻居"都是已被固定的.(一格可以是自己的邻居.)每次演进时,每格均遵从同一规矩一齐演进. 就形式而言,细胞自

生命游戏和细胞自动机的学习笔记

Last updated: 23rd. July, 2012 野比 2012 版权所有 (本文为学习笔记,知识浅薄.我会将学习中的实验记录和心得记录在此.) 欢迎对这方面感兴趣的爱好者一起研究. 寻求技术指导. 联系QQ:1429013154 我一直对人工智能很感兴趣,苦于数学基础太差,很多理论方面的东西理解起来十分吃力.最近又翻出以前的学习目标:人工生命.名字挺悬乎,其实很多人都曾和它有过交集,就算没有用到它进化出的好物种--智能机器人,至少也应该听过甚至中过它进化的恶劣物种--蠕虫病毒. 说

LA 3704细胞自动机——循环矩阵&amp;&amp;矩阵快速幂

题目 一个细胞自动机包含 $n$ 个格子,每个格子的取值为 $0 \sim m-1$.给定距离 $d$,则每次操作是将每个格子的值变为到它的距离不超过 $d$ 的所有格子的在操作之前的值的和除以 $m$ 的余数.给出 $n, m, d, k$ 和自动机各个格子的初始值.你的任务是计算 $k$ 次操作以后各格子的值.($1 \leq n\leq 500, 1 \leq m\leq 10^6, 0 \leq d\leq n/2, 1\leq k\leq 10^7$). 分析 如果我们把 $t$ 次操

C语言 细胞自动机(生命游戏)

1 #include<stdio.h> 2 #include<stdlib.h> 3 #include <windows.h> 4 5 #define ROWS 60 6 #define COLS 60 7 8 int board[ROWS][COLS]; 9 int temp[ROWS][COLS]; 10 11 int system(const char *string); 12 void randomize_board(); 13 void show_board(

【转载】计算机图形学框架

原文: 计算机图形学框架 应用 基本图形生成算法 图元光栅化标准 直线要直 图元终点要准 图元生成的亮度.色泽粗细要均匀 快速计算 直线光栅化算法 逐点比较法 数值微分法 中点Bresenham算法 圆的光栅化算法 简单方程产生圆弧 Bresenham算法产生圆弧 多边形填充 扫描线填充 宽图元 复制像素画宽图元 移动画笔画宽图元 3D数学基础 坐标系 向量 矩阵 空间集合运算 集合形体的表达 几何体之间的关系 图形变换 二维及三维图形几何变换 二维图形几何变换 平移变换 比例变换 旋转变换 错