CGIを書く

クライアントから受け取ったデータを使ってサーバ側で処理を行い、結果をクライアントに返します。
そこで、CGIを使ってサーバ側で処理を行うためのスクリプトを書きます。

データの内容を決める

ゲームを作る上で、サーバ側にどのようなデータが保存されるべきかを考えます。
ここでは一人のユーザに関するゲーム状況を、以下のような項目を使って一行で表します。

  • 最後に行動したユーザのユーザID
  • ユーザ1のユーザID
  • ユーザ2のユーザID
  • ユーザ1の体力
  • ユーザ2の体力
  • ユーザ1に表示されたメッセージ
  • ユーザ2に表示されたメッセージ

他のクライアントとデータを共有する必要があるため、お互いの情報を記録する必要があります。

271695271695131559100100相手の番です。あなたの番です。
2304684780532304688575敵の攻撃。\nあなたは15ポイントのダメージを受けた。あなたの攻撃。\n敵に15ポイントのダメージを与えた。
6699966999316545100100お昼寝をした。\nあなたは1ポイント回復した。敵はお昼寝をした。\n敵は1ポイント回復した。
271331563499271331100100あなたの番です。相手の番です。
584660107515584660054敵の攻撃。\nあなたは26ポイントのダメージを受けた。\nあなたはやられてしまった。\nあなたの負けです。あなたの攻撃。\n敵に26ポイントのダメージを与えた。\n敵を倒した\nあなたの勝ちです。

メインルーチンを書く

さきほどの基本的なルーチンを使用して、以下のようなCGIを書きます。

#!/usr/local/bin/perl
&fnMain;
sub fnMain {
    #★各種設定
    $strFileName = 's2.txt';
    $iRowMax = 100;    #最新何件分の対戦データを保存するか
    
    #★データを受信
    if ($ENV{'QUERY_STRING'} ne '') {
        @strParam = split(/&/, $ENV{'QUERY_STRING'});
    }
    foreach $strIdx (@strParam) {
        ($strKey,$strVal) = split(/=/,$strIdx);
        $strForm{$strKey} = $strVal;
    }
    $iAct = $strForm{'act'};
    $iUid = $strForm{'uid'};
    
    #★ファイル読み込み
    $strData = fnGetFileText($strFileName);
    
    #★自分の行を取得する
    if (($strData =~ /^(.+?)\t($iUid)\t(.*?)\t(.+?)\t(.+?)\t(.*?)\t(.*?)$/m)
     || ($strData =~ /^(.+?)\t(.+?)\t($iUid)\t(.+?)\t(.+?)\t(.*?)\t(.*?)$/m)) {
        $iTurn       = $1;
        $aiUid[0]    = $2;
        $aiUid[1]    = $3;
        $aiLife[0]   = $4;
        $aiLife[1]   = $5;
        $astrText[0] = $6;
        $astrText[1] = $7;
    } elsif ($strData =~ /^(.+?)\t(.+?)\t\t(.+?)\t(.+?)\t(.*?)\t(.*?)$/m) {
        $aiUid[0]    = $2;
        $aiUid[1]    = $iUid;
        $aiLife[0]   = $3;
        $aiLife[1]   = $4;
        $iTurn       = (int(rand(2)) == 1) ? $aiUid[0] : $aiUid[1];
        $astrText[0] = ($iTurn == $iUid) ? 'あなたの番です。' : '相手の番です。';
        $astrText[1] = ($iTurn != $iUid) ? 'あなたの番です。' : '相手の番です。';
        
        #★該当行を更新
        $strLine = "$iTurn\t$aiUid[0]\t$aiUid[1]\t$aiLife[0]\t$aiLife[1]\t$astrText[0]\t$astrText[1]";
        $strData =~ s/^.+?\t$aiUid[0]\t\t.*$/$strLine/m;
        #★新しい行を残して古い行を削除
        @astrData = split("\n",$strData);
        if ($#astrData >= $iRowMax) {
            $strData = join("\n",splice(@astrData,$#astrData - $iRowMax + 1,$iRowMax)) . "\n";
        }
        #★保存
        &fnSetFileText($strFileName,$strData);
    } else {
        $iTurn       = $iUid;
        $aiUid[0]    = $iUid;
        $aiUid[1]    = '';
        $aiLife[0]   = 100;
        $aiLife[1]   = 100;
        $astrText[0] = '対戦待ちです。';
        $astrText[1] = '対戦待ちです。';
        
        $strLine = "$iTurn\t$aiUid[0]\t$aiUid[1]\t$aiLife[0]\t$aiLife[1]\t$astrText[0]\t$astrText[1]\n";
        &fnAddFileText($strFileName,$strLine);
    }
    
    #★自分が何番(0 or 1)か求める
    $iMy = ($aiUid[0] == $iUid) ? 0 : 1;
    $iYu = 1 - $iMy;
    
    #★対戦
    if ($aiUid[1] ne '' && $iAct >= 0 && $iTurn == $aiUid[$iYu]) {
        if ($iAct == 0) {
            $iRand = 10 + int(rand(31));
            $astrText[$iMy] = 'あなたの攻撃。\n敵に%1%ポイントのダメージを与えた。';
            $astrText[$iYu] = '敵の攻撃。\nあなたは%1%ポイントのダメージを受けた。';
            $astrText[$iMy] =~ s/%1%/$iRand/g;
            $astrText[$iYu] =~ s/%1%/$iRand/g;
            $aiLife[$iYu] -= $iRand;
            if ($aiLife[$iYu] <= 0) {
                $aiLife[$iYu] = 0;
                $astrText[$iMy] .= '\n敵を倒した\nあなたの勝ちです。';
                $astrText[$iYu] .= '\nあなたはやられてしまった。\nあなたの負けです。';
            }
        } elsif ($iAct == 1) {
            $iRand = 10 + int(rand(21));
            if ($aiLife[$iMy] + $iRand > 100) {
                $iRand = 100 - $aiLife[$iMy];
            }
            $astrText[$iMy] = 'お昼寝をした。\nあなたは%1%ポイント回復した。';
            $astrText[$iYu] = '敵はお昼寝をした。\n敵は%1%ポイント回復した。';
            $astrText[$iMy] =~ s/%1%/$iRand/g;
            $astrText[$iYu] =~ s/%1%/$iRand/g;
            $aiLife[$iMy] += $iRand;
        }
        
        $iTurn = ($iTurn == $aiUid[0]) ? $aiUid[1] : $aiUid[0];
        $strLine = "$iTurn\t$aiUid[0]\t$aiUid[1]\t$aiLife[0]\t$aiLife[1]\t$astrText[0]\t$astrText[1]";
        $strData =~ s/^.+?\t$aiUid[0]\t$aiUid[1]\t.*$/$strLine/m;
        &fnSetFileText($strFileName,$strData);
    }
    
    #★レスポンス
    print "Content-type: text/html\n";
    print "\n";
    print "$iTurn\n$aiLife[$iMy]\n$astrText[$iMy]";
}

これにより、クライアントから渡されたデータを用いて、クライアントが要求する結果を返します。

動作を確認する

実際の動作は以下の通りです。
新規ウィンドウで実行

Copyright © 2006 Hikijishi All Rights Reserved.
[] [ajax][0.00180697441101074]