CellularAutomation(细胞自动机)

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

就形式而言,细胞自动机有三个特征:

平行计算(parallel computation):每一个细胞个体都同时同步的改变
局部的(local):细胞的状态变化只受周遭细胞的影响。
一致性的(homogeneous):所有细胞均受同样的规则所支配

生命游戏

生命游戏中,对于任意细胞,规则如下:
每个细胞有两种状态-存活或死亡,每个细胞与以自身为中心的周围八格细胞产生互动。(如图,黑色为存活,白色为死亡)

当前细胞为存活状态时,当周围低于2个(不包含2个)存活细胞时, 该细胞变成死亡状态。(模拟生命数量稀少)
当前细胞为存活状态时,当周围有2个或3个存活细胞时, 该细胞保持原样。
当前细胞为存活状态时,当周围有3个以上的存活细胞时,该细胞变成死亡状态。(模拟生命数量过多)
当前细胞为死亡状态时,当周围有3个存活细胞时,该细胞变成存活状态。 (模拟繁殖)
可以把最初的细胞结构定义为种子,当所有在种子中的细胞同时被以上规则处理后, 可以得到第一代细胞图。按规则继续处理当前的细胞图,可以得到下一代的细胞图,周而复始。

在这个游戏中,还可以设定一些更加复杂的规则,例如当前方格的状况不仅由父一代决定,而且还考虑祖父一代的情况。玩家还可以作为这个世界的“上帝”,随意设定某个方格细胞的死活,以观察对世界的影响。

在游戏的进行中,杂乱无序的细胞会逐渐演化出各种精致、有形的结构;这些结构往往有很好的对称性,而且每一代都在变化形状。一些形状已经锁定,不会逐代变化。有时,一些已经成形的结构会因为一些无序细胞的“入侵”而被破坏。但是形状和秩序经常能从杂乱中产生出来。

有个可以直接玩这个游戏的链接 - Game of Life

下面用Unity自己写一下。

using UnityEngine;
using System.Collections;public enum State{Died,Living
};public class Cell
{public State currentState;
}public class Earth : MonoBehaviour {public int width;public int height;public string seed;public bool useRandomSeed;public float updateInterval = 1.0f;float refreshTime = -1f;[Range(0, 100)]public int randomFillPercent;Cell[,] map;Cell[,] mapTmp;// Use this for initializationvoid Start () {map = new Cell[width,height];mapTmp = new Cell[width, height];for (int i = 0; i < width; i++)for (int j = 0; j < height; j++){map[i,j] = new Cell();map[i, j].currentState = State.Died;mapTmp[i, j] = new Cell();mapTmp[i, j].currentState = State.Died;}initEarth();}// Update is called once per framevoid Update () {if(Time.time - refreshTime > updateInterval){UpdateEarth();refreshTime = Time.time;}}void UpdateEarth(){for (int x = 0; x < width; x++){for (int y = 0; y < height; y++){mapTmp[x, y].currentState = map[x, y].currentState;int neighbourLiveCells = GetSurroundingLiveCells(x, y);if (map[x, y].currentState == State.Died && neighbourLiveCells == 3){mapTmp[x, y].currentState = State.Living;}if (map[x, y].currentState == State.Living){if(neighbourLiveCells < 2){mapTmp[x, y].currentState = State.Died;}else if( neighbourLiveCells > 3){mapTmp[x, y].currentState = State.Died;}else{mapTmp[x, y].currentState = State.Living;}}}}for (int x = 0; x < width; x++)for (int y = 0; y < height; y++){map[x, y].currentState = mapTmp[x, y].currentState;}}int GetSurroundingLiveCells(int gridX, int gridY){int count = 0;for (int neighbourX = gridX - 1; neighbourX <= gridX + 1; neighbourX++){for (int neighbourY = gridY - 1; neighbourY <= gridY + 1; neighbourY++){if (neighbourX >= 0 && neighbourX < width && neighbourY >= 0 && neighbourY < height){if (neighbourX != gridX || neighbourY != gridY){count += map[neighbourX, neighbourY].currentState == State.Living? 1 : 0;}}}}return count;}void initEarth(){if (useRandomSeed){seed = Time.time.ToString();}System.Random pseudoRandom = new System.Random(seed.GetHashCode());for (int x = 0; x < width; x++){for (int y = 0; y < height; y++){if (x == 0 || x == width - 1 || y == 0 || y == height - 1){map[x, y].currentState = State.Living;}else{map[x, y].currentState = (pseudoRandom.Next(0, 100) < randomFillPercent) ? State.Living : State.Died;}}}}void OnDrawGizmos(){if (map != null){for (int x = 0; x < width; x++){for (int y = 0; y < height; y++){if (map[x, y] != null){Gizmos.color = (map[x, y].currentState == State.Living) ? Color.black : Color.white;Vector3 pos = new Vector3(-width / 2 + x + .5f, 0, -height / 2 + y + .5f);Gizmos.DrawCube(pos, Vector3.one);}}}}}
}

代码其实就是按照前面算法的描述实现出来。

初始的细胞分布用了Unity自带的随机来生成,然后在OnDrawGizmos函数中绘制出来。运行起来是这样的:

可以将初始状态设置为经典的glider,修改 initEarth() 函数就可以了。

//Glider
map[20, 20].currentState = State.Living;
map[20, 21].currentState = State.Living;
map[20, 22].currentState = State.Living;
map[21, 22].currentState = State.Living;
map[22, 21].currentState = State.Living;

程序生成地形

程序生成有很多中方法,利用细胞自动机主要用生成地牢等类似的地形,常用于Roguelike类的游戏。主要的算法就是还是利用细胞生存的规则,比如现在规定只要细胞周围有四个以上的细胞,该细胞就存活,否则死去。

for (int x = 0; x < width; x++){for (int y = 0; y < height; y++){int neighbourWallTiles = GetSurroundingWallCount(x, y);if (neighbourWallTiles > 4)map[x, y] = 1;else if (neighbourWallTiles < 4)map[x, y] = 0;}}

不断迭代,就可以得到一张地图。当然首先还是要在画布上随机分布一些细胞。迭代5次,最终生成地图如下

    

代码清单

using UnityEngine;
using System.Collections;public class MapGenerator : MonoBehaviour {public int width;public int height;public string seed;public bool useRandomSeed;[Range(0, 100)]public int randomFillPercent;int[,] map;// Use this for initializationvoid Start () {GenerateMap();}// Update is called once per framevoid Update () {if (Input.GetMouseButtonDown(0)){GenerateMap();}}void GenerateMap(){map = new int[width, height];RandomFillMap();for (int i = 0; i < 5; i++){SmoothMap();}}void RandomFillMap(){if (useRandomSeed){seed = Time.time.ToString();}System.Random pseudoRandom = new System.Random(seed.GetHashCode());for (int x = 0; x < width; x++){for (int y = 0; y < height; y++){if (x == 0 || x == width - 1 || y == 0 || y == height - 1){map[x, y] = 1;}else{map[x, y] = (pseudoRandom.Next(0, 100) < randomFillPercent) ? 1 : 0;}}}}void SmoothMap(){for (int x = 0; x < width; x++){for (int y = 0; y < height; y++){int neighbourWallTiles = GetSurroundingWallCount(x, y);if (neighbourWallTiles > 4)map[x, y] = 1;else if (neighbourWallTiles < 4)map[x, y] = 0;}}}int GetSurroundingWallCount(int gridX, int gridY){int wallCount = 0;for (int neighbourX = gridX - 1; neighbourX <= gridX + 1; neighbourX++){for (int neighbourY = gridY - 1; neighbourY <= gridY + 1; neighbourY++){if (neighbourX >= 0 && neighbourX < width && neighbourY >= 0 && neighbourY < height){if (neighbourX != gridX || neighbourY != gridY){wallCount += map[neighbourX, neighbourY];}}else{wallCount++;}}}return wallCount;}void OnDrawGizmos(){if (map != null){for (int x = 0; x < width; x++){for (int y = 0; y < height; y++){Gizmos.color = (map[x, y] == 1) ? Color.black : Color.white;Vector3 pos = new Vector3(-width / 2 + x + .5f, 0, -height / 2 + y + .5f);Gizmos.DrawCube(pos, Vector3.one);}}}}
}

参考

细胞自动机wiki - https://zh.wikipedia.org/wiki/%E7%B4%B0%E8%83%9E%E8%87%AA%E5%8B%95%E6%A9%9F

Game of Life - http://www.bitstorm.org/gameoflife/

Procedural Cave Generation Project Icon - https://unity3d.com/learn/tutorials/projects/procedural-cave-generation-tutorial

CellularAutomation(细胞自动机)相关推荐

  1. 通过细胞自动机,AI在「我的世界」学会了盖房子

    子豪 发自 凹非寺 量子位 报道 | 公众号 QbitAI 了解游戏「我的世界(MineCraft)」的读者,一定很熟悉这样的画面. △图源:Science Magazine 但是,如果盖房子的不是人 ...

  2. 细胞自动机 通用计算机,细胞自动机

    细胞自动机,又称格状自动机.元胞自动机,是一种离散模型,在可算性理论.数学及理论生物学都有相关研究.它是由无限个有规律.坚硬的方格组成,每格均处于一种有限状态.整个格网可以是任何有限维的.同时也是离散 ...

  3. java实现细胞自动机_Java自动机实现

    java实现细胞自动机 这篇文章将解决在Java中实现有限状态机的问题. 如果您不知道什么是FSM或在什么地方可以使用FSM,您可能会热衷于阅读本 , 本和本 . 如果您发现自己在设计上使用FSM的情 ...

  4. 细胞自动机 c语言程序,Processing精彩例程之细胞自动机

    title: Processing精彩例程之细胞自动机 date: 2018-3-25 22:19:41 categories: 编程与生活 tags: Java 一维细胞自动机 一维细胞自动机 in ...

  5. c++ 45行代码实现 生命游戏-细胞自动机!!!

    概念:自动运行的机器 大家知道细胞自动机这个东西吗?当年冯诺依曼发明了计算机,同时也提出了一个概念:有一种机器,只要人为事先设定好,便可以一直自行地执行下去.可惜他早逝,52岁便被癌症带往天堂,到真正 ...

  6. 交通元细胞自动机matlab原代码,跪求交通流元细胞自动机matlab源代码

    满意答案 曾伽一路比 推荐于 2016.01.11 采纳率:58%    等级:9 已帮助:514人 不完全一样,改变下吧,希望能帮到你. function traffic1(n) % n是进站前的公 ...

  7. CellularAutomation(细胞自己主动机)

    CellularAutomation(细胞自己主动机) 细胞自己主动机(英语:Cellular automaton).又称格状自己主动机.元胞自己主动机,是一种离散模型,在可算性理论.数学及理论生物学 ...

  8. 【简单好玩】细胞自动机小游戏

    细胞自动机 备注:文末有自己用Javascript简单实现的网页版细胞自动机(还挺好玩) 什么是细胞自动机 细胞自动机(英语:Cellular automaton),又称格状自动机.元胞自动机,它是由 ...

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

    Last updated: 28 May, 2012 © 野比 2012 版权所有 (本文为个人学习笔记,知识浅薄,供大家乐乐) 欢迎对这方面感兴趣的爱好者一起研究. 寻求技术指导. 联系QQ 142 ...

  10. Java进阶学习-9 细胞自动机

    title: Java进阶学习-9 细胞自动机 date: 2020-02-02 22:06:23 tags: Java学习 死亡:如果活着的邻居数量<2或>3 则死亡 新生:如果正好有3 ...

最新文章

  1. 今年你的双11包裹,也是自动驾驶卡车送来的吗?
  2. mfc程序转化为qt_智慧虎超:小程序如何为珠宝行业助力?低频商品的高频转化你懂吗...
  3. WCF 第六章 序列化和编码之DataContractJsonSerializer
  4. 哥哥被我打哭了的飞鸽传书
  5. Dubbo基础知识总结
  6. java多态编译_关于java:编译时多态是否是这样的运行时多态?
  7. mac安装rstudio_在Windows / Linux / Mac OS上安装R和RStudio入门
  8. 双目测距(二)--双目标定与矫正
  9. numpy系列之拷贝和视图
  10. Access——SQL语言查询
  11. python vba sql_Excel、VBA与Mysql交互
  12. Google地图开发API
  13. empty怎么发音_empty是什么意思_empty在线翻译_英语_读音_用法_例句_海词词典
  14. ‘dtools’不是内部或外部命令,也不是可运行的程序或批处理文件,个人解决方案
  15. TYPE-C接口的定义诠释以及功能参数挖掘
  16. Shell 获取本月最后一天
  17. linux网卡命名规则及修改ip地址
  18. MODBUS RTU协议
  19. 手机控制电脑远程开机,笔记本与老电脑都能实现
  20. SQL server 数据库视频总结

热门文章

  1. 防止linux子系统关闭,Linux关闭selinux安全子系统的方法
  2. 友基-绘影G10数位屏到底是个什么东西呢要不要拆了看看
  3. html中panel居中显示图片,editorgridpanel
  4. Android 签名文件
  5. Mac快捷键大全-网络整理
  6. 【06年博文搬家】查看本机的瑞星序列号
  7. 基于QT的音视频采集推流实时传输播放数据发布系统 文档+项目源码+答辩PPT
  8. h5页面判断安卓或ios点击下载App
  9. NLP - 结巴分词 词云
  10. 74HC595串口转并口芯片学习