CGIを書く
クライアントから受け取ったデータを使ってサーバ側で処理を行い、結果をクライアントに返します。
そこで、CGIを使ってサーバ側で処理を行うためのスクリプトを書きます。
データの内容を決める
ゲームを作る上で、サーバ側にどのようなデータが保存されるべきかを考えます。
ここでは一人のユーザに関するゲーム状況を、以下のような項目を使って一行で表します。
- ユーザID
- 自分の体力
- 相手の体力
他のクライアントとデータを共有する必要が無いため、これが必要最低限のデータとなります。
455673 | 2 | 40 |
838840 | 100 | 100 |
975518 | 0 | 6 |
545722 | 83 | 83 |
基本的なルーチンを書く
ここでは、基本的なファイル処理として以下のルーチンを使用するのでご了承下さい。
指定したファイル名の中身を返すルーチン。
sub fnGetFileText {
($strFilePath) = @_;
@strText = ();
if (! -f $strFilePath){
@strText = split(/$/m, "");
return("");
}
open (IN,"$strFilePath");
@strText = <IN>;
close (IN);
$strData = join('',@strText);
return($strData);
}
指定したファイル名に指定した中身を保存するルーチン。
sub fnSetFileText {
($strFilePath, $strData) = @_;
@strText = split(/$/m, $strData);
if (! -f $strFilePath){
open(OUT,">$strFilePath");
close(OUT);
}
open (OUT,">$strFilePath");
flock(OUT, 2);
print OUT (@strText);
close (OUT);
}
指定したファイル名に指定した中身を追記するルーチン。
sub fnAddFileText {
($strFilePath, $strText) = @_;
if (! -f $strFilePath){
open(OUT,">$strFilePath");
close(OUT);
}
open(OUT, ">>$strFilePath");
flock(OUT, 2);
print OUT $strText;
close(OUT);
}
メインルーチンを書く
基本ルーチンを使用して、CGIを書きます。
#!/usr/local/bin/perl
&fnMain;
sub fnMain {
#★各種設定
$strFileName = 's1.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 =~ /^$iUid\t(.+?)\t(.+?)$/m) {
$iMyLife = $1;
$iYuLife = $2;
} else {
$iMyLife = 100;
$iYuLife = 100;
#★新しい行を残して古い行を削除
@astrData = split("\n",$strData);
if ($#astrData >= $iRowMax) {
$strData = join("\n",splice(@astrData,$#astrData - $iRowMax + 1,$iRowMax)) . "\n";
}
&fnSetFileText($strFileName,$strData);
#★自分の行を追加
$strLine = "$iUid\t$iMyLife\t$iYuLife\n";
&fnAddFileText($strFileName,$strLine);
}
#★対戦
if ($iAct >= 0) {
#★自分の攻撃
if ($iAct == 0) {
$iRand = 10 + int(rand(31));
$strMsg = 'あなたの攻撃。\n敵に%1%ポイントのダメージを与えた。';
$strMsg =~ s/%1%/$iRand/g;
$iYuLife -= $iRand;
if ($iYuLife <= 0) {
$iYuLife = 0;
$strMsg .= '\n敵を倒した\nあなたの勝ちです。';
}
} elsif ($iAct == 1) {
$iRand = 10 + int(rand(21));
if ($iMyLife + $iRand > 100) {
$iRand = 100 - $iMyLife;
}
$strMsg = 'お昼寝をした。\nあなたは%1%ポイント回復した。';
$strMsg =~ s/%1%/$iRand/g;
$iMyLife += $iRand;
}
#★相手の攻撃
if ($iYuLife > 0) {
$iRand = 10 + int(rand(31));
$strMsg .= '\n\n敵の攻撃。\nあなたは%1%ポイントのダメージを受けた。';
$strMsg =~ s/%1%/$iRand/g;
$iMyLife -= $iRand;
if ($iMyLife <= 0) {
$iMyLife = 0;
$strMsg .= '\nあなたはやられてしまった。\nあなたの負けです。';
}
}
#★保存
$strLine = "$iUid\t$iMyLife\t$iYuLife";
$strData =~ s/^$iUid\t.*$/$strLine/m;
&fnSetFileText($strFileName,$strData);
} else {
$strMsg = '行動を選んで下さい。';
}
#★レスポンス
print "Content-type: text/html\n";
print "\n";
print "$iMyLife\n$iYuLife\n$strMsg";
}
これにより、クライアントから渡されたデータを用いて、クライアントが要求する結果を返します。
動作を確認する
実際の動作は以下の通りです。
新規ウィンドウで実行