Skip to content

Instantly share code, notes, and snippets.

@alecmce
Created March 7, 2010 04:55
Show Gist options
  • Save alecmce/324161 to your computer and use it in GitHub Desktop.
Save alecmce/324161 to your computer and use it in GitHub Desktop.
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.Event;
/**
* A pretty quick implementation of Conway's Game Of Life
*
* @author Alec McEachran
*
* (c) 2010 alecmce.com
*
* Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
*/
public class GameOfLife extends Bitmap
{
private var _data:BitmapData;
private var _cells:Vector.<Boolean>;
private var _neighbours:Vector.<uint>;
private var _shift:uint;
private var _width:uint;
private var _height:uint;
private var _size:uint;
private var _stopped:Boolean;
public function GameOfLife(width:uint, height:uint, size:uint = 1)
{
_size = size;
_width = width / _size;
_height = height / _size;
_shift = 1;
while ((1 << _shift) < _width)
_shift++;
var dim:uint = (_width + 1) << _shift;
_cells = new Vector.<Boolean>(dim, true);
_neighbours = new Vector.<uint>(dim, true);
_data = new BitmapData(width, height);
randomize();
super(_data);
scaleX = scaleY = size;
if (stage)
onAddedToStage(null);
else
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
public function stop():void
{
removeEventListener(Event.ENTER_FRAME, iterate);
_stopped = true;
}
public function play():void
{
if (stage)
addEventListener(Event.ENTER_FRAME, iterate);
_stopped = false;
}
public function randomize():void
{
var i:int = _width;
while (i--)
{
var j:int = _height;
while (j--)
_cells[(i << _shift) | j] = Math.random() > 0.5;
}
}
private function onAddedToStage(event:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
if (!_stopped)
stage.addEventListener(Event.ENTER_FRAME, iterate);
stage.addEventListener(Event.RENDER, onRender);
}
private function onRemovedFromStage(event:Event):void
{
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
removeEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
stage.removeEventListener(Event.ENTER_FRAME, iterate);
stage.removeEventListener(Event.RENDER, onRender);
}
private function iterate(event:Event):void
{
var value:uint;
var row:uint;
var upper:uint;
var lower:uint;
var i:int = _width;
while (i--)
{
var j:int = _height;
while (j--)
{
value = 0;
upper = j == _height - 1 ? 0 : j + 1;
lower = j == 0 ? _height - 1 : j - 1;
row = (i == 0 ? _width - 1 : (i - 1)) << _shift;
if (_cells[row | lower]) ++value;
if (_cells[row | j]) ++value;
if (_cells[row | upper]) ++value;
row = i == _width - 1 ? 0 : (i + 1) << _shift;
if (_cells[row | lower]) ++value;
if (_cells[row | j]) ++value;
if (_cells[row | upper]) ++value;
row = i << _shift;
if (_cells[row | lower]) ++value;
if (_cells[row | upper]) ++value;
_neighbours[row | j] = value;
}
}
stage.invalidate();
}
private function onRender(event:Event):void
{
_data.lock();
var i:int = _width;
while (i--)
{
var j:int = _height;
while (j--)
{
var index:uint = (i << _shift) | j;
var value:uint = _neighbours[index];
var newCell:Boolean;
if (_cells[index])
newCell = value == 2 || value == 3;
else
newCell = value == 3;
var color:uint = newCell ? 0xFF000000 : 0xFFFFFFFF;
_cells[index] = newCell;
_data.setPixel32(i, j, color);
}
}
_data.unlock();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment