幅:
高さ:
どうも!LSSです!!
昨日の【JavaScript】自動生成迷路!を手直ししてみました。
変更点
ぱっと見で分かる通り、「壁が薄いタイプ」の迷路にしました。
実は元の迷路自体、奇数列・行と偶数列・行で壁か通路かがわかれるタイプの迷路だったので、列ごとの幅・行ごとの高さを変更するだけでしたがw
また、壁の色も黒ベタから濃灰色に変更しています。
特に迷路として見る分には支障ないと思いますが、どうでしょう?
※ここから下、JavaScriptについてつらつら書いています。
コード
<p>幅:<br /><input id="rgx" style="width: 100%;" max="60" min="5" type="range" value="15" /></p>
<p>高さ:<br /><input id="rgy" style="width: 100%;" max="60" min="5" type="range" value="10" /></p>
<div id="gamen"> </div>
<script>// <![CDATA[
xmax=0;
ymax=0;
mztxt='';
dd=0;
mps=[];
mz=(ax,ay)=>ax<0 || ax>=xmax || ay<0 || ay>=ymax?0:parseInt(mztxt.substr(ax+ay*xmax,1));
mzw=(ax,ay)=>{mztxt=mztxt.substr(0,ax+ay*xmax)+'0'+mztxt.substr(ax+ay*xmax+1);}
makemaze();
rgx.addEventListener('input',makemaze,false);
rgy.addEventListener('input',makemaze,false);
function makemaze(){
xmax=parseInt(rgx.value)*2+1;
ymax=parseInt(rgy.value)*2+1;
mztxt='';
for(i=0;i<xmax*ymax;i++){
mztxt+='1';
}
mps.splice(0);
mps.push([1,1]);
mzw(1,1);
dd=1;
do{
mpi=Math.floor(Math.random()*mps.length);
if(mz(mps[mpi][0]-2,mps[mpi][1])+mz(mps[mpi][0]+2,mps[mpi][1])+mz(mps[mpi][0],mps[mpi][1]-2)+mz(mps[mpi][0],mps[mpi][1]+2)==0){mps.splice(mpi,1);}else{
dig(mps[mpi][0],mps[mpi][1]);
}}while(dd<Math.floor(xmax/2)*Math.floor(ymax/2));
txt='幅 '+rgx.value+' /高さ '+rgy.value+'<br/>';
txt+='<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" viewbox="0 0 '+(Math.floor(xmax/2)+0.2)+' '+(Math.floor(ymax/2)+0.2)+'">';
txt+='<defs>';
txt+='<path id="svgs" d="M 0.9,0.2 L 0.3,0.4 0.8,0.7 0.2,0.9" stroke-width="0.14" stroke="#ff4444" fill="none"></path>';
txt+='<path id="svgg" d="M 0.9,0.4 L 0.6,0.3 0.3,0.4 0.3,0.7 0.6,0.8 0.85,0.7 0.85 0.85" stroke-width="0.14" stroke="#ff4444" fill="none"></path>';
txt+='</defs>';
for(j=0;j<ymax;j++){for(i=0;i<xmax;i++){
if(mz(i,j)==1){txt+='<rect x="'+Math.floor(i/2)+'" y="'+Math.floor(j/2)+'" width="'+(i%2==0?0.1:1)+'" height="'+(j%2==0?0.1:1)+'" fill="#444444" stroke-width="0" stroke="#444444"></rect>';}
if(i==1 && j==1){txt+='<use xlink:href="#svgs" x="'+Math.floor(i/2)+'" y="'+Math.floor(j/2)+'"/>'};
if(i==xmax-2 && j==ymax-2){txt+='<use xlink:href="#svgg" x="'+Math.floor(i/2)+'" y="'+Math.floor(j/2)+'"/>'};
}}
txt+='</svg>';
gamen.innerHTML=txt;
}
function dig(xd,yd){
vt=Math.floor(Math.random()*4);
vy=Math.floor(vt/2-0.5);
vx=(vt*2-3)-vy*3;
if(mz(xd+vx*2,yd+vy*2)==1){
mzw(xd+vx*2,yd+vy*2);
mzw(xd+vx,yd+vy);
xd+=vx*2;yd+=vy*2;
mps.push([xd,yd]);
dig(xd,yd);
dd++;
}
}
// ]]></script>
JavaScriptで配列変数のリセット
昨日のコード中で、
mps=[];
を2回、書いていました。
片方は、配列変数mpsをグローバル変数として宣言するため、もう一方は function makemaze() の中で配列をリセットするため。
それで問題なく動作はしていたのですが、
「宣言と同じ書き方でリセットするのがなんか気持ち悪い」
と思ってて^^;
で、今回は、配列内容のリセットに
mps.splice(0);
を使いました。
spliceは「配列変数の内容の置換」が役割ですが、
配列変数名.splice(0,1,'a');
のようにすると「配列の0番目から1つの要素を'a'に置き換える」という役割になり、
配列変数名.splice(0,1);
とすると「配列の0番目から1つの要素を削除する」という役割になります。
そこから更に2つめの引数をも省略し、
配列変数名.splice(0);
とすると「配列の0番目以降全ての要素を削除する」って事になるんですね。
アロー関数
作成した関数(function)のうち「mz」と「mzw」をアロー関数化してみました。
変更前
function mz(ax,ay){
if(ax<0 || ax>=xmax || ay<0 || ay>ymax){return 0;}
else{return parseInt(mztxt.substr(ax+ay*xmax,1));}
}
変更後
mz=(ax,ay)=>ax<0 || ax>=xmax || ay<0 || ay>=ymax?0:parseInt(mztxt.substr(ax+ay*xmax,1));
変更前
function mzw(ax,ay){
mztxt=mztxt.substr(0,ax+ay*xmax)+'0'+mztxt.substr(ax+ay*xmax+1);
}
変更後
mzw=(ax,ay)=>{mztxt=mztxt.substr(0,ax+ay*xmax)+'0'+mztxt.substr(ax+ay*xmax+1);}
アロー関数については、
にも書いていましたが、やはり短くなり、それと同時に分りにくくなりますねw
分かりにくい、といえば…
コード終盤の、function digの中に出てくる、
vt=Math.floor(Math.random()*4);
vy=Math.floor(vt/2-0.5);
vx=(vt*2-3)-vy*3;
↑の部分。
非常に分かりにくいかと思いますが、「上下左右の4方向をランダムで決めている」部分になります。
読みやすく書くと、
vt=Math.floor(Math.random()*4);
if(vt==0){vx=0;vy=-1;}
if(vt==1){vx=-1;vy=0;}
if(vt==2){vx=1;vy=0;}
if(vt==3){vx=0;vy=1;}
と書くべきところを、強引に計算式で同じ結果を出すようにしたものです。
ってなとこで、今回はこのへんで!
次回もまた、よろしくお願いします^^