// forked from shohei909's 足し算をするセルオートマン - celllular automaton,which do addition package { /* * ライフゲーム * とりあえずSPACEを押せばライフゲーム開始 * あとは,数字キーを押したり、 * Zでズームしたりして遊ぶ。 * * LIFE GAME * * start/stop: SPACE * reset: c * decel/accel: ← / → * random: x * zoom: z * stamp: 1-3 * stamp reverse (x): +↑ * stamp reverse (y): +↓ * stamp reverse (x/y): +SHIHT */ import flash.events.KeyboardEvent; import flash.display.Sprite; import flash.events.Event; public class FlashTest extends Sprite { public var game:Game; public var zoom:Boolean = false; public var zoomX:int; public var zoomY:int; public var revX:Boolean = false; public var revY:Boolean = false; public function FlashTest() { game = new Game(); stage.frameRate = 60; addChild(game); stage.addEventListener( KeyboardEvent.KEY_DOWN , onDown); stage.addEventListener( KeyboardEvent.KEY_UP , onUp); addEventListener( Event.ENTER_FRAME , onFrame); } public function onDown(e:KeyboardEvent):void{ if(e.keyCode == 32){ game.brain.player(null); }else if(e.keyCode == 67){ game.brain.reset(null); }else if(e.keyCode == 88){ game.brain.random(null); }else if(e.keyCode == 37){ if(Game.SPAN < 256){Game.SPAN*=2;} }else if(e.keyCode == 39){ if(Game.SPAN > 1){Game.SPAN/=2;} }else if(e.keyCode == 38){ revX = true; }else if(e.keyCode == 40){ revY = true; }else if(e.keyCode == 90 && zoom==false){ zoom = true; zoomX = mouseX; zoomY = mouseY; }else if(e.keyCode >= 48 &&e.keyCode <= 57){ //ショートカット1 var num:int = e.keyCode-48; var i:int = game.brain.mouseX / Game._SCALE; var j:int = game.brain.mouseY / Game._SCALE; if(revY){var dx:int = -1;}else{dx=1;} if(revX){var dy:int = -1;}else{dy=1;} if(e.shiftKey){var r:Boolean = true;}else{r=false;} game.brain.stamp(i,j,num,dx,dy,r); } } public function onUp(e:KeyboardEvent):void{ if(e.keyCode == 90){ zoom = false; }else if(e.keyCode == 38){ revX = false; }else if(e.keyCode == 40){ revY = false; } } public function onFrame(e:Event):void{ if(zoom){ game.scaleX = (4 + game.scaleX*7)/8; game.scaleY = game.scaleX; }else{ game.scaleX = (1 + game.scaleX*7)/8; game.scaleY = game.scaleX; } zoomX = (31*zoomX + mouseX)/32; zoomY = (31*zoomY + mouseY)/32; game.x = zoomX - (game.scaleX * zoomX); game.y = zoomY - (game.scaleX * zoomY); } } } import flash.events.MouseEvent; import flash.filters.GlowFilter; import flash.geom.Matrix; import flash.geom.Point; import flash.geom.Rectangle; import flash.events.Event; import flash.display.*; import mx.utils.*; class Game extends Sprite{ public static var _WIDTH:int = 116; public static var _HEIGHT:int = 116; public static var _SCALE:int = 4; public static var SPAN:int = 16; public static var ELECT:Boolean = false; public static var BIRTH_MIN:int = 3; public static var BIRTH_MAX:int = 3; public static var LIVE_MIN:int = 2; public static var LIVE_MAX:int = 3; public static var DATA:Array = [ [[0,1,1],[1,1,0],[0,1,0]], [[1,0,0],[0,1,1],[1,1,0]], [[0,0,0,1,0],[0,0,0,0,1],[1,0,0,0,1],[0,1,1,1,1]], [[0,0,1],[1,0,0,0,1],[0,0,0,0,0,1],[1,0,0,0,0,1],[0,1,1,1,1,1]], [[0,0,1,1],[1,0,0,0,0,1],[0,0,0,0,0,0,1],[1,0,0,0,0,0,1],[0,1,1,1,1,1,1]], [[1,1,1,1,1,1,1,1,1,1]], [ [0,0,0,0,0,0,0,1,0], [0,0,0,0,0,0,1,0,1], [0,0,0,0,0,0,1,0,1], [0,0,0,0,0,0,0,1,1], [0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,1,1,1,0,0,0,0,0,0,1,1,0], [0,1,0,0,1,0,0,0,0,0,1,0,0,1], [0,0,1,1,0,0,0,0,0,0,1,1,1,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,1,1,0], [0,0,0,0,0,0,1,0,1], [0,0,0,0,0,0,1,0,1], [0,0,0,0,0,0,0,1,0] ], [ [0,0,0,1,0],[0,0,0,0,1],[1,0,0,0,1],[0,1,1,1,1], [0],[0],[0], [1],[0,1,1],[0,0,1],[0,0,1],[0,1], [0],[0], [0,0,0,1,0],[0,0,0,0,1],[1,0,0,0,1],[0,1,1,1,1] ], [ [0,0,1,0,0,0,0,1,0,0,0], [1,1,0,1,1,1,1,0,1,1,0], [0,0,1,0,0,0,0,1,0,0,0], [0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,1,1,1,1,0,1,1,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1], [0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1], [1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,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,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ] ]; public var brain:Medium; public function Game():void{ brain = new Medium(); addChild(brain); addEventListener("mouseDown",onDown); addEventListener("enterFrame",loop); } public function onDown(e:MouseEvent):void{ var i:int = e.target.mouseX / _SCALE; var j:int = e.target.mouseY / _SCALE; brain.cells[i + _WIDTH*j].change(null); } private function loop(e:Event):void{ brain.loop(); } } class Medium extends Bitmap{ public var w:int = 0; public var h:int = 0; public var cellSize:int = 25; public var play:Boolean = false; public var cells:Vector.<Cell>; public var electrons:Vector.<Electron>; private var count:int = 0; private var nowMap:BitmapData; public var eShape:EShape = new EShape(); public function Medium(){ w = Game._WIDTH; h = Game._HEIGHT; cellSize = Game._SCALE; electrons = new Vector.<Electron>(); cells = new Vector.<Cell>(); for(var i:int=0;i<w;i++){ for(var j:int=0;j<h;j++){ cells[i*h + j] = new Cell(j,i); } } //ライフゲーム用--------------------------- for(var n:int=0;n<w;n++){ for(var m:int=0;m<h;m++){ for(var k:int= -1;k<2;k++){ for(var l:int= -1;l<2;l++){ i = n+k; j = m+l; if( i>=0 && i<h && (k!=0 || l!=0) ){ connect(n+m*w,i+j*w); } } } } } //------------------------------------------ nowMap = new BitmapData( w*cellSize+2, h*cellSize+2, false, 0x000000 ); super(new BitmapData( w*cellSize+2, h*cellSize+2, false, 0x000000 )); } public function player(e:Event):void{ play = (play == false); } public function reset(e:Event):void{ for each(var cell:Cell in cells){ cell.alive = false; cell.count = 0; } } public function random(e:Event):void{ for(var i:int=0; i<cells.length/25; i++){ var n:int = cells.length*Math.random(); cells[n].alive = true; } } public function loop():void{ drow(); count++; if(count%Game.SPAN == 0 && play){ for(var i:uint=0; i<w; i++){ for(var j:uint=0; j<h; j++){ cell = cells[i+j*w]; if(cell.alive){ if(Game.ELECT){ for each(var syn:Synapse in cell.synapses){ var sx:int = (cell.x+1/2) * cellSize; var sy:int = (cell.y+1/2) * cellSize; var tx:int = (syn.target.x+1/2) * cellSize; var ty:int = (syn.target.y+1/2) * cellSize; for(var n:uint=0;n<syn.strength;n++){ var el:Electron = new Electron(sx,sy,tx,ty,Game.SPAN); electrons.push(el); } } } cell.pass(); } } } for each(var cell:Cell in cells){ cell.setting(); } } } public function connect(st:int, en:int,s:int = 1):void{ if(en>=0 && en < cells.length){ cells[st].synapses.push( new Synapse(cells[en],s)); } } public function drow():void{ nowMap.lock(); bitmapData.lock(); for(var i:int=0; i<w; i++){ for(var j:int=0; j<h; j++){ var cell:Cell = cells[i+j*w]; var rect:Rectangle = new Rectangle(i*cellSize+1,j*cellSize+1,cellSize-1,cellSize-1); if(cell.alive){ nowMap.fillRect(rect, cell.color); }else if(cell.over){ nowMap.fillRect(rect, 0x191111 ); }else{ nowMap.fillRect(rect, 0x111111); } } } for( i=0;i< electrons.length;i++){ var el:Electron = electrons[i]; var mtr:Matrix = new Matrix(); mtr.translate(el.x, el.y); nowMap.draw(eShape,mtr); if(el.life == 0){ electrons.splice(i,1); i--; }else{ el.move(); } } rect = bitmapData.rect; var point:Point = new Point(0,0); var rate:uint = 0xE0; nowMap.unlock(); bitmapData.merge(nowMap,rect,point,rate,rate,rate,rate); nowMap.fillRect(rect,0x000000); bitmapData.unlock(); } public function stamp(j:int,i:int,num:int,dx:int=1,dy:int=1,rot:Boolean=false):void{ var data:Array = Game.DATA[num]; for(var n:int = 0; n < data.length;n++){ for(var m:int = 0; m < data[n].length;m++){ if(rot){ var an:int = m*dx+i; var am:int = n*dy+j; }else{ an= n*dx+i;am= m*dy+j; } if(an>=0 && an<w && am>=0 && am<h){ cells[an*h+am].alive=(data[n][m]>0); } } } } } class EShape extends Shape{ public function EShape():void{ filters = [new GlowFilter(0x00AAFF)]; with(graphics){ beginFill (0xFFFFFF, 1.0); drawCircle( 0, 0 ,2); } } } class Electron{ public var x:int; public var y:int; public var targetX:int; public var targetY:int; public var life:int; private var r:Number; private var deg:Number; private var dv:Number; public function Electron(sx:int,sy:int,tx:int,ty:int,l:int){ targetX = tx; targetY = ty; x = sx; y = sy; life = l; var lx:int = x-targetX; var ly:int = y-targetY; r = Math.sqrt( lx*lx + ly*ly)/life; deg = Math.atan2(ly, lx); dv = Math.random()*0.4-0.2; } public function move():void{ var nr:Number = r * life; deg += dv; x = targetX + nr * Math.cos(deg); y = targetY + nr * Math.sin(deg); life--; } } class Cell{ public var x:int; public var y:int; public var alive:Boolean = false; public var over:Boolean = false; public var count:int = 0; public var color:uint = 0; public var synapses:Vector.<Synapse>; public function Cell(px:int,py:int){ x = px; y = py; synapses = new Vector.<Synapse>(); changeColor(); } public function changeColor():void{ color = 0xFFFFFF*Math.random(); color = ColorUtil.adjustBrightness2(color,-50); color = ColorUtil.adjustBrightness(color,100); } public function pass():void{ changeColor(); for each(var synapse:Synapse in synapses){synapse.pass();} } public function setting():void{ over = ( ( alive && (count > Game.LIVE_MAX ) ) ||( (alive == false) && (count > Game.BIRTH_MAX ) ) ); alive = ( ( alive && (count >= Game.LIVE_MIN ) && (count <= Game.LIVE_MAX ) ) ||( (alive == false) && (count >= Game.BIRTH_MIN ) && (count <= Game.BIRTH_MAX ) ) ); count = 0; } public function change(e:Event = null):void{ alive = (alive == false); } } class Synapse{ public var target:Cell; public var strength:int; public function Synapse( t:Cell, stg:int = 1){ target=t; strength=stg; } public function pass():void{ target.count += strength; } } ライフゲーム