今更ながらCreateJSで、ライフゲームを作る
横:150セル、縦:150セルのライフゲームを作ってみた。
初期配置は、ランダムです。(1つだけグライダー型を配置)
一応、ライフゲームの生存ルールは以下の通り、
・生命がいるセルでは、その周りに2個か3個の生命が存在すれば、次の世代も生き残る。
・生命がいないセルでは、その周りに3個の生命が存在すれば、次の世代で生命が誕生する。
・それ以外のときは、どちらも次の世代で死滅する。
「スタート」ボタンで始まります。「ストップ」ボタンで途中で止められます。
ちなみに、jQueryでDOM版も作ってみた。jQueryでDOM版はこちら>
■初期配置
- 現在のセルの状況を保存する配列(arr_cells_now[])と、
- 1世代すすめた時の状況を保存する配列(arr_cells_future[])を作る
- arr_cells_now[]配列に、ランダムに配置する
function arr_init() {
for ( var i = 0; i < max_cells; i++ ) {
arr_cells_now[i] = 0;
arr_cells_future[i] = 0;
var nums = Math.random() * 10;
if( nums < 1 ) {
arr_cells_now[i] = 1;
}
}
//グライダーを配置
arr_cells_now[310] = 1;
arr_cells_now[461] = 1;
arr_cells_now[609] = 1;
arr_cells_now[610] = 1;
arr_cells_now[611] = 1;
//セル用shape
for ( var j = 0; j < max_cells; j++ ) {
gr_shapes[j] = new createjs.Shape();
stage.addChild(gr_shapes[j]);
gr_shapes[j].graphics.beginFill('#333333');
gr_shapes[j].graphics.drawRect(0,0,4,4);
gr_shapes[j].x = parseInt( j % max_width ) * 4;
gr_shapes[j].y = parseInt( j / max_width ) * 4;
if( arr_cells_now[j] == 0 ) {
gr_shapes[j].visible = false;
}
}
stage.update();
}
■世代を進めて描画する
- ライフゲームのルールに従って1世代ずつ進める
- 次の世代の状況を描画する
- 1000世代までで終了とする
function life_mov( now_arr , future_arr ) {
for ( var i = 0; i < max_cells; i++ ) {
//上下左右のセルの配列上の相対位置を出すため用
var arr_cellpos = [
(max_width +1) * -1, ( max_width ) * -1, ( max_width -1 ) * -1,
-1, 0 , 1,
max_width -1,max_width,max_width +1
]
//周りのセルを調べる
var cnt = 0;
for( var j = 0; j < 9; j++ ) {
if ( j != 4 ) {
var n = i + arr_cellpos[j];
if( n < 0 ) {
n += max_cells;
} else if( n > ( max_cells - 1 ) ) {
n -= max_cells;
}
if ( now_arr[n] >= 1 ) {
cnt++;
}
}
}
//生存セルのとき
future_arr[i] = now_arr[i];
if( now_arr[i] >= 1 ) {
if( cnt < 2 ) {
future_arr[i] = 0;
}
if( cnt > 3 ) {
future_arr[i] = 0;
}
} else {
//空きセルのとき
if( cnt == 3 ) {
future_arr[i] = 1;
}
}
//描画
if ( future_arr[i] == 1 ) {
gr_shapes[i].visible = true;
} else {
gr_shapes[i].visible = false;
}
}
sedai_label.text = sedai + ':世代';
}