新三山くずしゲーム

サーバーを介してクライアント同士が対戦する「新対戦型三山くずしゲーム」です。
新対戦型三山くずしゲームの呼び出し方です。
<a href="http://maedakobe.rw.xsi.jp/php/miyama2.php" target="_blank">新対戦型三山くずしゲーム</a><br>

対戦するには、二人のプレイヤーが同時にログインして下さい。
(1台のパソコンで別のホームページを立ち上げてテストすることも出来ます)
対戦型三山くずしゲーム

プログラムの説明

  1. ネット対戦三山くずしゲームのように交互にプレイするゲームでは、サーバーからの呼び出しを受けてクライアント側が調べるよりも、サーバー側で待ち合せて手番になると通知する方法が適しています。
    'miyama2_call.php' が手番を通知してくれるプログラムで、1秒ごとに "miyama.txt" を入力して $st と同じ値、または $state>2 になると miyama2.php を呼び直します。
    $state でゲームの進行を管理します。
    $state 説明
    0 二人のプレイヤーが揃うのを待つ
    1 プレイヤーAがプレイする
    2 プレイヤーBがプレイする
    3 プレイヤーAの勝ち
    4 プレイヤーBの勝ち
    9 ゲームを終了する
  2. 対戦型三山くずしゲームでは miyama.txt と Miyama2 Class を使用します。
    miyama.txt をサーバーにアップロードして、書き込みと読み込み属性を許可して下さい。
    名前 説明
    $state ゲームの進行状態
    $id_a プレイヤーAのID
    $id_b プレイヤーBのID
    $ary[3]山の石の数
  3. Miyama2 で三山くずしゲームを起動するときは、次の行を修正して下さい。
    Miyama2 Class の説明は Miyama2 Classを参照して下さい。
    miyama2_class.php の form_call($id, $msg) 関数を修正して下さい。
    修正前  print("<form action='miyama2_login.php' method='get'>\n");
    修正後  print("<form action='miyama2.php' method='get'>\n");
    
    サーバー上で定期的に miyama.txt を調べて PHP を呼び直す 'miyama2_call.php' の Link_URL(id) 関数を修正して下さい。
    修正前  str= "miyama2_login.php?mode=LOGIN&id=" + id;
    修正後  str= "miyama2.php?mode=PLAY&id=" + id;
    

miyama2.php

  1. 対戦型三山くずしゲームを実行する miyama2.php です。
    utf-8 でタイプしてアップロードして下さい。
    <html>
    <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-8">
      <title>Miyama2</title>
    <script type="text/javascript">
    history.forward();
    // Mouse Click Function
    function MouseClick(id, num)
    {   str= "miyama2.php?mode=9&id=" + id + "&num=" + num;
        location.href = str;
    }
    // Wait Call
    function Link_URL(id, st)
    {   str= "miyama2_call.php?&id=" + id + "&st=" + st;
        location.href = str;
    }
    </script>
    <?php
    // Disp 3 Line
    function stone_disp($id, $ary)
    {   $w= "'" . $id . "'";
        for($i=0; $i<3; $i++)
        {   $n= $i*15;
            for($j=0; $j<$ary[$i]; $j++)
            {   print "<img src=\"img/jewel.gif\" onClick=\"MouseClick($w, $n)\">\n";
                $n++;
            }
            print "<br><br>\r\n";
        }
    }
    // Recall miyama2 
    function Recall($id, $st)
    {   print("<script type='text/javascript'>\n");
        print("var id = '" . $id . "';\n");
        print("Link_URL(id, $st)");
        print("</script>\n");
    }
    ?>
    </head>
    
    <body bgcolor=#f4f8ff>
    <h2>Miyama2 Game</h2>
      <?php
        require_once("miyama2_class.php");
        $game= new miyama2_class();
        $id= $_GET['id'];       //id
        $mode= $_GET['mode'];   //mode
        $num= $_GET['num'];     //num
        if (!isset($mode))  $mode= 'LOGIN';
        if ($mode=='RESET')
        {   $game->put_file();
            $game->form_call('none', "Game Reset");
            return;
        }
        if (!isset($id))    $id= '-';
        if ($id=='-')
        {   $game->form_call('none', "ID Please");
            return;
        }
        $game->get_file();
        $msg= $game->message();
        switch($mode)
        {   case 'LOGIN':
                $game->action($id, $num);
                $game->put_file();
                $msg= $game->message();
                print("<br><br>$msg<br>\r\n");
                if ($id==$game->id_a)
                {   Recall($id,1);
                    return;
                }
                if ($id==$game->id_b)
                {   Recall($id,2);
                    return;
                }
            case 'PLAY':
                break;
            case 9:
                $game->action($id, $num);
                for($i=0; $i<3; $i++)
                {   for($j=0; $j<$ary[$i]; $j++)
                        print "<img src=\"img/jewel.gif\">\n";
                    print "<br><br>\r\n";
                }
                $game->put_file();
                if ($id==$game->id_a)
                {   Recall($id,1);
                    return;
                }
                if ($id==$game->id_b)
                {   Recall($id,2);
                    return;
                }
                break;
            default:
                print "<br>* mode error * : $mode<br>\r\n";
                exit();
        }
        $game->get_file();
        $msg= $game->message();
        $game->check($id);
        if ($game->state==0) $game->form_call($id, $msg);
        else
        {   stone_disp($id, $game->ary);
            print("<br><br>$msg<br>\r\n");
        }
    ?>
    </body>
    </html>
    
  2. Miyama2 Class の Form から miyama2.php を呼び出します。
    最初に RESET を選んで miyama.txt を RESET してから、プレイヤーがログインします。
        // Form Input
        function form_call($id, $msg)
        {   print "$id:$msg<br>\n";
            print("<form action='miyama2.php' method='get'>\n");
    //        print("<form action='miyama2_login.php' method='get'>\n");
    //        print("<form action='miyama_xml.php' method='get'>\n");
            print("ID:<input type=text name='id' value=\"$id\"><br><br><br><br>\n");
            print("<input type=submit name='mode' value='LOGIN' /><br>\n");
            print("<input type=submit name='mode' value='RESET' /><br>\n");
            print("</form>");
        }
    
  3. 山から石を取り除く処理は JavaScript でマウスのクリックを検出します。
    img で石の画像を並べるときに onClick を設定して、IDとクリックされた画像を引数にして MouseClick() を呼び出します。
    MouseClick() から miyama2.php を再起的に呼び出します。
    mode=9 は MouseClick() からの呼び出しの識別で、id はプレイヤーのIDで num はクリックされた画像の番号です。
    function MouseClick(id, num)
    {   str= "miyama2.php?mode=9&id=" + id + "&num=" + num;
        //window.alert(str);
        location.href = str;
    }
    
  4. miyama2.php が呼び出されると require_once("miyama2_class.php"); で組み込んで、$game= new miyama2_class(); で Class を生成します。
    パラメータで渡された $id, $mode, $num を取得します。
        require_once("miyama2_class.php");
        $game= new miyama2_class();
        $id= $_GET['id'];       //id
        $mode= $_GET['mode'];   //mode
        $num= $_GET['num'];     //num
    
  5. $mode が 'RESET' のときは miyama.txt を初期化します。
    $id が設定されていないときは、メッセージを表示します。
        if ($mode=='RESET')
        {   $game->put_file();
            $game->form_call('none', "Game Reset");
            return;
        }
        if (!isset($id))    $id= '-';
        if ($id=='-')
        {   $game->form_call('none', "ID Please");
            return;
        }
    
  6. get_file(); で miyama.txt から最新データを入力します。
    log($id, $mode); はデバッグ情報の収集です。
    $mode に従って処理を振り分けます。
    Recall() 関数で自分の手番を待ち合せます。
        $game->get_file();
        $msg= $game->message();
    //$game->log($id, $mode);
        switch($mode)
        {   case 'LOGIN':
                $game->action($id, $num);
                $game->put_file();
                $msg= $game->message();
                print("<br><br>$msg<br>\r\n");
                if ($id==$game->id_a)
                {   Recall($id,1);
                    return;
                }
                if ($id==$game->id_b)
                {   Recall($id,2);
                    return;
                }
            case 'PLAY':
                break;
    
  7. $mode が 9 のときは、プレイヤーが石をクリックした時です。
    action($id, $num) 関数で山から石を取り除いて $ary[3] に従って石を表示します。
    相手がプレイして自分の手番になるまで Recall() 関数で待ち合せます。
    自分の手番になると 'miyama2_call.php' から miyama2.php が呼び出されます。
            case 9:
                $game->action($id, $num);
                for($i=0; $i<3; $i++)
                {   for($j=0; $j<$ary[$i]; $j++)
                        print "<img src=\"img/jewel.gif\">\n";
                    print "<br><br>\r\n";
                }
                $game->put_file();
                if ($id==$game->id_a)
                {   Recall($id,1);
                    return;
                }
                if ($id==$game->id_b)
                {   Recall($id,2);
                    return;
                }
                break;
            default:
                print "<br>* mode error * : $mode<br>\r\n";
                exit();
        }
    
  8. ログイン処理のときは form_call() を呼び出します。
    山から石を取り除いている時は stone_disp() を呼び出します。
        $game->get_file();
        $msg= $game->message();
        $game->check($id);
        if ($game->state==0) $game->form_call($id, $msg);
        else
        {   stone_disp($id, $game->ary);
            print("<br><br>$msg<br>\r\n");
        }
    

前田稔の超初心者のプログラム入門
PHP Program