足し算をするセルオートマトン - celllular automaton do addition

by shohei909
LIVE CODING 2010/06/25 19:17-1:22
変形ライフゲームみたいなものですが、
OR回路,AND回路が作れたので、
マスの点灯、消灯を数字に対応させて、
二進数の足し算をやらせてみました。
♥5 | Line 324 | Modified 2015-04-04 22:54:38 | MIT License
play

ActionScript3 source code

/**
 * Copyright shohei909 ( http://wonderfl.net/user/shohei909 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/rG7W
 */

    /*
LIVE CODING 2010/06/25 19:17-1:22
変形ライフゲームみたいなものですが、
OR回路,AND回路が作れたので、
マスの点灯、消灯を数字に対応させて、
二進数の足し算をやらせてみました。

※答えを出すまでのタイムラグがあります。
 すべてのセルが変化がなくなったら答えです。





セルの光り方のルール
the rule of this celllular automaton.

    1. セルは合計 1 の電流が流れているとき、黄色く光る。
      流れる電流の合計が 2 以上になると、暗く赤に光る。
      The cell is yellow, if it is applied one electrical current,
      and is dark red, if it is applied two or more electrical currents.
      
    2. 黄色く光ったセルは、そのセルとつながったセルに電流を伝える。
      The yellow cell apply the current to cells connected.
      
      
    3. セルのつながり方には弱いつながり(>)と強いつながり(>>)の二種類があり、
      弱くつなっがったセルには 1 の電流を伝える。
      強くつながったセルには 2 の電流を伝える。
      また、つながりは一方通行である。
      There are two types of the connections, weak connection(>) and strong connection(>>).
      To the cell weak connected, it apply one current.
      To the cell strong connected, it apply two currents.
      
    セルのつながり方
    the connection of cells
        0  , 1  , 2  , 3  , 4  , 5  ;
        6  , 7  , 8  , 9  , 10 , 11 ;
        12 , 13 , 14 , 15 , 16 , 17 ;
        18 , 19 , 20 , 21 , 22 , 23 ;
        24 , 25 , 26 , 27 , 28 , 29 ;
        30 , 31 , 32 , 33 , 34 , 35 ;
        
        0: >4 
        1: >4
        2: >5
        3: >5
        4: >5
        5: >14, >15, >32
        6: >6, >24, >25, >>26, >35
        7: >7, >12, >13, >>14, >23
        8: >8, >0, >1, >>2, >11
        9: >9, >10, >22
        10: >29
        11: >33 
        12: >16
        13: >16
        14: >17
        15: >17
        16: >17
        17: >26, >27, >31
        18: >18, >>25, >>27, >35
        19: >19, >>13, >>15 >23
        20: >20, >>1, >>3, >11
        21: >21, >>22
        22: >29
        23: >32
        24: >28
        25: >28
        26: >30
        27: >30
        28: >30
        29: >2, >3, >33
        35: >31
        
        
        6,7,8,9 を x に 、
        18,19,20,21 を y に、
        30,31,32,33,34 を z に対応させると、
        x + y = z の の答えを出してくれる。
        
        
        
    この変形ライフゲームと遺伝的アルゴリズムを使って、
    思考回路の自動生成ができないかなぁ、と思ってる。
*/
package {
    import flash.display.Sprite;
    import com.bit101.components.*;
    import flash.events.Event;
    
    public class FlashTest extends Sprite {
        private var brain:Medium;
        private var game:Game;
        private var btn1:Array;
        private var btn2:Array;
        private var ans:Label;
        
        public function FlashTest() {
            game = new Game();
            brain = game.brain;
            game.x = 130;
            game.y = 50;
            
            with(graphics){
                beginFill (0x000010, 1.0);    // 面のスタイル設定
                drawRect  ( 0, 0 , 465 , 465);
            }
            
            Style.fontSize = 8;
            Style.BACKGROUND = 0x808080;
            Style.BUTTON_FACE = 0x606060;
            Style.LABEL_TEXT = 0xaaaaaa;
            Style.DROPSHADOW = 3;
            Style.PANEL = 0x303030;
            Style.PROGRESS_BAR = 0x404040;
            
            
            
            var panel:Panel = new Panel(this,83,93);
            panel.setSize(300,220);
            panel.content.addChild(game);
            var x:int = 15;
            var y:int = 75;
            var w:int = 25;
            var h:int = 25;
            
            var power:PushButton = new PushButton(panel,10,10,"power",brain.player);
            power.toggle= true; 
            power.selected = true;
            power.setSize(40,16);
            
            var reset:PushButton = new PushButton(panel,60,10,"reset",brain.reset);
            reset.setSize(40,16);
            
            
            
            
            btn1 = new Array();
            for(var i:int = 0;i<4;i++){    
                btn1[i] = new PushButton(panel,x+w*i,y,"0",brain.cells[i+6].change );
                btn1[i].setSize(w+1,h+1);
            }

            y += 50;
            btn2 = new Array();
            for(i=0;i<4;i++){    
                btn2[i] = new PushButton(panel,x+w*i,y,"0",brain.cells[i+18].change );
                btn2[i].setSize(w+1,h+1);
            }
            
            x = 60;
            var lbl:Label = new Label(panel,x,105,"+");
            var lbl2:Label = new Label(panel,x,155,"=");
            ans = new Label(panel,x-10,180,"");
                
            addEventListener("enterFrame",loop);
        }
        

        private function loop(e:Event):void{
            
            for(var i:int=0;i<4;i++){
                if(brain.cells[i+6].elect == true){    
                    btn1[i].label = "1";
                }else{
                    btn1[i].label = "0";
                }
            }
            for(i=0;i<4;i++){
                if(brain.cells[i+18].elect == true){    
                    btn2[i].label = "1";
                }else{
                    btn2[i].label = "0";
                }
            }
            brain.loop();
            ans.text="";
            for(i=0;i<5;i++){
                if(brain.cells[i+30].elect == true){    
                    ans.text += "1";
                }else{
                    ans.text += "0";
                }
            }
        }
    }
}
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.*;

class Game extends Sprite{
    public var _WIDTH:int = 6;
    public var _HEIGHT:int = 6;
    public var _SCALE:int = 25;
   public var brain:Medium;
    public function Game():void{
        brain = new Medium(6,6,25);
        addChild(brain);
        addEventListener("mouseDown",onDown);
    }
    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);
    }
}
 
class Medium extends Bitmap{
    public var cWidth:int = 0;
    public var cHeight:int = 0;
    public var cellSize:int = 25;
    public var play:Boolean = true;
    public var cells:Vector.<Cell>;
    public var electrons:Vector.<Electron>;
    
    private var count:int = 0;
    private var span:int = 15;
    private var nowMap:BitmapData;
    
    public function Medium(w:int, h:int, s:int){
        cWidth = w; cHeight = h; cellSize = s;
        electrons = new Vector.<Electron>();
        cells = new Vector.<Cell>();
        for(var i:int=0;i<cWidth;i++){
            for(var j:int=0;j<cHeight;j++){
                cells[i*cHeight + j] = new Cell(j,i);
            }
        }
        
        
        
        //接続の設定
        conect(0,4);
        conect(1,4);
        conect(2,5);
        conect(3,5);
        conect(4,5);
        
        
        conect(5,15);conect(5,14);conect(5,32);
        
        conect(6,6);conect(6,24);conect(6,25);conect(6,26,true);conect(6,35);
        conect(7,7);conect(7,12);conect(7,13);conect(7,14,true);conect(7,23);
        conect(8,8); conect(8,0);conect(8,1);conect(8,2,true);conect(8,11);
        conect(9,9); conect(9,10);conect(9,22);conect(9,34);
        conect(10,29);
        
        conect(11,33);
        
        conect(12,16);
        conect(13,16);
        conect(14,17);
        conect(15,17);
        conect(16,17);
        
        conect(17,26);conect(17,27);conect(17,31);
        
        conect(18,18); conect(18,25,true);conect(18,27,true);conect(18,35);
        conect(19,19); conect(19,13,true);conect(19,15,true);conect(19,23);
        conect(20,20);conect(20,1,true);conect(20,3,true);conect(20,11);
        conect(21,21);conect(21,22,true);conect(21,34);
        conect(22,29);
        
        conect(23,32);
        
        conect(24,28);
        conect(25,28);
        conect(26,30);
        conect(27,30);
        conect(28,30);
        
        conect(29,2);conect(29,3);conect(29,33);
        
        conect(35,31);
        
        
        
        
        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.elect = false;
            cell.weak = false;
            cell.strong = false;
        }
    }


    public function loop():void{
        drow();
        count++;
        if(count%span == 0 && play){
            for each(var cell:Cell in cells){
                cell.setting();
            }
            
            for(var i:int=0; i<cWidth; i++){
                for(var j:int=0; j<cHeight; j++){
                    cell = cells[i+j*cWidth];
                    if(cell.elect){
                        for each(var syn:Synapse in cell.conection){
                            var sx:Number = (cell.x+1/2) * cellSize;
                            var sy:Number = (cell.y+1/2) * cellSize;
                            var tx:Number = (syn.target.x+1/2) * cellSize;
                            var ty:Number = (syn.target.y+1/2) * cellSize;
                            var el:Electron = new Electron( sx,sy,tx,ty,span );
                            electrons.push(el);
                            if(syn.strong){
                                el = new Electron( sx,sy,tx,ty,span );
                                electrons.push(el);
                            }

                        }
                        cell.pass();
                    }
                }
            }
        }
     }      
     public function conect(st:int, en:int,s:Boolean =false):void{
        if(en>=0 && en < cells.length){
            cells[st].conection.push( new Synapse(cells[en],s));
        }
    }
    
    public function drow():void{
        for(var i:int=0; i<cWidth; i++){
            for(var j:int=0; j<cHeight; j++){
                var cell:Cell = cells[i+j*cWidth];
                var rect:Rectangle = new Rectangle(i*cellSize+2,j*cellSize+2,cellSize-2,cellSize-2);
                if(cell.strong){        
                    nowMap.fillRect(rect, 0x261111);
                }else if(cell.weak){
                    nowMap.fillRect(rect, 0xFFDD22);
                }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(el,mtr);
            if(el.life == 0){ 
                electrons.splice(i,1);
                i--;
            }else{ el.move(); }
        }
       
        rect = new Rectangle(0,0,cellSize*cWidth,cellSize*cHeight);
        var point:Point = new Point(0,0);
        var rate:uint = 0x40;
        bitmapData.merge(nowMap,rect,point,rate,rate,rate,rate);   
        nowMap.fillRect(rect,0x000000); 
    }
}

class Electron extends Sprite{
    public var targetX:Number;
    public var targetY:Number;
    public var life:int;
    private var r:Number;
    private var deg:Number;
    private var dv:Number;
    
    public function Electron(sx:Number,sy:Number,tx:Number,ty:Number,l:int){
        targetX = tx;
        targetY = ty;
        x = sx;
        y = sy;
        
        life = l;
        var lx:Number = x-targetX;
        var ly:Number = y-targetY;
        r = Math.sqrt( lx*lx + ly*ly);
        deg = Math.atan2(ly, lx);
        dv = Math.random()*0.4-0.2;
        filters = [new GlowFilter(0x00AAFF)]
        
        with(graphics){
            beginFill (0xFFFFFF, 1.0);
            drawCircle( 0, 0 ,2);
        }

    }
    public function move():void{
        r = r * (life-1)/life;
        deg += dv;
        x = targetX + r * Math.cos(deg);
        y = targetY + r * Math.sin(deg);
        life--;
        if(life == 0){
        }else{
            with(graphics){
                clear();
                beginFill (0xFFFFFF, life/(life+5));
                drawCircle( 0, 0 ,2*(life+1)/life);
            }
        }
 
    }

}

class Cell{ 
    public var x:int;
    public var y:int;
    public var elect:Boolean = false;
    public var weak:Boolean = false;
    public var strong:Boolean = false;
    public var conection:Vector.<Synapse>;
    public function Cell(px:int,py:int){
        x = px;
        y = py;
        conection = new Vector.<Synapse>();
    }
    public function pass():void{
        for each(var synapse:Synapse in conection){synapse.pass();}
    }
    public function setting():void{
        if(weak && strong==false){
            elect = true;
        }else{
            elect = false;
        }
        weak = false;
        strong = false;
    }
    
    public function change(e:Event):void{
        if(elect){
            elect = false;
            weak = false;
            strong = false;
        }else{
            elect = true;
            weak = true;
            strong = false;
        }
    }
}

class Synapse{
    public var target:Cell;
    public var strong:Boolean;
    public function Synapse( t:Cell, stg:Boolean = false ){
        target=t; strong=stg;
    }
    public function pass():void{
        if(strong || target.weak){
            target.strong = true;
        }else{
            target.weak = true;
        }
    }
}

Forked