#9 Conway's Game of Life(flash on 2009-8-23)

by krogue
Conway's Game of Life
*
* NOTE: 前回はセルが少なかったので今回は1px=1セルで。小さすぎるよ……
* NOTE: テンプレート作成&試用
* NOTE: 標準コーディングルールに一部準拠(インデントなど)
* TODO: 初期化(リセットボタン)
* TODO: ズーム
* @author krogue
♥0 | Line 106 | Modified 2009-08-23 18:51:17 | MIT License
play

ActionScript3 source code

/**
 * Copyright krogue ( http://wonderfl.net/user/krogue )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/wsV8
 */

/**
 * Conway's Game of Life
 *
 * NOTE: 前回はセルが少なかったので今回は1px=1セルで。小さすぎるよ……
 * NOTE: テンプレート作成&試用
 * NOTE: 標準コーディングルールに一部準拠(インデントなど)
 * TODO: 初期化(リセットボタン)
 * TODO: ズーム
 * @author krogue
 */
package  {
    import flash.display.Sprite;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.PixelSnapping;
    import flash.events.Event;
    import flash.geom.Rectangle;
    
    [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="60")]
    public class ConwayGame extends Sprite {
        private const WIDTH:int = 465;
        private const HEIGHT:int = 465;
        private const INIT_LIFE_NUM:int = WIDTH * HEIGHT / 5;
        private const COLOR_LIFE:uint = 0xFFFFFF;
        private const COLOR_DEATH:uint = 0x000000; // == 0 でないと動作しない
        private var bitmap:Bitmap;
        private var fgBitmapData:BitmapData;
        private var bgBitmapData:BitmapData;
        private var points:Array; /* of Point */
        private var rectangle:Rectangle;
        
        public function ConwayGame() {
            addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
        }
        
        private function addedToStageHandler(event:Event):void {
            removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
            initialize();
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }
        
        private function enterFrameHandler(event:Event):void {
            update();
        }
        
        private function initialize():void {
            // init points
            points = new Array(WIDTH * HEIGHT); /* of Point */
            for (var y:int = 0; y < HEIGHT; y++) {
                for (var x:int = 0; x < WIDTH; x++) {
                    points[y * HEIGHT + x] = new Point(x, y);
                }
            }
            
            // randomize points
            for (var i:int = points.length - 1; i > 0; i--) {
                var index:int = Math.floor(Math.random() * (i + 1));
                var work:Point = points[index];
                points[index] = points[i];
                points[i] = work;
            }
            
            // init bitmapData
            rectangle = new Rectangle(0, 0, WIDTH, HEIGHT);
            fgBitmapData = new BitmapData(rectangle.width, rectangle.height, false, COLOR_DEATH);
            bgBitmapData = fgBitmapData.clone();
            points.every(function(point:*, index:int, array:Array /* of Point */):Boolean {
                if (index >= INIT_LIFE_NUM) {
                    // do nothing
                    return false; // break
                }
                fgBitmapData.setPixel(point.x, point.y, COLOR_LIFE);
                return true; // continue
            }, this);
            
            // init bitmap
            bitmap = addChild(new Bitmap(fgBitmapData, PixelSnapping.NEVER, false)) as Bitmap;
        }
        
        private function update():void {
            var fg:BitmapData = fgBitmapData;
            var bg:BitmapData = bgBitmapData;
            
            fg.lock();
            bg.lock();
            
            bg.fillRect(rectangle, COLOR_DEATH);
            for (var y:int = 0; y < fg.height; y++) {
                for (var x:int = 0; x < fg.width; x++) {
                    var lifeCount:int = 0;
                    if (fg.getPixel(x - 1, y - 1) != 0) lifeCount++;
                    if (fg.getPixel(x + 0, y - 1) != 0) lifeCount++;
                    if (fg.getPixel(x + 1, y - 1) != 0) lifeCount++;
                    if (fg.getPixel(x - 1, y + 0) != 0) lifeCount++;
                    if (fg.getPixel(x + 1, y + 0) != 0) lifeCount++;
                    if (fg.getPixel(x - 1, y + 1) != 0) lifeCount++;
                    if (fg.getPixel(x + 0, y + 1) != 0) lifeCount++;
                    if (fg.getPixel(x + 1, y + 1) != 0) lifeCount++;
                    if ((lifeCount == 3) || (lifeCount == 2 && fg.getPixel(x, y) != 0)) {
                        bg.setPixel(x, y, COLOR_LIFE);
                    }
                }
            }
            
            bitmap.bitmapData = bg;
            bgBitmapData = fg;
            fgBitmapData = bg;
            
            fg.unlock();
            bg.unlock();
        }
    }
}

class Point {
    private var _x:int;
    private var _y:int;
    
    public function Point(x:int, y:int) {
        _x = x;
        _y = y;
    }
    
    public function get x():int {
        return _x;
    }
    
    public function set x(value:int):void {
        _x = value;
    }
    
    public function get y():int {
        return _y;
    }
    
    public function set y(value:int):void {
        _y = value;
    }
}

Forked