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

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

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 cases a cell dies or remains dead.
     In the case that a live square has zero or one neighbor, it is said to die of loneliness;
     if it has more than three neighbors, it is said to die of overcrowding.

规则很简单,周围细胞数是2保持当前状态,3存活或复活,其余情况死亡。
可以把最初的细胞结构定义为种子,当所有在种子中的细胞同时被以上规则处理后, 可以得到第一代细胞图。按规则继续处理当前的细胞图,可以得到下一代的细胞图,周而复始。

2.世界需要告诉中心细胞周围细胞的个数

从上面的规则可以知道是迭代关系,康威生命游戏的规则作用于当前细胞图生成下一代的细胞图。
在迭代中如果以每个细胞为单位进行,相邻细胞的存活标志的变化就会立刻影响到中心细胞的变化。
细胞需要知道自己下一刻的生存状态,在程序中体现为关于下一刻生存状态被细胞所预测和记忆。
细胞需要观察世界上与自己相邻的八个细胞的生存数目,这需要世界告诉每一个细胞。
这在程序中表现为,世界上记录着每一个细胞的生存状态和位置,世界可以生成当前迭代的细胞图。

3.细胞根据周围的细胞数和生存规则得到下一刻的生存状态

生存规则掌握在每一个细胞自己的控制范围内,只不过这个规则细胞本身不能改变。
细胞掌握着自己的存活规则,生命规则经过触发后导致细胞存活或死亡。
当时间流逝,细胞需要更新自己的生存状态,程序中表现为下一刻的生存状态赋值给当前生存状态。
当细胞图刷新完成后,即所有的细胞复制完毕后,世界需要让细胞需要预测自己下一刻的生存状态。
预测完成后,世界的时间加一。

4.世界的拓扑应该是立体圆环

为了避免细胞碰壁死亡,当细胞在世界的边缘时,需要和另一侧边缘的细胞相互作用。
先把上边和下边对接在一起,然后把左边和右边卷在一起,会得到类似游泳圈的立体图形。
需要提供获取当前世界图的方法,获取特定坐标周围存活细胞数的方法,时间流逝的方法。
在时间流逝的方法里,世界上的每一个细胞会更新它们的生存状态,并且预测下一刻的生存状态。

5.上帝创造世界并控制世界的时间

当上帝创造夏娃的时候,并没有想到夏娃会遇到那一条诱惑之蛇。
创造世界提供了两种方法,一种是通过在世界上放置一个生命特定结构的种子,
另一种是让世界随机的发生生命。两种方式都需要按照生命游戏的规则迭代细胞图。
随机的发生需要制定细胞发生的空间范围和在范围内发生细胞的设定概率。
当细胞图迭代后,上帝会通过自己的观察得到世界上生命的繁衍情况。

6.细胞:存活状态,时间流逝,预测下一刻存活状态

package yumu.chaos.lifegame;

public class Cell {

    private boolean alive;
    private boolean aliveNext;

    public boolean isAlive() {
        return alive;
    }
    public void setAlive(boolean alive) {
        this.alive = alive;
        this.aliveNext = alive;
    }

    public void timePass() {
        alive = aliveNext;
    }

    public void aliveNextReady(int count) {
        switch (count) {
        case 2:
            break;
        case 3:
            aliveNext = true;
            break;
        default:
            aliveNext = false;
            break;
        }
    }

}

7.世界:所有的细胞及其位置,时间流逝,获取当前细胞图

package yumu.chaos.lifegame;

import java.util.Random;

public class World {

    private int lenX;
    private int lenY;
    private Cell[][] cells;

    private World(int lenX, int lenY) {
        this.lenX = lenX;
        this.lenY = lenY;
        cells = new Cell[lenX][lenY];
        for(int x = 0; x < lenX; ++x){
            for(int y = 0; y < lenY; ++y)
                cells[x][y] = new Cell();
        }
    }

    public World(int lenX, int lenY, int[][] seed){
        this(lenX, lenY);
        for(int x = 0; x < seed.length; ++x){
            for(int y = 0; y < seed[x].length; ++y)
                if(seed[x][y] == 1)
                    cells[x][y].setAlive(true);
        }
    }

    public World(int lenX, int lenY, int scale, int ratio) {
        this(lenX, lenY);
        Random random = new Random();
        for(int x = 0; x < lenX/scale; ++x){
            for(int y = 0; y < lenY/scale; ++y)
                if(random.nextInt() % ratio == 0)
                    cells[x][y].setAlive(true);
        }
    }

    public void timePass(){
        for(int x = 0; x < lenX; ++x){
            for(int y = 0; y < lenY; ++y)
                cells[x][y].timePass();
        }
        for(int x = 0; x < lenX; ++x){
            for(int y = 0; y < lenY; ++y){
                int count = aliveRoundCount(x, y);
                cells[x][y].aliveNextReady(count);
            }
        }
    }

    private int aliveRoundCount(int x, int y){
        int count = 0;
        for(int i = -1; i <= 1; ++i){
            int tempX  = (x + i + lenX) % lenX;
            for(int j = -1; j <= 1; ++j){
                if(i == 0 && j == 0)
                    continue;
                int tempY  = (y + j + lenY) % lenY;
                if(cells[tempX][tempY].isAlive())
                    ++ count;
            }
        }
        return count;
    }

    public boolean[][] aliveArray(){
        boolean[][] alive = new boolean[lenX][lenX];
        for(int x = 0; x < lenX; ++x){
            for(int y = 0; y < lenY; ++y)
                alive[x][y] = cells[x][y].isAlive();
        }
        return alive;
    }

}

8.上帝:随机创建世界,用种子创建世界,时间流逝

package yumu.chaos.lifegame;

import yumu.chaos.lifegame.gui.Painter;

public class Deus {

    private World world;
    private Painter painter;

    public Deus() {
        painter = new Painter();
    }

    public void createWorld(int scale, int ratio){
        int lenX = 100;
        int lenY = 100;
        world = new World(lenX, lenY, scale, ratio);
    }

    public void createWorld(int[][] seed){
        int lenX = 50;
        int lenY = 50;
        world = new World(lenX, lenY, seed);
    }

    public void timePass(){
        world.timePass();
        painter.paint(world.aliveArray());
    }
}

9.当细胞在世界上演化

package yumu.chaos.lifegame;

public class Demo {

    static int[][] TANK = {
        {1, 0, 1},
        {0, 1, 1},
        {0, 1, 0}
    };

    static int[][] SHIP = {
        {0, 1, 0, 0, 1},
        {1, 0, 0, 0, 0},
        {1, 0, 0, 0, 1},
        {1, 1, 1, 1, 0}
    };

    static int[][] TOAD = {
        {0, 0, 0, 0},
        {0, 1, 1, 1},
        {1, 1, 1, 0}
    };

    static int[][] BOAT = {
        {1, 1, 0},
        {1, 0, 1},
        {0, 1, 0}
    };

    static int[][] GLIDER = {
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
        {0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
        {1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
    };

    public static void main(String[] args) {

        Deus deus = new Deus();
        deus.createWorld(2, 1);
//        deus.createWorld(TANK);
//        deus.createWorld(SHIP);
//        deus.createWorld(TOAD);
//        deus.createWorld(BOAT);
//        deus.createWorld(transpose(GLIDER));

        for(int i = 0; i < 1000; ++i){
            deus.timePass();
//            sleep(100);
        }
    }

    static int[][] transpose(int[][] a){
        int lenI = a.length;
        int lenJ = a[0].length;
        int[][] b = new int[lenJ][lenI];
        for (int i = 0; i < lenI; i++) {
            for (int j = 0; j < lenJ; j++)
                b[j][i] = a[i][j];
        }
        return b;
    }

    static void sleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

10.随机演化的细胞图

当创建世界的细胞区域比例scale = 2,发生生命的比率ratio = 1,时:

当创建世界的细胞区域比例scale = 2,发生生命的比率ratio = 5,时:

11.种子演化的细胞图

当种子为坦克TANK时,

当种子为滑翔机GLIDER时,

12.霍金的大设计中第八章的插图

参考链接:

[康威生命游戏 - 维基百科](https://zh.wikipedia.org/wiki/%E5%BA%B7%E5%A8%81%E7%94%9F%E5%91%BD%E6%B8%B8%E6%88%8F)
[大设计 - 霍金 - 亚马逊](http://www.amazon.cn/%E5%A4%A7%E8%AE%BE%E8%AE%A1-%E5%8F%B2%E8%92%82%E8%8A%AC%E2%80%A2%E9%9C%8D%E9%87%91/dp/B004HW7ZZA/ref=sr_1_8?s=books&ie=UTF8&qid=1439720917&sr=1-8)
[混沌理论入门(二十五) 生命游戏:模拟的出生和繁衍过程](http://www.bbfish.net/live/live_8394.html)
[生命游戏在线JavaDoc - gameoflife.free.fr](http://gameoflife.free.fr/doc_cn.htm)
[JAVA SWING GUI TUTORIAL](http://cs.nyu.edu/~yap/classes/visual/03s/lect/l7/)
[混沌,awt和swing绘制平面图形简介](http://www.cnblogs.com/kodoyang/p/Chaos_Graphics2D_Awt_Swing.html)

绘制生命游戏的细胞图的代码将会在下一篇日志中提供,日志地址为:

[混沌,细胞自动机与生命游戏图形绘制](http://www.cnblogs.com/kodoyang/p/Chaos_ConwayCellularAutomata_GameOfLife_GraphDrawing.html)

请点击正下方的『关注我』关注我!点击右下方的推荐图标推荐这片日志。

本文地址:http://www.cnblogs.com/kodoyang/p/Chaos_ConwayCellularAutomata_GameOfLife.html

雨木阳子

2015年8月16日

时间: 2024-12-04 10:47:48

混沌,细胞自动机与生命游戏的相关文章

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

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

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

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

元胞自动机+生命游戏

元胞自动机 元胞自动机(Cellular Automaton,复数为Cellular Automata,简称CA,也有人译为细胞自动机.点格自动机.分子自动机或单元自动机).是一时间和空间都离散的动力系统.散布在规则格网 (Lattice Grid)中的每一元胞(Cell)取有限的离散状态,遵循同样的作用规则,依据确定的局部规则作同步更新.大量元胞通过简单的相互作用而构成动态系统的演化. 不同于一般的动力学模型,元胞自动机不是由严格定义的物理方程或函数确定,而是用一系列模型构造的规则构成.凡是满

关于康威生命游戏的学习

 康威生命游戏,又称康威生命棋,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机.它最初于1970年10月在<科学美国人>杂志上马丁·葛登能的"数学游戏"专栏出现. 一个偶然机会发现了这个美妙的生命游戏.于是开始写程序来实现它,其实实现是很简单的,我现在还只能做到这个而已,不过还会继续深究下去的.先用Random来生成随机数,这样就可以在初始的时候在随机位置设定生死细胞了.输出的时候用2个for循环就是了.昨天做的时候遇到的问题是不知道最后该怎么判断了,因为判断

LeetCode:Game of Life - 康威生命游戏

1.题目名称 Game of Life(康威生命游戏) 2.题目地址 https://leetcode.com/problems/game-of-life 3.题目内容 英文: According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conw

生命游戏HTML5 Canvas代码

生命游戏是英国数学家约翰·何顿·康威在1970年发明的细胞自动机.它最初于1970年10月在<科学美国人>杂志中马丁·葛登能(Martin Gardner,1914年11月21日-2010年5月22日.又译:马丁·加德纳)的"数学游戏"专栏出现. 生命游戏其实是一个零玩家游戏,它包括一个二维矩形世界,这个世界中的每个方格居住着一个活着的或死了的细胞.一个 细胞在下一个时刻生死取决于相邻八个方格中活着的或死了的细胞的数量.如果相邻方格活着的细胞数量过多,这个细胞会因为资源匮乏

生命游戏的三种玩法

生命游戏 每个细胞有两种状态--存活或者死亡,每个细胞只与以其自身为中心的细胞产生互动. 当细胞为死亡状态,若周围有3个存活细胞,则该细胞变成存活状态(模拟繁殖) 当细胞为存活状态,若周围有2个或3个存活细胞,保持原样 若周围有3个以上存活细胞,该细胞变成死亡(模拟极度拥挤) 若周围有低于2个一下存活细胞,该细胞死亡(模拟人口稀疏) 这个游戏也叫康威生命游戏.细胞自动机.元胞自动机等. 图案介绍 "脉冲星":它周期为3,看起来像一颗爆发的星星 "滑翔者":每4个回合

[Leetcode] 第289题 生命游戏

一.题目描述 根据百度百科,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞.每个细胞具有一个初始状态 live(1)即为活细胞, 或 dead(0)即为死细胞.每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律: 如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡: 如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活: 如果活细胞周围八个位置有

Leetcode 289.生命游戏

生命游戏 根据百度百科,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞.每个细胞具有一个初始状态 live(1)即为活细胞, 或 dead(0)即为死细胞.每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律: 如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡: 如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活: 如果活细胞周围八个位置有超过