最近、ActionScript3.0を勉強してました。(オライリーの詳説ActionScript 3.0にて)
一通り読み終えたのと仕事がなくて暇なのでライフゲームでも作ってみようと思いました。

見栄えとか、べた書きしているロジックなどをなんとかしたいけども、まあなんとか基本的なところはできました。
暇が続いて、やる気になったら改善するぞと。

メインクラスは以下の感じ、こいつをflaファイルのドキュメントクラスに指定。

info.uebuyahonpo.lg.Main.as
----
package info.uebuyahonpo.lg {
    import flash.display.*;
    import flash.events.*;
    import flash.utils.*;

    public class Main extends Sprite {
        private var boad:Boad;
        private var timer:Timer;
        public function Main() {
            boad = new Boad();
            boad.x = boad.y = 10;
            addChild(boad);
            addChild(make_btn(click_listener));
            timer = new Timer(300,0);
            timer.addEventListener(TimerEvent.TIMER,timer_listener);
            var btn:SimpleButton = make_btn(timer_trigger);
            btn.x = 100;
            addChild(btn);
            stage.align = StageAlign.TOP_LEFT;
        }

        private function make_btn(callback:Function):SimpleButton {
            var btn:SimpleButton = new SimpleButton();
            btn.upState      = make_rect(0xFF0000,0,0,50,8);
            btn.overState    = make_rect(0xFF0000,1,1,48,6);
            btn.downState    = make_rect(0xCC3333,1,1,48,6);
            btn.hitTestState = btn.upState;
            btn.addEventListener(MouseEvent.CLICK,callback);
            return btn;
        }

        private function make_rect(color:uint,x:int,y:int,w:int,h:int):Shape {
            var s:Shape = new Shape();
            s.graphics.lineStyle();
            s.graphics.beginFill(color);
            s.graphics.drawRect(x,y,w,h);
            return s;
        }

        private function click_listener(e:MouseEvent):void {
            boad.next();
        }

        private function timer_trigger(e:MouseEvent):void {
            if ( timer.running ) {
                timer.stop();
            }
            else {
                timer.start();
            }
        }

        private function timer_listener(e:TimerEvent):void {
            boad.next();
        }
    }
}

セルとゲームボードはそれぞれこんな感じ。

info.uebuyahonpo.lg.Cell.as
----
package info.uebuyahonpo.lg {
    import flash.display.*;
    import flash.events.*;

    class Cell extends Shape {
        private var neighbors:Array;
        private var alive:Boolean;
        private var next:Boolean;

        public function Cell(size:uint) {
            var r = Math.round(size/2);
            this.graphics.lineStyle();
            this.graphics.beginFill(0x000099);
            this.graphics.drawCircle(r,r,r);
            neighbors = new Array(4);
            this.die();
        }

        public function set_neighbors(n:Cell,e:Cell,s:Cell,w:Cell):void {
            neighbors[0] = n;
            neighbors[1] = e;
            neighbors[2] = s;
            neighbors[3] = w;
        }

        public function is_alive():Boolean {
            return alive;
        }

        public function bear():void {
            alive = true;
            visible = true;
        }

        public function die():void {
            alive = false;
            visible = false;
        }

        public function toggle():void {
            if ( is_alive() ) {
                die();
            }
            else {
                bear();
            }
        }

        public function set_next(val:Boolean):void {
            next = val;
        }

        public function update():void {
            if ( next ) {
                bear();
            }
            else {
                die();
            }
        }

        public function north():Cell {
            if ( neighbors[0] is Cell ) {
                return (Cell)(neighbors[0]);
            }
            return null;
        }

        public function east():Cell {
            if ( neighbors[1] is Cell ) {
                return (Cell)(neighbors[1]);
            }
            return null;
        }

        public function south():Cell {
            if ( neighbors[2] is Cell ) {
                return (Cell)(neighbors[2]);
            }
            return null;
        }

        public function west():Cell {
            if ( neighbors[3] is Cell ) {
                return (Cell)(neighbors[3]);
            }
            return null;
        }

        public function north_west():Cell {
            var n:Cell = this.north();
            if ( n is Cell ) {
                return n.west();
            }
            return null;
        }

        public function north_east():Cell {
            var n:Cell = this.north();
            if ( n is Cell ) {
                return n.east();
            }
            return null;
        }

        public function south_west():Cell {
            var s:Cell = this.south();
            if ( s is Cell ) {
                return s.west();
            }
            return null;
        }

        public function south_east():Cell {
            var s:Cell = this.south();
            if ( s is Cell ) {
                return s.east();
            }
            return null;
        }
    }
}
info.uebuyahonpo.lg.Boad.as
----
package info.uebuyahonpo.lg {
    import flash.display.*;
    import flash.events.*;

    class Boad extends Sprite {
        private var square_size:uint;
        private var column_num:uint;
        private var cells:Array;

        public function Boad(square_size:uint=10,column_num:uint=10) {
            this.square_size = square_size;
            this.column_num  = column_num;
            cells = new Array();
            setup();
            this.addEventListener(MouseEvent.CLICK,click_listener);
        }

        public function next():void {
            for (var i:int=0; i<cells.length; i++) {
                var num:int = 0;
                var c:Cell = cells[i];
                if ( c.north().is_alive() )      { num++; }
                if ( c.north_east().is_alive() ) { num++; }
                if ( c.east().is_alive() )       { num++; }
                if ( c.south_east().is_alive() ) { num++; }
                if ( c.south().is_alive() )      { num++; }
                if ( c.south_west().is_alive() ) { num++; }
                if ( c.west().is_alive() )       { num++; }
                if ( c.north_west().is_alive() ) { num++; }

                if ( c.is_alive() ) {
                    if ( num == 2 || num == 3 ) {
                        c.set_next(true);
                    }
                    else {
                        c.set_next(false);
                    }
                }
                else {
                    if ( num == 3 ) {
                        c.set_next(true);
                    }
                    else {
                        c.set_next(false);
                    }
                }
            }
            for (i=0; i<cells.length; i++) {
                cells[i].update();
            }
        }

        private function setup():void {
            draw_bg();
            create_cells();
            set_cell_neighbors();
        }

        private function draw_bg():void {
            this.graphics.lineStyle(1);
            this.graphics.beginFill(0xffffff);
            this.graphics.drawRect(
                0,0,
                column_num*square_size,column_num*square_size
            );
            this.graphics.lineStyle();
            this.graphics.beginFill(0xcccccc);
            for (var i:int=0; i < column_num; i++) {
                for (var j:int=0; j < column_num; j++) {
                    if ( (i+j)%2 == 0 ) { continue; }
                    this.graphics.drawRect(
                        i*square_size, j*square_size,
                        square_size,square_size
                    );
                }
            }
        }

        private function create_cells():void {
            for (var j:int=0; j < column_num; j++) {
                for (var i:int=0; i < column_num; i++) {
                    var c:Cell = new Cell(square_size*0.8);
                    c.x = i*square_size + square_size*0.1;
                    c.y = j*square_size + square_size*0.1;
                    cells.push(c);
                    addChild(c);
                    c = null;
                }
            }
        }

        private function set_cell_neighbors():void {
            for (var i=0; i < cells.length; i++) {
                var x:int = i%column_num;
                var y:int = i/column_num;
                var n:int = (y-1)>=0 ? column_num*(y-1)+x : column_num*(column_num-1)+x;
                var s:int = (y+1)<column_num ? column_num*(y+1)+x : x;
                var e:int = (x+1)<column_num ? column_num*y+x+1 : column_num*y;
                var w:int = (x-1)>=0 ? column_num*y+x-1 : column_num*y+column_num-1;
                cells[i].set_neighbors(cells[n],cells[e],cells[s],cells[w]);
            }
        }

        private function click_listener(e:MouseEvent):void {
            var x:int = e.localX/square_size;
            var y:int = e.localY/square_size;
            var c:int = column_num*y + x;
            cells[c].toggle();
        }
    }
}