セル・オートマトンとは
格子状のセルと単純な規則による、離散的計算モデルである。離散的な時間で個々のセルの状態が変化する。その変化は、ある時刻 t においてのセルの状態、および近傍のセルの内部状態によって、次の時刻t+1 、すなわち新たな「ジェネレーション」(世代)での各セルの状態が決定される。
ライフゲームとは
セル・オートマトンに従った数理モデルのこと。生物集団において過密でも過疎でも個体の生存に適さないという個体群生態学的な背景に持つ。セル・オートマトンの代表例としてライフゲームが挙げられます。
ライフゲームのルール
誕生
死んでいるセルに隣接する生きたセルがちょうど3つあれば、次の世代がちょうど3つあれば、次の世代が誕生する。
灰色が生のセル
白色が死のセル
赤色は生成されたセル
生存
生きているセルに隣接する生きたセルが2つか3つならば、次の世代でも生存する。
過疎
生きているセルに隣接する生きたセルが1つ以下ならば、過疎により死滅する。
過密
生きているセルに隣接する生きたセルが4つ以上ならば、過密により死滅する。
ライフゲームの実装
このセル配置で銀河が生成される
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();
}
}