In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Game of Life. Universal

Convolution filter + paletteMap = super fast Game of Life simulation.
Get Adobe Flash player
by DaniilTutubalin 10 Sep 2012

    Talk

    Quasimondo at 27 Jan 2011 01:49
    In case you need help with the credits: http://www.quasimondo.com/archives/000680.php
    8cdhto61 at 27 Jan 2011 05:09
    wonderful wonderfl code
    DaniilTutubalin at 27 Jan 2011 08:22
    Quasimondo, thanks! But there was someone else on 25-lines contest who converted my 5-lines code into 4-lines by replacing 2 threshold with one paletteMap. Alas, site is down.
    at 28 Jan 2011 13:37
    I like how Quasimondo is so self-sure about it, meanwhile credits link in http://wonderfl.net/c/gfPa? predates his article by 3 years
    Quasimondo at 28 Jan 2011 14:09
    Oh noes - that psyarc.jp post is from 2005? Now I look look pretty stupid indeed. My apologies.
    Embed
/**
 * Copyright DaniilTutubalin ( http://wonderfl.net/user/DaniilTutubalin )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/fiMy
 */

/* Game of Life by Daniil Tutubalin

The idea was invented partially by me, partially by other people.
Quasimondo  http://www.quasimondo.com/archives/000680.php 
was the first who got an idea to use paletteMap for Game of Life.
My initial idea was to use threshold method, 
but it required to be called twice and it was much less adapting for different rules. 
Using paletteMap is one line shorter and more adapting.

So, this code allows you to experiment with different rules of Game of Life
*/

package {
    import flash.geom.Point;
    import flash.filters.ConvolutionFilter;
    import flash.display.Bitmap;
    import flash.events.Event;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    public class Life extends Sprite {
        
        
        // Rules: neighbors to born / neighbors to survive                
        // You may experiment with it
        
        //* Classic rules: cell borns if and only if 3 neighbors are nearby, cell survive if 2 or 3 neighbors
        private const RULES:String = "3/23"; /**/        
        
        /* Walled Cities - best with density = 17%
        private const RULES:String = "45678/2345" /**/        
        
        /* Maze generation
        private const RULES:String = "23/12345" /**/
        
        /* Space travellers
        private const RULES:String = "B368/S245" /**/
        
        // More rules can be found here: http://en.wikipedia.org/wiki/Life-like_cellular_automaton
                
        // Density of initial noise in percents
        // You may change it
        private const DENSITY:Number = 17;
                       
        // Convolution filter. 
        // 1 for every neighbor, 9 for cell itself
        // so empty cell result in 0..8 depending on number of neighbors
        // live cell result in 9..17
        private const LIFE_FILTER:ConvolutionFilter = new ConvolutionFilter(3, 3, [1,1,1,1,9,1,1,1,1], 255, 0, true, false, 0, 1);
                
        private const POINT_ZERO:Point = new Point();
        private const EMPTY_ARRAY:Array = [];
        
        private var gameField:BitmapData;
        private var bitmap:Bitmap;
        private var palette:Array;
        
        public function Life() {            
            if (stage) {
                init();
            } else {
                addEventListener(Event.ADDED_TO_STAGE, init);
            }
        }
        
        private function init(e:Event = null):void {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            
            // create field
            gameField = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0x000000);
            
            // make some noise
            var colorMin:int;
            var colorMax:int;
            if (DENSITY <= 50) {
                colorMin = 0;
                colorMax = 5.1 * DENSITY;                  
            } else {
                colorMin = 5.1 * (DENSITY-50)
                colorMax = 255;
            }
            gameField.noise(int(Math.random()*int.MAX_VALUE),colorMin,colorMax,1,true);
            
            // put on stage            
            bitmap = new Bitmap(gameField);
            addChild(bitmap);
            
            // init palette array
            palette = [];
            var rules:Array = RULES.split("/");
            var born:String = rules[0];
            var survive:String = rules[1];            
            
            // 0..8 - to burn
            for (var i:int = 0; i<9; i++) {
                if (born.indexOf(String(i)) != -1) {
                    palette.push(0xFFFFFF);
                } else {
                    palette.push(0x000000);
                }
            }
            // 9..17 - to survive
            for (i = 0; i<9; i++) {
                if (survive.indexOf(String(i)) != -1) {
                    palette.push(0xFFFFFF);
                } else {
                    palette.push(0x000000);
                }
            }
            
            addEventListener(Event.ENTER_FRAME, run);
        }

        private function run(e:Event = null):void {
            gameField.lock();
            gameField.applyFilter(gameField,gameField.rect, POINT_ZERO, LIFE_FILTER);
            gameField.paletteMap(gameField,gameField.rect, POINT_ZERO, palette, [], []);
            gameField.unlock();
        }

    }
}