At 9/13/09 05:50 PM, trig1 wrote:
I've recently become obsessed with cellular automata. I've made a wireworld sim, a cyclic automata, an averaging cells one (don't know the real name for that one), and rules 31, 90, and 184. The only big ones I haven't made is Conways Game of Life and Langton's ant.
For an AS3 contest a while back, I made a 3D cellular automaton. The contest was to write something cool in 25 lines on the first frame of a CS4 timeline, so just paste this there and run. Mouse rotates, click to reset
Tom-
/**
* 25-Line ActionScript Contest Entry
*
* Project: 3D Cellular Automaton (Click to reset, move to rotate)
* Author: Tom Vian (thomas.vian07@gmail.com)
* Date: 29 / 11 / 08
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// 3 free lines! Alter the parameters of the following lines or remove them.
// Do not substitute other code for the three lines in this section
[SWF(width=300, height=300, backgroundColor=0xFFFFFF, frameRate=12)]
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.EXACT_FIT;
// 25 lines begins here!
main(Vector.<Vector.<uint>>([Vector.<uint>([0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]), Vector.<uint>([0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0])]), new Vector.<Bitmap>(), new Vector.<Vector.<Vector.<uint>>>(), Sprite(this.addChild(new Sprite())));
function main(rule:Vector.<Vector.<uint>> = null, planes:Vector.<Bitmap> = null, model2:Vector.<Vector.<Vector.<uint>>> = null, container:Sprite = null, model1:Vector.<Vector.<Vector.<uint>>> = null, tempModel:Vector.<Vector.<Vector.<uint>>> = null, i:int = 0, j:int = 0, k:int = 0, size:uint = 16, gap:uint = 8):void
{
for(model1 = Vector.<Vector.<Vector.<uint>>>([new Vector.<Vector.<uint>>()]); model1.length <= size; model1.push(new Vector.<Vector.<uint>>()))
{
(planes[planes.length] = Bitmap(container.addChild(new Bitmap(new BitmapData(size*gap, size*gap, true, 0))))).transform.matrix3D = new Matrix3D(Vector.<Number>([1,0,0,0,0,1,0,0,0,0,1,0,-size*gap*0.5, -size*gap*0.5, size * 0.5 * gap - gap * (planes.length-1), 1]));
model2.push(new Vector.<Vector.<uint>>());
for(model1[model1.length - 1].push(new Vector.<uint>()); model1[model1.length - 1].length <= size; model1[model1.length - 1].push(new Vector.<uint>()))
{
model2[model1.length - 1].push(new Vector.<uint>());
for(model1[model1.length - 1][model1[model1.length - 1].length-1].push(uint(Math.random()*2)); model1[model1.length - 1][model1[model1.length - 1].length-1].length <= size; model1[model1.length - 1][model1[model1.length - 1].length-1].push(uint(Math.random()*2))) model2[model1.length - 1][model1[model1.length - 1].length-1].push(model1[model1.length - 1][model1[model1.length - 1].length-1][model1[model1.length - 1][model1[model1.length - 1].length-1].length-1]);
}
}
// 8
stage.addEventListener(Event.ENTER_FRAME, act);
function act(e:Event = null):void
{
for(i = 0; i < size; i++)
{
for(j = 0; j < size; j++)
{
for(k = 0; k < size; k++) planes[i].bitmapData.fillRect(new Rectangle(j*gap, k*gap, gap, gap), 0x0F000000 + (0xF0000000) * (model2[i][j][k] = rule[model1[i][j][k]][v(i-1,j-1,k-1) + v(i,j-1,k-1) + v(i+1,j-1,k-1) + v(i-1,j,k-1) + v(i,j,k-1) + v(i+1,j,k-1) + v(i-1,j+1,k-1) + v(i,j+1,k-1) + v(i+1,j+1,k-1) + v(i-1,j-1,k) + v(i,j-1,k) + v(i+1,j-1,k) + v(i-1,j,k) + v(i+1,j,k) + v(i-1,j+1,k) + v(i,j+1,k) + v(i+1,j+1,k) + v(i-1,j-1,k+1) + v(i,j-1,k+1) + v(i+1,j-1,k+1) + v(i-1,j,k+1) + v(i,j,k+1) + v(i+1,j,k+1) + v(i-1,j+1,k+1) + v(i,j+1,k+1) + v(i+1,j+1,k+1)]) + ((0xFF * i / size) << 16));
}
}
tempModel = model2;
model2 = model1;
model1 = tempModel;
}
// 16
function v(i:int, j:int, k:int):uint {return model1[(i+size)&(size-1)][(j+size)&(size-1)][(k+size)&(size-1)];}
stage.addEventListener(MouseEvent.MOUSE_MOVE, changeView);
function changeView(e:MouseEvent = null):void {container.transform.matrix3D = Matrix3D.interpolate(new Matrix3D(Vector.<Number>([0.707,0,0.707,0,0,1,0,0,-0.707,0,0.707,0,stage.stageWidth / 2,stage.stageHeight / 2,-50,1])), new Matrix3D(Vector.<Number>([0.707,0,-0.707,0,0,1,0,0,0.707,0,0.707,0,stage.stageWidth / 2,stage.stageHeight / 2,-50,1])), 0.5 - (stage.mouseX - (stage.stageWidth / 2)) / stage.stageWidth); }
changeView();
// 20
stage.addEventListener(MouseEvent.CLICK, reset);
function reset(e:MouseEvent = null):void
{
for(i = 0; i < size; i++)
{
for(j = 0; j < size; j++)
{
for(k = 0; k < size; k++) model1[i][j][k] = uint(Math.random()*2);
}
}
}
// 25
}
// 25 lines ends here!