概要
Javascript学習のスタートアップのために試作したもの。
内部に配列を持ち、世代交代の結果を文字ベースで表示し、setInterval()で更新している。
htmlのdiv要素内に文字ベースで表示している。
デモンストレーション
このアプリケーションは文字ベースなため、ブラウザやスタイルによって大変見にくい。別ページで用意したこのアプリケーションで、ブラウザによっては見やすくなる場合がある
パターン選択
実行
表示エリア
コード内容
HTML
カテゴリーごとの初期パターン選択ボタン、起動/停止ボタン、表示エリアを表示させている。
| 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 | <div> <h3>パターン選択</h3> 移動体 <input type="button" value="Grider" onclick="patternGrider()"> <input type="button" value="L-Spaceship" onclick="patternSpaceshipL()"> <input type="button" value="M-Spaceship" onclick="patternSpaceshipM()"> <input type="button" value="H-Spaceship" onclick="patternSpaceshipH()"> <br> 周期型 <input type="button" value="Octagon" onclick="patternOctagon()"> <input type="button" value="Nebula" onclick="patternNebula()"> <br> 長寿型 <input type="button" value="Die hard" onclick="patternDiehard()"> <br> ランダム <input type="button" value="Random" onclick="patternRandom()"> </div> <div> <h3>実行</h3> <input type="button" value="start/stop" onclick="startAndStop()"> </div> <div> <h3>表示エリア</h3> <div id="display_area"></div> <script src="./js/app_lifegame1.js"></script> | 
JavaScript
グローバルな二次元配列にセルの情報を保持し、配列上で世代交代の処理をしたうえで、HTMLに書き出している。初期パターンの選択は、パターンごとの設定用関数を準備し、ボタンで呼び出している。主な処理ブロックは以下の通り。
- グローバル処理
- グローバル変数の宣言と初期値定義を行っている。
- 初期パターン選択
- 各パターンのボタンのクリックに応じて、パターンごとに準備された関数が呼び出され、初期pターンの設定と表示を行う。
- 起動・停止
- ボタンのクリックによって、一定時間間隔で世代交代関数を実行させ、停止させる。
- 世代交代
- ライフゲームのルールに従い、一世代後のパターンを決定し、表示する。
グローバル処理
- 共通して利用する変数の宣言/定義
- グリッドの初期化
- 初期状態のグリッドの表示
| 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 36 37 38 39 40 41 42 | var isRunning = false; var timer; var rows = 20; var cols = 20; // エリアサイズ+2のグリッドを確保 var cell = new Array( rows + 2 ); for ( var i = 0; i <= rows + 1; i++ ) {   cell[i] = new Array( cols + 2 ); } // 更新用のグリッドを確保 var newCell = new Array( rows + 2 ); for ( var i = 0; i <= rows + 1; i++ ) {   newCell[i] = new Array( cols + 2 ); } initialize(); display(); function initialize() {   for ( var i = 0; i <= rows + 1; i++ ) {     for ( var j = 0; j <= cols + 1; j++ ) {       cell[i][j] = 0;       newCell[i][j] = 0;     }   } } function display() {   var displayArea = document.getElementById( "display_area" );   displayArea.innerHTML = "";   for ( var i = 1; i <= rows; i++ ) {     for ( var j = 1; j <= cols; j++ ) {       displayArea.innerHTML += ( cell[i][j] == 0 ) ? "□" : "■";     }     displayArea.innerHTML += "<br>";   } } | 
初期パターン選択
ボタンで選択された初期パターンに対応した設定関数が呼び出される。設定関数はパターンごとに準備され、配列リテラルの内容を、グリッドの”ほぼ中央”にコピーする。
| 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 36 37 38 39 40 41 | function patternGrider() {   initialize();   var pattern = [     [1,1,1],     [1,0,0],     [0,1,0]   ];   copyPattern( pattern );   display(); } function patternSpaceshipL() {   initialize();   var pattern = [     [0,1,0,0,1],     [1,0,0,0,0],     [1,0,0,0,1],     [1,1,1,1,0]   ];   copyPattern( pattern );   display(); } function copyPattern( pattern ) {   var patternRow = pattern.length;   var patternCol = pattern[0].length;   var startRow = Math.floor( rows / 2 ) - Math.floor( patternRow / 2 );   var startCol = Math.floor( cols / 2 ) - Math.floor( patternCol / 2 );   for ( var i = 0; i < patternRow; i++ ) {     for ( var j = 0; j < patternCol; j++ ) {       cell[startRow + i][startCol + j] = pattern[i][j];     }   } } | 
起動・停止
起動・停止のボタンが押されるたびに、稼働状態/停止状態がスイッチする。稼働時には、一定時間間隔で関数life()を呼び出している。life()関数内では、世代交代を施した後、表示をさせる。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function startAndStop() {   if ( isRunning ) {     clearInterval( timer );     isRunning = false;   } else {     timer = setInterval( "life()", 500 );     isRunning = true;   } } function life() {   nextGeneration();   display(); } | 
世代交代
あるセルの次世代の状態は、そのセル自身の状態と、その周囲8つのセルの数によって定められる。
| 存在 | 不在 | |
|---|---|---|
| 0~1 | 死滅 | 不在 | 
| 2 | 存在 | 不在 | 
| 3 | 存在 | 誕生 | 
| 4~ | 死滅 | 不在 | 
| 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 | function nextGeneration() {   var n;   for ( var i = 1; i <= rows; i++ ) {     for ( var j = 1; j <= cols; j++ ) {       n = numOfNeighbors( i, j );       if ( n <= 1 )         newCell[i][j] = 0;       else if ( n == 2 )         newCell[i][j] = cell[i][j];       else         if ( n == 3 ) newCell[i][j] = 1;       else         newCell[i][j] = 0;     }   }   for ( var i = 0; i <= rows + 1; i++ ) {     for ( var j = 0; j <= cols + 1; j++ ) {       cell[i][j] = newCell[i][j];     }   } } function numOfNeighbors( i, j ) {   var count = 0;   count += cell[i-1][j-1] + cell[i-1][j] + cell[i-1][j+1];   count += cell[i][j-1] + cell[i][j+1];   count += cell[i+1][j-1] + cell[i+1][j] + cell[i+1][j+1];   return count; } |