[Prev] [Back] [Home]

■ UpperHand Gameを作る


ゲームの結果をサーバに通知する

とうとう最終回となりました。 最後にゲームの結果(Appletの勝敗)をサーバに通知する機能を追加します。

CGIを実装する

サーバに結果を通知するために、結果を受け付け、記録するCGIを作成します。 CGIはWebサーバ上で動作するプログラムです。 検索エンジンや商品が購入できるWebサイトで使われています。

Appletの強さと勝敗(引き分けも)を記録するために、以下のCGIを作成しました。

#!/usr/local/bin/perl

# パラメータが足りない場合は終了する。
exit if ! $ARGV[1];

# パラメータを取得する。
$rank = $ARGV[0];
$result = $ARGV[1];

# HTTPのヘッダを出力する。
print "Content-Type: text/plain\n";
print "\n";

# 結果をログファイルに書き込む。
open(LOG, ">> .log");
print LOG "$rank $result\n";
close(LOG);

第1引数は強さで、Beginer〜Senior Masterに0〜4の数値を割り当てます。 第2引数は勝敗で、Appletが勝った場合はw、負けた場合はl、 引き分けの場合はdとします。
ふつう、CGIはHTMLの文書を生成するのですが、 今回は結果が記録できさえすればいいので、ヘッダ以外何も返さないCGIとしました。

[注釈] セキュリティ上の理由で、AppletからはAppletが置かれていたWebサーバにしか アクセスできません。

CGIを呼び出す

CGIにアクセスする前にUpperHandPlayerクラスに メソッドを1つ追加する必要がありました。 プレーヤーの強さを返すメソッドです。

//-----------------------------------------------------------------------------
//  public int rank()
//      プレーヤーの強さを返す。
//-----------------------------------------------------------------------------
public int rank()
{
    return rank;
}

準備ができたのでAppletからCGIを呼び出しましょう。
先程作成したCGIのURLを http://www.somewhere/result.cgi とすると、引数を渡すためには、 http://www.somewhere/result.cgi?rank+result というURLにアクセスすることになります。
Webサーバにアクセスするためには、以下の手順をふみます。

  1. アクセスするURLを表すURLクラスのインスタンスを生成する。
  2. URLオブジェクトを使用してWebサーバに接続する。 (このときにURLConnectionクラスのインスタンスが 生成される。)
  3. URLConnectionオブジェクトを使用して、 Webサーバからの応答を受け取る。
URLクラス、URLConnectionクラスは、 java.netパッケージに定義されています。 具体的にはUpperHandクラスに新規にpostResult()メソッドを 追加しました。

//-----------------------------------------------------------------------------
//  private void postResult(int rank, char result)
//      ゲームの結果をサーバに通知する。
//      rank    コンピュータの強さ
//      result  'w': 勝ち、'l': 負け、'd': 引き分け
//-----------------------------------------------------------------------------
private void postResult(int rank, char result)
{
    try
    {
        //  CGIのURLを作成する。
        URL url = new URL(getCodeBase(), "result.cgi?" + rank + '+' + result);
        
        URLConnection con = url.openConnection();   //  CGIに接続する。
        con.getContent();                           //  結果を通知する。
    }
    catch (Exception e)
    {
        showStatus("" + e);
    }
}

最後に、UpperHandクラスのfinishGame()メソッドに postResult()メソッドを呼び出す処理を追加します。

//-----------------------------------------------------------------------------
//  private void finishGame()
//      終局時の処理を行う。
//-----------------------------------------------------------------------------
private void finishGame()
{
    if (player[UpperHandGame.FIRST]  == null &&     //  コンピュータ同士の
        player[UpperHandGame.SECOND] == null        //  対戦のとき
            ||
        player[UpperHandGame.FIRST]  != null &&     //  人間同士の
        player[UpperHandGame.SECOND] != null)       //  対戦のとき
    {
        playSound(PUT_BALL_SOUND);
    }
    else
    {
        // コンピュータの手番を取得する。
        int p = (player[UpperHandGame.FIRST] != null) ?
                        UpperHandGame.FIRST :
                        UpperHandGame.SECOND;

        // ゲームの勝者を取得する。
        int winner = game.winner();

        // コンピュータの強さを取得する。
        int rank = player[p].rank();

        if (winner == UpperHandGame.NUTRAL)
        {                       // 引き分け
            playSound(PUT_BALL_SOUND);
            postResult(rank, 'd');
        }
        else
        if (winner == p)
        {                       // コンピュータの勝ち
            playSound(APP_WIN_SOUND);
            postResult(rank, 'w');
        }
        else
        {                       // コンピュータの負け
            playSound(APP_LOST_SOUND);
            postResult(rank, 'l');
        }
    }
}

結果はこちらで確認できます。


ここまでにできあがったもの

あなたのブラウザはJavaに対応していません。

Javaソースコード (Ver. 1.1a14)



[Prev] [Back] [Home]
Satoshi Kobayashi (koba@yk.rim.or.jp)