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
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();
}
}
}