Little Strange Software

スマホアプリの開発を行う LittleStrangeSoftware のブログです。

【JavaScript】続・自動生成迷路

幅:

高さ:

 

 

 

 どうも!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);}

 

 アロー関数については、

little-strange.hatenablog.com

にも書いていましたが、やはり短くなり、それと同時に分りにくくなりますね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;}

と書くべきところを、強引に計算式で同じ結果を出すようにしたものです。 

 

 

 

ってなとこで、今回はこのへんで!

次回もまた、よろしくお願いします^^