読者です 読者をやめる 読者になる 読者になる

paper.jsでライフゲーム3(6角形)

6角形のライフゲーム

paper.jsによるライフゲーム 通常のライフゲームとは違い、6角形の格子構造。


前回までのライフゲームの一マス(4角形)を6角形に変更してみた。この状態でもライフゲームと呼ばれるのかはよくわからいけれど。

4角系の時と比べて、収束が早く、円環上になるとその形で止まる。ただし、一個でも余計なものがついているとそこから消滅していく。3つか4つで固まる場合が多い。


ソース

var width = view.viewSize.width;
var height = view.viewSize.height;

var cellSize =3;
var sides = 6;
var widthNum = Math.floor(width/(cellSize* Math.sqrt(3)));
var heightNum = Math.floor(height/(cellSize*1.5));
var cells = [];

var maxCount  = 126;

function defaultAlign(){
  var cellWidth =  Math.sqrt(3)*cellSize;
  var cellHeight = cellSize*1.5;
  var cell;

  for( var w =0;w < widthNum;w++){
    cells[w] = new Array();
    for( var h =0;h< heightNum;h++){

      if( h%2 === 0 ){
        var center = new Point((w+0.5)*cellWidth,h*cellHeight);
      } else if ( h%2 === 1 ){
        var center = new Point(w*cellWidth,h*cellHeight);
      }

      cell = new Path.RegularPolygon( center, sides, cellSize );
      cell.strokeColor = '#fafafa';
      cell.strokeWidth = 1;
      cells[w][h] = cell;
    }
  }
}

function setcell(){
  for( var w =0;w < widthNum;w++){
    for( var h =0;h< heightNum;h++){
      cells[w][h].fillColor
        = new HsbColor(w*360/widthNum*2,h*1/(heightNum*1.5)+0.2,1);
      cells[w][h].visible = Math.floor(Math.random()+0.25) >= 1;
      cells[w][h].preVisible = cells[w][h].visible;
    }
  }
}

function onFrame( event ){
  if( event.count % maxCount !== 0 ) return;

  for( var w =0;w < widthNum;w++){
    for( var h =0;h< heightNum;h++){
       neibhorCalcuate( w, h );
     }
  }
  for( var w =0;w < widthNum;w++){
    for( var h =0;h< heightNum;h++){
      cells[w][h].preVisible = cells[w][h].visible;
    }
  }
}

function neibhorCalcuate( w, h ){
  var sum = 0;
  var hue = 0;
  var saturation = 0;
  var brightness  = 0;

  if( h%2=== 0 ){
    var list = [{x:w,y:h-1},{x:w+1,y:h-1},{x:w-1,y:h},{x:w+1,y:h},{x:w,y:h+1},{x:w+1,y:h+1}];
  } else if( h%2=== 1 ){
    var list = [{x:w-1,y:h-1},{x:w,y:h-1},{x:w-1,y:h},{x:w+1,y:h},{x:w-1,y:h+1},{x:w,y:h+1}];
  }

  for( var i =0,len =list.length;i<len;i++){
    var x = list[i].x;
    var y = list[i].y;
    if ( cells[x] && cells[x][y] && cells[x][y].preVisible ){
      sum++;
      hue += cells[x][y].fillColor.hue;
      saturation += cells[x][y].fillColor.saturation;
      brightness  += cells[x][y].fillColor.brightness;
    }
  }

  if ( cells[w][h].preVisible ){
    if(  sum < 2 ||  4  <= sum){
      cells[w][h].visible = false;
    }
  } else {
    if( sum === 3){
      cells[w][h].visible =true;

      if( Math.random() > 0.8 ){
        brh  = Math.random()+0.7;
      } else{
        brh = brightness /sum;
      }

      cells[w][h].fillColor =  new HsbColor(hue/sum,saturation/sum,brh);
    }
  }
}

function onMouseDown(){
  setcell();
}

defaultAlign();
setcell();

100行ぐらいしかないものの、ブログに載せるには少し長いのでもう少し短くしたい。

変更点


  • RegularPolygonで6角系のpathを生成
  • 敷き詰めるために偶数列とき数列が互い違いになるように配置
  • 全体の数が少なくなって負荷が減ったので見栄え用に枠線を追加
  • 色のばらつきがすくなるように調整
  • 判断するセルを周囲6個になるように調整
  • コード簡略化