マインスイーパのソースとまとめ
先日完成したマインスイーパです。
結局、全然ブラッシュアップしていないのですが、動いてる奴のソースを載せます。
<?php session_start(); if(isset($_SESSION['number'])){$board=$_SESSION['number'];} else{$_SESSION['number']=0;} $board=$_SESSION['number']; print <<< DOC_END <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <style type="text/css"> <!-- .btnCss { width:32px;height:32px; border: none; margin: 0px; padding: 0px; overflow: visible; white-space: nowrap;} --> </style> <title>マインスイーパ</title> </head> <body > <h1>マインスイーパ作るよ!</h1> <form style="margin-top:0px; margin-bottom:0px" action="index.php" method="POST"> DOC_END; $btn = $_POST['btn'] ; $start = $_POST['start']; $boardWidth = 9; $boardHeight = 9; $boardMines = 10; $board = array(); $img=""; //クリア条件 $clear = ($boardWidth*$boardHeight)- $boardMines - 1; //盤面を作る // board配列を二次元配列にセットする。大きさは[boardWidth + 2][boardHeight + 2]を想定 for($i = 0; $i < $boardHeight+2; $i++) { for($j = 0; $j < $boardWidth+2; $j++) { $board[$i][$j]['mine'] = 0; $board[$i][$j]['open'] = 0; } } // 地雷をboardMines個セットする for($i = 0; $i < $boardMines; $i++) { $x = rand(1,$boardHeight); $y = rand(1,$boardWidth); if($board[$x][$y]['mine'] == true) { // その場所にすでに地雷があればパス $i--; } else { // 地雷をセットする $board[$x][$y]['mine'] = true; } } for($y = 1; $y < $boardWidth+1; $y++) { for($x = 1; $x < $boardHeight+1 ; $x++) { $c = "0"; if($board[$x][$y]['mine'] == true) { // そこに地雷があれば地雷マークを設定する $c= "*"; } else { // 周りにある地雷の数をカウントする for($dx =-1; $dx <= 1; $dx++) { for($dy =-1; $dy <= 1; $dy++) { if($board[$x + $dx][$y + $dy]['mine'] === true || $board[$x + $dx][$y + $dy]['mine'] === "*"){ $c++; } } } } $board[$x][$y]['mine']=$c; } } //スタートボタン if($start == null && $btn == null){ session_destroy(); $cnt=0; print "<input type=submit style=width:140px name=start value=start>"; print "</form>"; } elseif($start == "start"){ $_SESSION['number']=$board; $board=$_SESSION['number']; for($l=1;$l<=$boardHeight;$l++){ for($m=1;$m<=$boardWidth;$m++){ $masu = $board[$l][$m]['mine']; masu($masu); // print "<button class=btnCss type=submit name=btn value=$l,$m><img src=$img></button>\n";//デバッグ用 print "<button class=btnCss type=submit name=btn value=$l,$m><img src=panel.jpg></button>\n"; } print "<br>"; } } //なんでかこう呼び出さないとバグる↓ $board=$_SESSION['number']; //ボタンが押されたら if($btn != null){ $btn = list($x,$y)=explode(",",$btn); //セッションとかのエラー対策 if($board == false){error("<br>何らかのエラーです");} if($board[$x][$y]['mine'] == 0){ turn_panel($x,$y); } $board[$x][$y]['open'] = true; $_SESSION['number']=$board; //ゲームオーバー処理 if($board[$x][$y]['mine'] == '*'){ for($l=1;$l<=$boardHeight;$l++){ for($m=1;$m<=$boardWidth;$m++){ $masu = $board[$l][$m]['mine']; masu($masu); if($board[$l][$m]['open'] === true){ print "<img src=$img>\n"; } elseif($masu == '*'){ print "<img src=99.jpg>\n";} else{ print "<img src=panel.jpg>\n";} } print "<br>"; } $_SESSION = array(); echo '爆発しました。ゲームオーバー。'; print "<br><br><br><a href=index.php>もう1回</a>"; exit(); }else{ //押したボタンが爆弾じゃなかった場合 for($l=1;$l<=$boardHeight;$l++){ for($m=1;$m<=$boardWidth;$m++){ $masu = $board[$l][$m]['mine']; masu($masu); if($board[$l][$m]['open'] == true){ print "<img src=$img>\n"; $cnt++; } else{ print "<button class=btnCss type=submit name=btn value=$l,$m><img src=panel.jpg></button>\n"; } } print "<br>"; } } /*デバッグ用カウンタ print_r($clear); print "<br>"; print_r($cnt); */ } //クリア判定 if($cnt > $clear){ cleared(); exit(); } //画像に変えるユーザー定義関数(switch使わない方がスマートかも) function masu($masu){ global $masu,$img; switch ($masu) { case 1: $img = "1.jpg"; break; case 2: $img = "2.jpg"; break; case 3: $img = "3.jpg"; break; case 4: $img = "4.jpg"; break; case 5: $img = "5.jpg"; break; case 6: $img = "6.jpg"; break; case 7: $img = "7.jpg"; break; case 8: $img = "8.jpg"; break; case '*': $img="99.jpg"; break; default: $img = "base.jpg"; } } //クリアのメッセージ function cleared(){ print "クリアしました。"; session_destroy(); print "<br><br><br><a href=index.php>もう1回</a>"; } //再帰で爆弾のない周辺を開く function turn_panel($x, $y){ global $board; //まだ開かれていないときのみ、オープン処理。 //こうしないと、何度も同じ場所をオープンすることになり、バグるはず。 if($board[$x][$y]['open'] != true) { $board[$x][$y]['open'] = true; //開く //開いた場所が爆弾だったときの処理 if($board[$x+$i][$y+$j]['mine'] == '*') { //開いたところが爆弾だった場合。(エラー処理?) return 0; } //開いたところの周囲の爆弾数が0なら、周囲のマスも開く if ($board[$x+$i][$y+$j]['mine'] == 0) { for ($i = -1; $i <= 1; $i++) { for ($j = -1;$j <= 1; $j++) { turn_panel($x+$i,$y+$j); //再帰呼び出し。 } } } } } //エラー function error($mes){ echo $mes; session_destroy(); print "<br><br><br><a href=index.php>もう1回</a>"; exit; } ?>
ファイル名がindex.phpで、同じディレクトリに画像ファイル1~8.jpg,panel.jpg,base.jpg,99.jpgを用意すれば同じように動くと思われます。
セッション、$board=$_SESSION['number'];じゃなくて$board=$_SESSION['board'];にした方が良かったんじゃ…わかりにくっ!
下に今まで書いたマインスイーパの記事もまとめてみました。
完成までいろいろ助言下さったid:tek_kocさんはじめ、多数の方に感謝します。
2009-01-12 - プログラミングを始める10の理由
2009-01-12 - プログラミングを始める10の理由
2009-01-12 - プログラミングを始める10の理由
2009-01-13 - プログラミングを始める10の理由
2009-01-14 - プログラミングを始める10の理由
2009-01-15 - プログラミングを始める10の理由
2009-01-15 - プログラミングを始める10の理由
2009-01-16 - プログラミングを始める10の理由
2009-01-16 - プログラミングを始める10の理由
2009-01-17 - プログラミングを始める10の理由
いちおう完成したもの
マインスイーパ