知らないことを調べるブログ

映画の分からないところを調べてまとめる場所にしていきます。

ルール90(HTML5+JavaScript)

つくった


ルール90の1次元セル・オートマトンは典型的なフラクタル図形であるシェルピンスキーのギャスケットを生成する。(WolframAlphaでルール90を見る→rule 90)

現在の状態 中央のセルの次の状態
000 0
001 1
010 0
011 1
100 1
101 0
110 1
111 0
セル・オートマトン - Wikipedia

きれい・・・


ソースコード。70行ぐらい

<canvas id="world"></canvas>
<script type="text/javascript">

/* グローバル変数の宣言 */
var SCREEN_SIZE = 360; // キャンバスの大きさ
var CELL_SIZE = 2; // セルの大きさ
var FPS = 60; // フレームレート
var canvas; //= document.getElementById('world');
var ctx; //= canvas.getContext('2d');
var cell = new Array();
var temp;

function start() {
  /* 初期化処理と開始処理 */
  canvas = document.getElementById('world'); // canvas要素を取得
  canvas.width = canvas.height = SCREEN_SIZE; // キャンバスのサイズを設定
  ctx = canvas.getContext('2d');                // コンテキスト
  ctx.fillStyle = 'rgb(0, 0, 0)';          // 色
  for(var i = 0; i < SCREEN_SIZE / CELL_SIZE; i++){
    cell[i] = new Array();
  }
  for(var i = 0; i < SCREEN_SIZE / CELL_SIZE; i++){ // 0で初期化
    for(var j = 0; j < SCREEN_SIZE / CELL_SIZE; j++){
      cell[i][j] = 0;
    }
  }
  cell[0][Math.floor(Math.random() * (SCREEN_SIZE / CELL_SIZE)) + 1] = 1; // 単一の初期値をランダムに決定
  update();   // ループ開始
}

function update() { // 計測とキャンバスの描画処理
  for(var i = SCREEN_SIZE / CELL_SIZE - 1; i > 0; i--){ // セルの世代を進める
    for(var j = SCREEN_SIZE / CELL_SIZE; j > 0; j--){
      temp = cell[i][j];
      cell[i][j] = cell[i - 1][j];
      cell[i - 1][j] = temp;
    }
  }
  for(var i = 0; i < SCREEN_SIZE / CELL_SIZE; i++){ // 新しい世代を誕生させる
    if(cell[1][i - 1] == 1 && cell[1][i] == 1 && cell[1][i + 1] == 1){
      cell[0][i] = 0;
    } else if(cell[1][i - 1] == 1 && cell[1][i] == 1 && cell[1][i + 1] == 0){
      cell[0][i] = 1;
    } else if(cell[1][i - 1] == 1 && cell[1][i] == 0 && cell[1][i + 1] == 1){
      cell[0][i] = 0;
    } else if(cell[1][i - 1] == 1 && cell[1][i] == 0 && cell[1][i + 1] == 0){
      cell[0][i] = 1;
    } else if(cell[1][i - 1] == 0 && cell[1][i] == 1 && cell[1][i + 1] == 1){
      cell[0][i] = 1;
    } else if(cell[1][i - 1] == 0 && cell[1][i] == 1 && cell[1][i + 1] == 0){
      cell[0][i] = 0;
    } else if(cell[1][i - 1] == 0 && cell[1][i] == 0 && cell[1][i + 1] == 1){
      cell[0][i] = 1;
    } else if(cell[1][i - 1] == 0 && cell[1][i] == 0 && cell[1][i + 1] == 0){
      cell[0][i] = 0;
    }
  }
  
  draw(); // canvasを更新
  setTimeout(update, 1000/FPS); // ミリ秒後に再帰
}

function draw() { // キャンバスの描画処理。update関数で呼び出される
  ctx.clearRect(0, 0, SCREEN_SIZE, SCREEN_SIZE); // 画面をクリア
  for(var i = 0; i < SCREEN_SIZE / CELL_SIZE; i++){ // セルの状態が1なら描画する
    for(var j = 0; j < SCREEN_SIZE / CELL_SIZE; j++){
      if(cell[i][j] == 1) ctx.fillRect(j * CELL_SIZE, (SCREEN_SIZE / CELL_SIZE - i) * CELL_SIZE, CELL_SIZE, CELL_SIZE);
    }
  }
}

start();
</script>