ライフゲーム 修正版
修正してみた。
- 指摘された点の改良
- 無駄なループの削減
- 世代を表示
- 停止判定ロジックの追加
<html> <head> <style type="text/css"> * { margin: 0; padding: 0; } p { padding: 10px; font-size: 200%; } </style> <script type="text/javascript"> lifegame = function() { var size = 15; // フィールドサイズ。定数 var field; // フィールド var age = 0; // 世代 var stop = false; // 停止するかどうか // フィールドの初期化 // 初期の生きセルはランダムに生成 var init = function() { field = new Array(size); for (var i = 0; i < size; i++) { field[i] = new Array(size); for (var j = 0; j < size; j++) { field[i][j] = (parseInt(Math.random() * 10) % 3 == 0) ? true : false; } } }; // 次世代のフィールドを生成 var createNextField = function() { var nextField = new Array(size); for (var i = 0; i < size; i++) { nextField[i] = new Array(size); for (var j = 0; j < size; j++) { var c = getAliveCellCount(i, j) nextField[i][j] = birth(i, j, c) || keep(i, j, c); } } return nextField; }; // 生きてるセルのカウントアップ var getAliveCellCount = function(i, j) { var c = 0; for (var x = -1; x <= 1; x++) { if (i + x < 0 || i + x >= size) continue; for (var y = -1; y <= 1; y++) { if (j + y < 0 || j + y >= size || (x == 0 && y == 0)) continue; if (field[i+x][j+y] == true) c++; } } return c; }; // 誕生するか? var birth = function(i, j, c) { if (field[i][j] == true) return false; return (c == 3) ? true : false; }; // 維持するか? var keep = function(i, j, c) { if (field[i][j] == false) return false; return (c == 2 || c == 3) ? true : false; }; // 停止判定 // 現世代のフィールドと次世代のフィールドが完全に同一だった場合、停止とみなす var isStop = function(nextField) { if (field.length != nextField.length) return false; for (var i = 0; i < size; i++) { if (field[i].length != nextField[i].length) return false; for (var j = 0; j < size; j++) { if (field[i][j] != nextField[i][j]) return false; } } return true; } // 描画用文字列を作成 var createDrawBuffer = function() { var buf = ""; for (var i = 0; i < size; i++) { for (var j = 0; j < size; j++) { buf += field[i][j] ? "■" : "□"; } buf += "<br>"; } if (stop) { buf+= "第" + age + "世代にて停止"; } else { age++; buf += "第" + age + "世代"; } return buf; }; // public methods return { exec : function() { if (typeof(field) == "undefined") { init(); } else { var nextField = createNextField(); if (isStop(nextField)) { stop = true; } field = nextField; } document.getElementById("area").innerHTML = createDrawBuffer(); } }; }(); window.onload = function(){setInterval(lifegame.exec, '1000');}; </script> </head> <body> <p id="area"></p> </body> </html>