码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-08-16 22:39:43      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:


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

 

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日

 

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

标签:

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!