;
close(IN);
#前回の答え合わせ
if($in{press}){
local($no,$question,$correct,@ans)=split(/<>/,$logs[$in{line}]);
if($in{ans} == $correct){
print "正解!
\n";
}else{
print "
間違い!
\n";
$in{mymissnum}++;
}
}else{print "
\n";$in{start}=time;}#初めての問題の時
#ステータス
$correctnum = $in{anssum}-$in{mymissnum};
if($in{anssum}){
$per = sprintf("%4.2f",($correctnum*100)/$in{anssum});
}else{
$in{anssum}=0;
$per = 0;
}
if(!$in{mymissnum}){$in{mymissnum} = 0;}
$passtime = time-$in{start};
print<<"STATUS";
| 問題数 | 正解数 | 間違い数 | 正解率 | 経過時間 |
| $in{anssum} | $correctnum |
$in{mymissnum} | $per |
$passtime秒 |
STATUS
if($in{mymissnum} >= $maxmissnum || $in{anssum} == scalar(@logs) ){
print "ゲームオーバー
成績を登録します。
\n";
®istform;
}else{
$in{anssum}++;
#問題を重複しないようにランダムで出題
#$in{anssum}が問題数
srand( $in{seed} );
#順列作成
@q_array = ();
for( $i = 0; $i < scalar(@logs); $i++ ){
push( @q_array, $i );
}
#一応表示
#foreach(@q_array){print "$_
";};
#print "
";
#並び替え
for( $i = 0; $i < scalar(@logs); $i++ ){
$rand = int( rand( scalar(@logs) - $i ) ) + $i;
$temp = $q_array[ $i ];
$q_array[ $i ] = $q_array[ $rand ];
$q_array[ $rand ] = $temp;
}
#一応表示
#foreach(@q_array){print "$_
";};
#今回の問題
$thistime = $q_array[ $in{anssum} ];
chomp $logs[ $thistime ];
($no,$question,$correct,@ans)=split(/<>/,$logs[ $thistime ]);
print<<"QUIZ";
QUIZ
}
}
#成績登録
sub regist{
if(!$in{name}){&error("名前が入力されていません");}
if(!$in{key}){&error("パスワードが入力されていません");}
$in{correctnum} = $in{anssum}-$in{mymissnum};
$in{per} = sprintf("%4.2f",($in{correctnum}*100)/$in{anssum});
#同じ名前の人物がいないかチェック
open(IN,$memfile) or &openerror($memfile);
@mems = ; close(IN);
$flag=0;$i=0;
foreach(@mems){
&linesplit($_);
#同じ名前の時、同一人物かどうか
if($name eq $in{name}){
#キーが合ってるか?
if($pass eq crypt($in{key},$pass)){
$flag=1;
$prev = $i;#添字取得
last;
}else{$flag=2;last;}
}
$i++;
}
#キーを暗号化
$xx = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./";
$salt = substr($xx,int(rand(64)),1);
$salt .= substr($xx,int(rand(64)),1);
$enckey = crypt($in{key},$salt);
#成績登録
#新規の場合
if($flag == 0){
if(!mkdir($lockdir,0755)){&error("同時アクセスが起こりました。");}
$flag2 = 0;
open(OUT,">$memfile");
foreach(@mems){
&linesplit($_);
if(!$flag2 && $in{per} > $per){
print OUT "$in{name}<>$in{msg}<>$enckey<>$in{url}<>$in{anssum}<>$in{correctnum}<>$in{mymissnum}<>$in{per}<>$in{passtime}\n";
$flag2 = 1;
}
print OUT $_;
}
#最下位の場合
if(!$flag2){print OUT "$in{name}<>$in{msg}<>$enckey<>$in{url}<>$in{anssum}<>$in{correctnum}<>$in{mymissnum}<>$in{per}<>$in{passtime}\n";}
close(OUT);
rmdir($lockdir);
print "成績を記録しました。
\n";
}
#更新の場合
elsif($flag == 1){
if(!mkdir($lockdir,0755)){&error("同時アクセスが起こりました。");}
open(OUT,">$memfile");
$j = 0;$flag2 = 0;
foreach(@mems){
&linesplit($_);
if($flag2==0 && $in{per} > $per){
print OUT "$in{name}<>$in{msg}<>$enckey<>$in{url}<>$in{anssum}<>$in{correctnum}<>$in{mymissnum}<>$in{per}<>$in{passtime}\n";
$flag2 = 1;
}
if($j == $prev){;}#前のデータを削除
else{print OUT $_;}
$j++;
}
#最下位の場合
if(!$flag2){print OUT "$in{name}<>$in{msg}<>$enckey<>$in{url}<>$in{anssum}<>$in{correctnum}<>$in{mymissnum}<>$in{per}<>$in{passtime}\n";}
close(OUT);
rmdir($lockdir);
print "成績を更新しました。
\n";
}
#名前が重複していた場合
elsif($flag == 2){
print "その名前で既に登録されています。他の名前で登録して下さい。";
®istform;
exit;
}
}
#問題作成ページ
sub new{
print<<"FORM";
問題を追加します。
FORM
}
#問題追加
sub do_new{
if(!$in{question}){&error("問題を入力して下さい。");}
if(!$in{newans}){&error("正解をチェックして下さい。");}
open(IN,$logfile) or &openerror($logfile);
@logs = ;
close(IN);
#同じ問題がないかチェック
foreach(@logs){
local($no,$q) = split(/<>/,$_);
if($q eq $in{question}){&error("同じ問題が登録されています。");}
}
#MAXNOを取得
$maxno=1;
for($i=0;$i/,$logs[$i]);
if($maxno<$no){$maxno=$no;}
}
$maxno++;
if(!mkdir($lockdir,0755)){&error("同時アクセスが起こりました。");}
open(OUT,">$logfile");
print OUT "$maxno<>$in{question}<>$in{newans}";
for($i=1;$i<$ANS_NUM+1;$i++){
$str = sprintf("ans%d",$i);
print OUT "<>$in{$str}";
}
print OUT "\n";
print OUT @logs;
close(OUT);
rmdir($lockdir);
print "問題を追加しました。
\n";
}
#成績を見るページ
sub lookmem{
open(IN,$memfile) or &openerror($memfile); @dat=; close(IN); chop(@dat);
$sum = scalar(@dat);
print "上位$sum人の成績表\
\n"
."\n"
."| 順位 | 名前 | 正解数 | 正解率 | タイム | コメント |
\n";
$rank=1;$prev=1;$i=0;
foreach(@dat){
&linesplit($_);
$i++;
if($prev > $per){$rank = $i;}
$prev = $per;
print "| $rank | "
."$name | "
."$correctnum | $per | $time | $msg |
\n";
}
print "
\n";
}
#成績登録フォーム
sub registform{
if(!$passtime){$passtime=$in{passtime};}
print<<"GAMEOVER";
GAMEOVER
}
#ログ形式通り分割して変数に格納
sub linesplit{
($name,$msg,$pass,$url,$qnum,$correctnum,$missnum,$per,$time) = split(/<>/,$_[0]);
chomp($time);
}
#フォーム情報
sub form{
local($buffer,@pairs);
$ENV{REQUEST_METHOD} =~ tr/A-Z/a-z/;#大文字を小文字に
if($ENV{REQUEST_METHOD} eq 'post'){
read(STDIN,$buffer,$ENV{CONTENT_LENGTH});
}else{$buffer = $ENV{QUERY_STRING};}
@pairs = split(/&/,$buffer);
foreach(@pairs){
local($key,$value) = split(/=/,$_);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
$value =~ s/&/&/g;
$value =~ s/"/"/g;
$value =~ s/</g;
$value =~ s/>/>/g;
$value =~ s/\r\n/\n/g;
$value =~ s/\n/
/g;
$in{$key} = $value;
}
}
sub openerror{print "$_[0]がオープン出来ません。";&foot;exit;}#オープンエラー
sub error{print "$_[0]\n";&foot;exit;}#エラー