ライフゲームとか。

昨日、ライフゲーム*1を作る流れが86辺りであったので、時代に乗り遅れつつ書いてみた。
みんなRubyとかで書いてて見た目つまんないのでJavaScriptで。


んで、出来たのはこんな感じ。
http://negator.s56.xrea.com/junk/lifegame.html


アルゴリズムとかどっか間違ってるかもしれん。あんまちゃんと確認してないので。
作成時間は…どんくらいだ?多分3,4時間くらいです。
ライフゲームアルゴリズムより言語周りでやたら時間食った。
たまには普段使わない言語も触っておかないと駄目ですね。


ソースは以下。へたれなので長いよ。

<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
	<head>
		<title>Lifegame</title>
		<style type="text/css">
		<!--
			td {height: 16px; width: 16px;}
			td.dead {background-color: red;}
			td.live {background-color: green;}
		-->
		</style>
	</head>
		<form>
			h:<input type="text" id="height" value="24" />
			w:<input type="text" id="width" value="24" />
			<a href="javascript: start();">start</a>
			<a href="javascript: clearInterval(intervalId);">stop</a>
		</form>
		<table>
			<tbody></tbody>
		</table>
		
	<body>
		<script type="text/javascript" language="JavaScript">
		<!--	
			var Lifegame = function() {
				this.h = 0;
				this.w = 0;
				this.cell = [];
			}
			Lifegame.prototype = {
				init : function(h,w) {
					this.h = h;
					this.w = w;
					this.cell = new Array(h);
					for(var i = 0; i < h; ++i) {
						this.cell[i] = new Array(w);
						for(var j = 0; j < w; ++j) {
							this.cell[i][j] = (Math.random()*6 < 1) ? 1 : 0;
						}
					}
				},
				getEnv : function(h,w) {
					var c = 0;
					
					for(var i = -1; i <= 1; ++i) {
						var y = h+i;
						if(y < 0) { y = this.h-1; }
						if(y >= this.h) { y = 0; }
						for(var j = -1; j <= 1; ++j) {
							if (i==0&&j==0) { continue; }
							var x = w+j;
							if(x < 0) { x = this.w-1; }
							if(x >= this.w) { x = 0; }
							c += this.cell[y][x];
						}
					}
					
					return c;
				},
				next : function() {
					newCell = new Array(this.h);
					for(var i = 0; i < this.h; ++i) {
						newCell[i] = new Array(this.w);
					}
					
					for(var i = 0; i < this.h; ++i) {
						for(var j = 0; j < this.w; ++j) {
							var env = this.getEnv(i,j);
							if(this.cell[i][j]==0 && env==3) {
								newCell[i][j] = 1;
							} else if(this.cell[i][j]==1 && (env==2 || env==3)) {
								newCell[i][j] = 1;
							} else {
								newCell[i][j] = 0;
							}
						}
					}
					
					this.cell = newCell;
				}
			}
			var lifegame = new Lifegame();
			
			var Board = function() {
				this.h = 0;
				this.w = 0;
			}
			Board.prototype = {
				init : function() {
					this.h = parseInt(document.getElementById("height").value);
					this.w = parseInt(document.getElementById("width").value);
					
					//table
					var table = document.createElement("table");
					var tbody = document.createElement("tbody");
					for(var i = 0; i < this.h; ++i) {
						var row = document.createElement("tr");
						for(var j = 0; j < this.w; ++j) {
							var col = document.createElement("td");
							col.setAttribute("class", "dead");
							row.appendChild(col);
						}
						tbody.appendChild(row);
					}
					table.appendChild(tbody);
					
					var oldTable = document.getElementsByTagName("table")[0];
					document.getElementsByTagName("body")[0].replaceChild(table, oldTable);
					
					lifegame.init(this.h, this.w);
				},
				draw : function() {
					var table = document.getElementsByTagName("td");
					for(var i = 0; i < this.h; ++i) {
						for(var j = 0; j < this.w; ++j) {
							table[i*this.w+j].setAttribute("class",(lifegame.cell[i][j]!=0) ? "live" : "dead");
						}
					}
				}
			}
			var board = new Board();
			
			var intervalId = 0;
			function start() {
				if(intervalId != 0) {
					clearInterval(intervalId);
				}
				board.init();
				board.draw();
				intervalId = setInterval(function() {
					lifegame.next();
					board.draw();
					}, 2000);
			}
		//-->
		</script>
	</body>
</html>


追記:
setAttribute("class",~)などとしているのでIEでは動かない罠を発見した。
IE爆発しろ。

*1:ルールはこの辺参照:ライフゲーム - Wikipedia