0
0

ライフゲームを実装してみた!

Posted at

セル・オートマトンとは

格子状のセルと単純な規則による、離散的計算モデルである。離散的な時間で個々のセルの状態が変化する。その変化は、ある時刻 t においてのセルの状態、および近傍のセルの内部状態によって、次の時刻t+1 、すなわち新たな「ジェネレーション」(世代)での各セルの状態が決定される。

ライフゲームとは

セル・オートマトンに従った数理モデルのこと。生物集団において過密でも過疎でも個体の生存に適さないという個体群生態学的な背景に持つ。セル・オートマトンの代表例としてライフゲームが挙げられます。

ライフゲームのルール

誕生
死んでいるセルに隣接する生きたセルがちょうど3つあれば、次の世代がちょうど3つあれば、次の世代が誕生する。
灰色が生のセル
白色が死のセル
赤色は生成されたセル

これが
Screenshot from 2024-08-29 00-38-45.png
こうなる
Screenshot from 2024-08-29 00-40-30.png

生存
生きているセルに隣接する生きたセルが2つか3つならば、次の世代でも生存する。

これは
Screenshot from 2024-08-29 00-52-13.png
変化なし

過疎
生きているセルに隣接する生きたセルが1つ以下ならば、過疎により死滅する。

これが
Screenshot from 2024-08-29 01-04-24.png
こうなる
Screenshot from 2024-08-29 01-04-53.png

過密
生きているセルに隣接する生きたセルが4つ以上ならば、過密により死滅する。

これが
Screenshot from 2024-08-29 01-00-07.png
こうなる
Screenshot from 2024-08-29 01-02-55.png

ライフゲームの実装

このセル配置で銀河が生成される
p5.jsのサイトで初心者でも簡単にJavaScriptを試せますよ

class Gen{
    constructor(){
      this.cells = [
        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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,1,1,0,1,1,1,1,1,1,0,0,0,
        0,0,0,0,1,1,0,1,1,1,1,1,1,0,0,0,
        0,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,1,1,0,0,0,
        0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,
        0,0,0,0,1,1,0,0,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,1,1,1,1,1,1,0,1,1,0,0,0,
        0,0,0,0,1,1,1,1,1,1,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,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,0,0,0,0,0,0,0,0,0,0,0,0,
      ]
    }
    next(){
      let t = this;
      let n = new Gen();
      for(let i=0; i<t.cells.length; i++){
        let L = t.livesAround(...t.indexToXy(i));
        if (t.cells[i] === 0){
          //現世代で死んでいるセルは......
          //3個の生きてるセルに囲まれたら復活
          n.cells[i] = (L === 3) ? 1 : 0;
        }else{
          //現世代で生きているセルは......
          //2個か3個の生きてるセルに囲まれていれば生存、それ以外なら過疎か過密で死
          n.cells[i] = (L === 2 || L === 3) ? 1 : 0;
        }
      }
      return n;
    }
    // 周りの生きているセルの数
    livesAround(x,y){
      let L = 0;
      // 中心のセルまで数えている
      for(let a=x-1; a<=x+1; a++){
        for(let b=y-1; b<=y+1; b++){
          let i = this.xyToIndex(a,b);
          L += (i === -1) ? 0 : this.cells[i];
        }
      }
      // 中心のセルをひく
      L -= this.cells[this.xyToIndex(x,y)];
      return L;
    }
    xyToIndex(x,y){
      let w = sqrt(this.cells.length);
      if(x<0 || x>=w || y<0 || y>=w) return -1;
      return y*w + x;
    }
    indexToXy(i){
      let w = sqrt(this.cells.length);
      let x = i%w;
      let y = floor(i/w);
      return [x,y]
    }
  
    draw(){
      fill(0, 206, 209);
      stroke(255,255,255);
      for (let [i,c] of this.cells.entries()){
        let [x,y] = this.indexToXy(i);
        let w = height/sqrt(this.cells.length);
        if (c === 1){
          rect(w*x, w*y, w, w);  
        }
      }
    }
  }
  // Generationのインスタンスを生成
  let g = new Gen();
  
  
  function setup(){
    createCanvas(480, 480);
    background(0, 128, 255);
    g.draw();
  }
  function redrawAll(){
    background(0, 128, 255);
    g.draw();
  }
  function mousePressed(){
    g = g.next();
    redrawAll();
  }
  function draw(){
    if(frameCount%10 === 9){
      mousePressed();
    }
  }

galaxy-lifegame.gif

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0