マインスイーパーfor JavaScript全行解説
<html> <head> <title>JavaScriptマインスイーパー</title> <SCRIPT
LANGUAGE="JavaScript"> <!-- //
JavaScriptマインスイーパー Programed by たこじゃらし // このスクリプトは、商用目的でなければ、自由に使っていただいて結構です。 // 改造、配布も自由に行っていただいてかまいません。 // 作者への連絡も強要しません。 // ただし、この5行のコメントは消さないでください。 // 2006年2月13日改造 by himawarinokage // windowsのマインスイーパ風に右クリックで地雷をマークできるようにしました。 // 地雷のマークにミスがある場合、間違えた地雷の画像に×がつくようにしました。 // たこじゃらしさんのコメントの下の4行のコメントも消さないでください。 |
JavaScriptの始まり <!--表示されない--> // の後ろはJavaScriptの中で、コメントとしてコンピュータは無視する。 |
||||||||||
//
-------------------------------- var bom_c; //
地雷の数。 //
-------------------------------- map = new
Array(100); //
地雷の有無のマップ op_map =
new Array(100); // あいているかどうか op_mapx =
new Array(10); // あけるマップX op_mapy =
new Array(10); // あけるマップY mis = new
Array(100); //
右クリックし、地雷を表示されたかどうか var
game_over = 0; |
変数bom_cの宣言 配列map、op_map、op_mapx、op_mapy,misの宣言括弧の中は要素の数 変数 game_overの値に0を代入(「=」意味は代入) 1のときゲームオーバー、0のときゲームオーバーではない。 |
||||||||||
function
init_map() //
マップを作る { for(
i=0;i<100; i++ ) { map[i]
= 0; mis[i]
= 0; // misも初期化 op_map[i]
= 0; document.images[i].src
= "base.jpg"; // リセットしたときに置き直す } //
地雷の数を決める bom_c
= Math.round(Math.random() * 5)+10; document.ms.cnt.value=bom_c; //
テキストボックスに地雷の数を書き込む cnt
= 0; while(1)
{ r
= Math.round(Math.random() * 100); if(
map[r] == 0 ) { map[r]
= 99; cnt++; if(
cnt == bom_c ) break; } } for(
x=0;x<10;x++ ) { for(
y=0;y<10;y++ ) { tnum
= y*10+x; if(
map[tnum] != 99 ) { cnt
= get_cnt(x,y); map[tnum]
= cnt; } } } game_over
= 0; } |
関数init_map()の宣言 mapの要素に地雷の位置を代入する リセットした時に画像をbase.jpgに置きなおす 地雷の数を決めてbom_cに代入する。 Math.random()は0以上、1未満の乱数を発生させる。Math.round(Math.random()*5)は四捨五入して0から5の整数にする。 0以上、1未満の乱数を発生させ、100倍し四捨五入し、0〜99までの整数にし、地雷の数と同じ数になるまで、map[0]〜[99]に99(地雷)を代入する。 while(1)はbreakの条件(cntが地雷の数になるまで)間で繰り返す。Whileの引数1は真の間ということ 「==」は「等しい」という意味。 tnumに 0×10+0,1×10+0,・・・,9×10+0 0×10+1,1×10+1,・・・,9×10+1 : 0×10+9,1×10+9,・・・,9×10+9 を代入し、map[0]〜[99]が99(地雷を配置)でないなら、関数get_cnt(x,y)を実行し、周りに何個地雷があるか(temp_cntの値)をcntに代入し、99に等しくないmap[0]〜[99]に、周りの地雷の数を代入する。 すでにゲームオーバーの場合もあるので、game_overに0を代入する。 |
||||||||||
// 何個回りにあるか function get_cnt(x,y) { tmp_cnt
= 0; if(
x > 0 ) {
// 左端でないなら(左端ならしない) num
= y * 10 + ( x - 1 ); // 左をチェック if(
map[num] == 99 ) tmp_cnt++; if(
y > 0 ) { //
左上をチェック num
= ( y - 1 ) * 10 + x - 1; if(
map[num] == 99 ) tmp_cnt++; } if(
y < 9 ) { //
左下をチェック num
= ( y + 1 ) * 10 + x - 1; if(
map[num] == 99 ) tmp_cnt++; } } if(
x < 9 ) {
// 右端でないなら(右端ならしない) num
= y * 10 + ( x + 1 ); // 右をチェック if(
map[num] == 99 ) tmp_cnt++; if(
y > 0 ) { //
右上をチェック num
= ( y - 1 ) * 10 + x + 1; if(
map[num] == 99 ) tmp_cnt++; } if(
y < 9 ) { //
右下をチェック num
= ( y + 1 ) * 10 + x + 1; if(
map[num] == 99 ) tmp_cnt++; } } if(
y > 0 ) { //
上端でないなら、真上をチェック(上端ならしない) num
= ( y - 1 ) * 10 + x; if(
map[num] == 99 ) tmp_cnt++; } if(
y < 9 ) { //
下端でないなら、真下をチェック(下端ならしない) num
= ( y + 1 ) * 10 + x; if(
map[num] == 99 ) tmp_cnt++; } return(
tmp_cnt ); } |
周りの地雷の数を求めて、int_map()に返す。 関数get_cnt()の宣言:x,yの値を受け取る
上下左右、斜め上下をチェックし、 map[num]が99(地雷がある)ならば、そのたびにtemp_cntに1を足す。 関数get_cnt()の結果としてtemp_cntの値(地雷の数)をinit_map()のcntに返す。 |
||||||||||
function
put(x,y) // 置く { if(
game_over == 1 ) { alert("リセットして、やり直してください!"); } num
= y*10+x; if(
op_map[num] == 1 ) return; //
開いてたら戻る open_map(x,y); //
マップを開く //
地雷を弾いちゃった時 if(
map[num] == 99 ) { alert("どっかーん!!"); game_over
= 1; open_bom(); return; } //
クリアチェック cnt
= 0; for(
i=0;i<100;i++ ) { if(
op_map[i] == 0 ) cnt++; // 開いてないマップの数をカウント } if(
cnt == bom_c ) { //
地雷の数と一致したらクリア alert("おめでとう!クリアです。"); game_over
= 1; open_bom(); return; } } |
関数put(x,y)の宣言 bodyのbase.jpgをクリックすると、put(x,y)が実行され、その座標xとyの値が代入される。 game_overの値が1に等しい時、アラートを実行し、ダイアログ・ボックスに「リセットして、やり直してください!」と表示。 numに、送られてきたy座標の値を10倍して、x座標の値を足したものを、代入 op_map[num]の値が1のとき(開いているとき)は何もしない 関数open_map(x,y)を実行し、op_mapの値を1にすると共に回りに地雷がいくつあるか書いた画像に変える。 map[num]の値が99のとき、アラートを実行し、ダイアログ・ボックスに「どっかーん」と表示。Game_overの値を1にしopen_bom()を実行し、地雷を開き、戻る。 cntに0を代入し、 op_map[0]〜[99]まで、0に等しいか調べ、0に等しい(開いていない)場合はcntの値を1ずつ増やす。 開いていないop_mapの数(cntの値)が地雷の数と等しくなったとき、アラートを実行し、ダイアログ・ボックスに「おめでとう!クリアです。」と表示。 Game_overの値を1、地雷を開き、戻る。 |
||||||||||
function open_bom() //
地雷を開く { for(
i=0;i<100;i++ ) { if(
( mis[i] == 1 ) && ( map[i] != 99 ) ){ // misが1かつmapが99でないとき document.images[i].src
= "100.jpg"; // 地雷×の画像に置き換える } if(
map[i] == 99 ) { document.images[i].src
= "99.jpg"; } } } |
関数open_bom()の宣言 配列misの要素が1に等しく、かつ配列mapの要素が99以外のとき(地雷のマークが間違っている場合)、地雷に×の画像に変える map[0]〜[99]を調べ、99に等しい場合、 画像を99.jpg(地雷の画像)にする。 |
||||||||||
function open_map(x,y) //
選択されたもののopen_mapの値を1し、画像を変える { op_cnt = 0; op_cnt2
= 1; op_mapx[0]
= x; op_mapy[0]
= y; num
= y*10+x; op_map[num]
= 1; wdata
= map[num]+".jpg"; document.images[num].src
= wdata; if(
map[num] == 0 ) { open_map2(); } } |
関数open_map(x,y)の宣言 関数open_map2()で使う op_cntに0、op_cnt2に1を代入 open_mapxの1番目の要素にx座標の値を代入 open_mapyの1番目の要素にy座標の値を代入 numに、送られてきたy座標の値を10倍して、x座標の値を足したものを、代入 op_map[num]に1(開いている)を代入 wdataにmap[num](周りの地雷の数)を代入 num番目の画像を周りの地雷の数の画像に置き換える(正確にはnum+1番目の画像) map[num]が0に等しいとき(周りに地雷がないとき) 関数open_map2()を実行する |
||||||||||
function open_map2(x,y) // クリックしたmapの周りのマップに // check()を実行させる { while(
1 ) { loop
= op_cnt; op_cnt
= op_cnt2; for(
i=loop; i<op_cnt;i++ ) { if(
op_mapx[i] > 0 ) { //
左をチェック check(
op_mapx[i]-1,op_mapy[i] ); } if(
op_mapx[i] < 9 ) { //
右をチェック check(
op_mapx[i]+1,op_mapy[i] ); } if(
op_mapy[i] > 0 ) { //
上をチェック check(
op_mapx[i],op_mapy[i]-1 ); } if(
op_mapy[i] < 9 ) { //
下をチェック check(
op_mapx[i],op_mapy[i]+1 ); } } if(
op_cnt == op_cnt2 ) break; } } |
関数open_map2()の宣言 breakまで繰り返し、{ }の中身を実行 loopにop_cnt(初めの値は0)の値を代入、次に op_cntにop_cnt2の値(初めの値は1)を代入。 iにloopの値(初めは0)を代入し、op_cntの値以下(この時点では1になっている)の間繰り返し、1回実行するとiに1を足す。 op_mapxの値が1以上(左端でない)のとき、 x座標が1小さいもの(左のマップ)に関数check(x,y)を実行 op_mapxの値が8以下(右端でない)のとき、 x座標が1大きいもの(右のマップ)に関数check(x,y)を実行 op_mapyの値が1以上(上端でない)のとき、 y座標が1小さいもの(上のマップ)に関数check(x,y)を実行 op_mapyの値が8以下(下端でない)のとき、 y座標が1大きいもの(下のマップ)に関数check(x,y)を実行 (関数check(x,y)の結果、チェックした座標の周りに地雷がない場合op_cnt2の値が1増える) 増えない場合、op_cnt=op_cnt2になり終了。増えた場合、繰り返す。 |
||||||||||
function
check(x,y) //
上下左右をチェックする { num
= y*10+x; if(
op_map[num] == 1 ) return; if(
map[num] == 0 ) { //
0の時 op_mapx[op_cnt2]=x; op_mapy[op_cnt2]=y; op_cnt2++; //
取るところを増やす } //
0以外の時も開く。 if(
map[num] != 99 ) { op_map[num]
= 1; wdata
= map[num]+".jpg"; document.images[num].src
= wdata; } } |
関数check(x,y)の宣言 x,yにはクリックしたマップの上下左右の座標が送られてくる。 numにy×10+xの値を代入 op_mapの値が1(開いている)なら関数終了 それ以外の場合 map[num]が0(周りに地雷がない)に等しいとき、 op_map[op_cnt2]にxの値を代入 op_map[op_cnt2]にyの値を代入 (open_map()に戻って、代入した座標のチェックを繰り返す。 op_cnt2に1を足す(while(1)がbreakしないで続く) map[num]が99以外(地雷でない)のとき op_map[num]に1(開いている)を代入 wdataにmap[num](周りの地雷の数)を代入 num番目の画像を周りの地雷の数の画像に置き換える(0から始まっているので正確にはnum+1番目の画像) |
||||||||||
function
change(x,y) //右クリックしたとき、地雷を表示 { num
= y*10+x; if(op_map[num]==1){ // すでに開いているとき return;
// 中止 } if(mis[num]==1){ //
地雷を表示しているとき、 document.images[num].src
= "base.jpg"; // base.jpgを表示 mis[num]
= 0; return; } if(mis[num]==0){ //
地雷を表示してないときは、 document.images[num].src
= "99.jpg"; // 地雷の画像を表示 mis[num]
= 1; } } |
関数change(x,y)の宣言 マップの上で右クリックしたとき実行される。 すでに開いているところを右クリックした場合、何もしないで関数を中止する すでに地雷(99.gif)が表示されているときは、base.jpgに置き換える。 配列要素mis[num]の値を0(地雷が表示されてない)に戻す。 関数を終了。 地雷が表示されていないときは、 地雷(99.jpg)を表示し、 配列要素mis[num]の値を1(地雷を表示した)にする。 |
||||||||||
// --> </SCRIPT> |
javascriptの終了 |
||||||||||
</head> |
headの終了 |
||||||||||
<BODY BGCOLOR="#000000"
TEXT="#ffffdd" LINK="#88ffff"
VLINK="#88ffcc" ALINK="#88ffcc" onLoad=init_map()> |
本文開始時に関数init_map()を実行 |
||||||||||
<div
align="center"> <font
size=7 color=#ff4466> マインスイーパー</font><font size=5 color=#ffffff>for
JavaScript</font> <hr> |
「マインスイーパー for JavaScript」の文字を表示 |
||||||||||
<!--- ゲームの枠
--> <table
border=2><tr><td> |
ゲームの画像を並べる表の作成 |
||||||||||
<script
language="JavaScript"> <!-- for(i=0;i<10;i++)
{ for(j=0;j<10;j++)
{ document.write('<a
href=JavaScript:put(',j,',',i,')><img src=base.jpg oncontextmenu="change(',j,',',i,');return
false" border=0 width=32 height=32></a>'); } document.write("<br>\n"); } // --> </script> |
JavaScriptの始まり 10行、10列の画像base.jpgが並び、画像をクリックすると、xにjの値、yにiの値が代入され、関数
put(x,y)が実行される。 右クリックしたとき、関数change(x,y)を実行する 地雷を表示する ※ put(',j,',',i,')は put('+j+','+i+')と書いても同じ。document.wirate('×××'+j+'・・・') ということです。シングルクォートがないとjやiが文字とみなされてしまいます。 1行に10個のbase.jpgを書いた後に改行を入れる。 |
||||||||||
</td></tr></table> |
表の終了 |
||||||||||
<form
name=ms> 地雷の数は<input type = text value="" alt=""
name="cnt" size="5">個<br><br> <input
type = button value="リセット" onClick="init_map()"> </form> |
フォームの作成(名前はms) 関数init_map()のbom_c(地雷の数)をテキストボックスに表示する クリックすると関数init_map()を実行する、「リセット」と表示された、ボタンの作成 |
||||||||||
<br> [<a
href=http://www.bb.e-mansion.com/~okayama/j-tako/js/game/mines/mines_play.html>遊び方</a>] </div> <hr> </body> </html> |
遊び方へのリンク |
||||||||||