マインスイーパのソースとまとめ

先日完成したマインスイーパです。
結局、全然ブラッシュアップしていないのですが、動いてる奴のソースを載せます。

<?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の理由
いちおう完成したもの
マインスイーパ