ライフゲーム
/**
* Copyright awef ( http://wonderfl.net/user/awef )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/rSL4
*/
package
{
import flash.display.Sprite
import flash.utils.Timer;
import flash.events.TimerEvent;
public class Main extends Sprite
{
//セルが描写されるエリア
private var game :Sprite;
//セルのサイズ
private const cellSize :int = 4;
//セルを横に並べる数
private const gameWidth :int = 100;
//セルを縦に並べる数
private const gameHeight :int = 100;
//最初に誕生させるセル数
private const cellStart :int = gameWidth * gameHeight * 0.8;
//セルのデータを格納する配列
private var dat :Array;
//世代を進めるためのタイマー
private var timer :Timer;
//何ミリ秒おきに世代を進める処理を行うか
private var interval :int = 100;
public function Main()
{
//セルのデータを格納する配列の生成
var i :int;
var ii :int;
dat = new Array();
for (i = 0; i < gameWidth; i++)
{
dat.push(new Array());
for (ii = 0; ii < gameHeight; ii++)
dat[i].push(false);
}
//ランダムなセルを誕生させる
for (i = 0; i < cellStart; i++)
dat[Math.floor(Math.random() * gameWidth)][Math.floor(Math.random() * gameHeight)] = true;
//画面のセットアップ
graphics.beginFill(0xEEEEEC);
graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
graphics.endFill();
game = new Sprite();
clear();
game.x = Math.floor((stage.width - game.width) / 2);
game.y = Math.floor((stage.height - game.height) / 2);
stage.addChild(game);
//タイマーのスタート
timer = new Timer(interval, 0);
timer.addEventListener("timer", change);
timer.start();
}
//タイマーを一時停止させ、世代を一つ進めて再描写
private function change(e :TimerEvent) :void
{
timer.stop();
calc();
clear();
draw();
timer.start();
}
//セルを描写
private function draw() :void
{
var i :int;
var ii :int;
for (i = 0; i < gameWidth; i++)
{
for (ii = 0; ii < gameHeight; ii++)
{
if (dat[i][ii])
{
game.graphics.beginFill(0);
game.graphics.drawRect(i * cellSize, ii * cellSize, cellSize, cellSize);
game.graphics.endFill();
}
}
}
}
//セルの描写のクリア
private function clear() :void
{
game.graphics.clear();
game.graphics.beginFill(0xFFFFFF);
game.graphics.drawRect(0, 0, cellSize * gameWidth, cellSize * gameHeight);
game.graphics.endFill();
}
//世代を一つ進める
private function calc() :void
{
//次世代で死亡するセルのリスト
var dlist :Array = new Array();
//次世代で誕生するセルのリスト
var blist :Array = new Array();
var count :int;
var i :int;
var ii :int;
for (i = 0; i < gameWidth; i++)
{
for (ii = 0; ii < gameHeight; ii++)
{
//セルの周囲の生存セルをカウント
count = 0;
//左のセル
if (i - 1 >= 0 && dat[i - 1][ii])
count++;
//右のセル
if (i + 1 < gameWidth && dat[i + 1][ii])
count++;
//上のセル
if (ii - 1 >= 0 && dat[i][ii - 1])
count++;
//下のセル
if (ii + 1 < gameHeight && dat[i][ii + 1])
count++;
//左上のセル
if (i - 1 >= 0 && ii - 1 >= 0 && dat[i - 1][ii - 1])
count++;
//左下のセル
if (i - 1 >= 0 && ii + 1 < gameHeight && dat[i - 1][ii + 1])
count++;
//右上のセル
if (i + 1 < gameWidth && ii - 1 >= 0 && dat[i + 1][ii - 1])
count++;
//右下のセル
if (i + 1 < gameWidth && ii + 1 < gameHeight && dat[i + 1][ii + 1])
count++;
//死亡、かつ周囲に3つ生きているセルが有れば次世代で誕生させるリストに追加
if (!dat[i][ii] && count == 3)
blist.push([i, ii]);
//生存、かつ周囲の生存セル数が2か3で無い場合に次世代で死亡させるリストに追加
if (dat[i][ii] && count != 2 && count != 3)
dlist.push([i, ii]);
}
}
//誕生リスト及び死亡リストにあるセルを処理
var s :String;
for (s in blist)
dat[blist[s][0]][blist[s][1]] = true;
for (s in dlist)
dat[dlist[s][0]][dlist[s][1]] = false;
}
}
}