twitter ■お問い合わせ当サイトへのリンクサイト仕様

現在位置 > LostTechnology > JavaScript > 迷路生成

迷路生成

ランダムに迷路を作成するジェネレータです。長い間JavaScriptでプログラミングをしないでいると忘れてしまいそうなので、なんとなく作成してみました。W3C準拠のDOMとJavaScriptを実装したブラウザであれば動くはずです。

左上に出口を用意してあります。スタートはお好きなところからどうぞ。一応マウスカーソル下の色が変わるようになっています。Internet Explorerは7以降でないと色は変わりませんが、それは仕様です。

サイズ(×

サイズを指定して作成ボタンを押してください。サイズは奇数のみ有効です。偶数を指定した場合は+1します。縦も横も最大のサイズは255です。それ以上の数値を入力すると多くのブラウザではエラーになると思われます。
2009-5-19
ちょいと作ってみた。

JavaScript解説

それほど特殊なことは行なっていませんので、JavaScriptを勉強中の方がいたら参考になるかと思い、今回は軽く解説をつけておきます。使用した迷路の作成アルゴリズムは棒倒し法です。

var mazedata=new Array(256);
for (lp=0;lp<256;lp++) mazedata[lp]=new Array(256);

迷路の作成時に壁の有無を判定するための二次元配列mazedataの準備です。最大サイズを縦横ともに255を想定しています。

function intRandom(max) {
	return Math.floor(Math.random()*max);
}

乱数を得るための関数。0からmaxで指定した数値-1までの数が返ってきます。

function makeMaze(x,y) {
	/* 初期化 */
	if (x % 2==0) x++;
	if (y % 2==0) y++;
	document.getElementById('x').value=x;
	document.getElementById('y').value=y;
	wx=parseInt((x-3) / 2);
	wy=parseInt((y-3) / 2);
	/* 枠をつけて配列を作成 */
	for (lx=0;lx<x;lx++) {
		for (ly=0;ly<y;ly++) {
			(lx==0 || lx==x-1 || ly==0 || ly==y-1)?mazedata[lx][ly]='1':mazedata[lx][ly]='0';
		}
	}
	mazedata[0][1]='0';
	/* 柱と壁を作成 */
	for (lx=0;lx<wx;lx++) {
		for (ly=0;ly<wy;ly++) {
			mazedata[lx*2+2][ly*2+2]='1';
			do {
				sx=sy=0;
				switch (intRandom((ly==0)?4:3)) {
					case 0:sx=1; break;
					case 1:sx=-1; break;
					case 2:sy=1; break;
					case 3:sy=-1; break;
				}
			}
			while (mazedata[lx*2+2+sx][ly*2+2+sy]=='1');
			mazedata[lx*2+2+sx][ly*2+2+sy]='1';
		}
	}
	/* HTMLを生成 */
	mt='<table cellspacing="0" cellpadding="0">';
	for (ly=0;ly<y;ly++) {
		mt+='<tr>';
		for (lx=0;lx<x;lx++) {
			mt+=(mazedata[lx][ly]=='0')?'<td></td>':'<td class="wall"></td>';
		}
		mt+='</tr>';
	}
	document.getElementById('maze').innerHTML=mt+='</table>';
}

/* 初期化 */の部分は縦横のサイズが偶数だった場合に+1して、一応サイズを入力欄へ書き戻しています。変数wxとwyには棒倒し法で必要となる柱の数を入れました。

/* 枠をつけて配列を作成 */では外周の壁をmazedataに1、それ以外は通路となる0を入れて枠を作成しています。そして最後のは出口(0,1)を開ける処理です。

(プレビュー用エリア)

/* 柱と壁を作成 */の部分では縦横どちらも奇数となる部分に柱を置いていきます。棒倒し法はこの柱を基点に処理を行なうためです。棒倒し法では最上段の柱だけ柱の隣りならばどの方向に壁を作っても構いません。すでに壁ができているところへは置いてはいけないので、do~whileで置こうとしている場所に壁があるか調べて、壁があったら乱数を再生成して別の方向に壁を作ります。2段目からは上側に壁を作ってはいけないので、intRandom((ly==0)?4:3)の部分で乱数で3が出ないようにして阻止です。あとは一番下の柱のところまで処理を繰り返します。

/* HTMLを生成 */の部分では配列mazedataに格納されている壁の有無の情報をTABLEに変換しています。壁の部分はclassをwallにしてスタイルシートで色分けするようにHTMLを生成して出来上がりです。