CGI/Perlで作成したパズルゲームのプログラムソース公開CGI/Perlで作成したパズルゲームの主要部分(画面表示とタイル移動処理)のプログラムソースを公開します。プログラムの一部にJavaScriptも含まれています。また、HTML部はタグが大文字で記述されていたり、属性値をダブルクオーテーションで囲っていないなど、HTMLの基本文法を無視した形になっていますが、IE(InternetExplorer)、Firefox、Operaなど、主要なブラウザーでは一応動作します。■ パズルゲーム名:『タイルdeパズル』 URL: //kunisan.jp/puzzle/ ■ ゲーム画面表示 (プログラム名: "game.cgi") #!/usr/local/bin/perl print "Content-type: text/html\n\n"; #QUERY受け取り $mes = $ENV{ 'QUERY_STRING' }; @group = split(/&/,$mes); foreach $ans(@group) {($name,$value) = split(/=/,$ans); $value =~ s/%(..)/pack("c",hex($1))/ge; $ok_mes{$name}= $value;} $id = $ok_mes{'ID'}; #データ読み込み $datafile = "lib/id$id.cnt"; open(TXT,"<$datafile"); $or_data = <TXT>; close(TXT); @dt = split(/,/,$or_data); #(重要!ゲームデータに元からあるデータ)$dt[0] 幅, $dt[1] 高さ, $dt[2]制限時間(秒) #(重要!ゲーム中開始後に作成されるデータ)$dt[4] ゲーム名(数値のみ), $dt[5] ゲーム名, $dt[6] スタート時のタイム, $dt[7] 手数, $dt[8] 完成時のタイム, $dt[9] 完成時の手数 #(重要!)$dt[10~] タイル配置データ(ファイル名データ) $width = $dt[0]; $height = $dt[1]; $max_val = @dt - 1; #読み込み最大値(要素数-1) #$table_w = ( $width + 2 ) * 64; $time_limit = &view_time($dt[2]); #制限時間 $time_now = time - $dt[6]; if ($time_now < 0) { $time_now = 0; } if (($dt[2] - $time_now) <= 30 ) { $html2 = "<FONT color=#EAEA00>"; $html3 = "</FONT>"; } $time_now = &view_time($time_now); #経過時間 if ($dt[4] == 999) { $html4 = '矢印ボタンでタイルを<BR>並び替えて、制限時間<BR>内に『完成図』の通り<BR>にしてください。<BR>'; } if ($id eq "") { print <<"end_mark"; <HTML> <HEAD> <TITLE>タイルdeパズル</TITLE> <STYLE TYPE="TEXT/CSS"> <!-- /* STYLE */ A:link {color:#EAEAEA; text-decoration:underline;} A:visited {color:#BFBFBF; text-decoration:underline;} A:hover {color:#FFDDDD; text-decoration:underline;} --> </STYLE> </HEAD> <BODY background=/bg.gif bgcolor=#8888FF> <META http-equiv="Refresh" content="0;URL=index.cgi"> <SMALL><FONT color=#EAEAEA> 自動的にジャンプしない場合は<A href="index.cgi">ここ</A>をおしてください。 </FONT></SMALL> </BODY> </HTML> end_mark exit(0); } #HTML1 print <<"end_mark"; <HTML> <HEAD> <TITLE>タイルdeパズル</TITLE> <STYLE TYPE="TEXT/CSS"> <!-- /* STYLE */ A:link {color:#EAEAEA; text-decoration:underline;} A:visited {color:#BFBFBF; text-decoration:underline;} A:hover {color:#FFDDDD; text-decoration:underline;} --> </STYLE> </HEAD> <BODY background=/bg.gif bgcolor=#8888FF> <SCRIPT language="JavaScript"> <!-- image100 = new Image (256,256); image100.src = "/arrow_d.gif"; image101 = new Image (256,256); image101.src = "/arrow_ds.gif"; image102 = new Image (256,256); image102.src = "/arrow_u.gif"; image103 = new Image (256,256); image103.src = "/arrow_us.gif"; image104 = new Image (256,256); image104.src = "/arrow_r.gif"; image105 = new Image (256,256); image105.src = "/arrow_rs.gif"; image106 = new Image (256,256); image106.src = "/arrow_l.gif"; image107 = new Image (256,256); image107.src = "/arrow_ls.gif"; end_mark #矢印の画像切り替え処理 for ($x=1; $x <= $width; $x++){ #下矢印 print "function d$x\(\){\n"; print "document.D$x.src = image100.src\;\n"; print "}\n"; print "function d$x\s\(\){\n"; print "document.D$x.src = image101.src\;\n"; print "}\n"; } for ($x=1; $x <= $width; $x++){ #上矢印 print "function u$x\(\){\n"; print "document.U$x.src = image102.src\;\n"; print "}\n"; print "function u$x\s\(\){\n"; print "document.U$x.src = image103.src\;\n"; print "}\n"; } for ($y=1; $y <= $height; $y++){ #右矢印 print "function r$y\(\){\n"; print "document.R$y.src = image104.src\;\n"; print "}\n"; print "function r$y\s\(\){\n"; print "document.R$y.src = image105.src\;\n"; print "}\n"; } for ($y=1; $y <= $height; $y++){ #左矢印 print "function l$y\(\){\n"; print "document.L$y.src = image106.src\;\n"; print "}\n"; print "function l$y\s\(\){\n"; print "document.L$y.src = image107.src\;\n"; print "}\n"; } #HTML2 print <<"end_mark"; //--> </SCRIPT> <TABLE cellpadding="0" cellspacing="0" border="0"> <TR> <TD valign="top"> end_mark #タイル&矢印表示 print "<NOBR><IMG src=/blank.gif width="64" height="64"> "; for ($x = 1; $x <= $width ;$x++) { print "<A href="move.cgi?ID=$id&MOVE=d$x" onMouseOver=d$x\s() onMouseOut=d$x\()><IMG src=/arrow_d.gif width="64" height="64" border="0" name="D$x" > </A>"; } print "<IMG src=/blank.gif width="64" height="64"> </NOBR><BR>\n\n"; for ($y = 1; $y <= $height ;$y++) { print "<A href="move.cgi?ID=$id&MOVE=r$y" onMouseOver=r$y\s() onMouseOut=r$y\()><IMG src=/arrow_r.gif width="64" height="64" border="0" name="R$y" > </A>"; for ($x = 1; $x <= $width ;$x++) { $i = ($y - 1) * $width + $x + 9; print "<IMG src=/$dt[$i].gif width="64" height="64"> "; } print "<A href="move.cgi?ID=$id&MOVE=l$y" onMouseOver=l$y\s() onMouseOut=l$y\()><IMG src=/arrow_l.gif width="64" height="64" border="0" name="L$y" > </A><BR>\n\n"; } print "<NOBR><IMG src=/blank.gif width="64" height="64"> "; for ($x = 1; $x <= $width ;$x++) { print "<A href="move.cgi?ID=$id&MOVE=u$x" onMouseOver=u$x\s() onMouseOut=u$x\()><IMG src=/arrow_u.gif width="64" height="64" border="0" name="U$x" > </A>"; } print "<IMG src=/blank.gif width="64" height="64"> </NOBR><BR>\n\n"; #HTML3 print <<"end_mark"; </TD> <TD width="5"> </TD><TD width="2" bgcolor=#EAEAEA > </TD><TD width="16"> </TD> <TD valign="top"> <SMALL><FONT color=#EAEAEA> <CENTER><IMG src=/title_mini.gif></CENTER> <BR> <B>$dt[5]</B><BR> <TABLE cellpadding="0" cellspacing="0" border="0"> <TR><TD align=CENTER> <IMG src=/game$dt[4]\.gif border="0"> <BR> <SMALL><FONT color=#EAEAEA>[ 完成図 ]</FONT></SMALL><BR> </TD></TR></TABLE> <BR> <FONT color=RED><B>制限時間:</B> $time_limit\<BR></FONT> $html2\<B>経過時間:</B> $time_now\<BR>$html3 <!-- <B>手数:</B> $dt[7]\回<BR> --> <BR> $html4 <BR> <A href="return.cgi?ID=$id"><B>トップページに戻る<B></A><BR> </FONT></SMALL> </TD> </TR></TABLE> </BODY> </HTML> end_mark exit(0); #時間表示用サブルーチン sub view_time { my ($tim) = @_; ( $sec,$min,$hour,$day,$mon,$year,$wday) = localtime($tim); $vtim = "$sec\秒"; if ($tim >= 60) { $vtim = "$min\分$vtim"; } if ($tim >= 3600) { $vtim = "$hour\時間$vtim"; } return $vtim; } ■ タイル移動処理 (プログラム名: "move.cgi") #!/usr/local/bin/perl print "Content-type: text/html\n\n"; #QUERY受け取り $mes = $ENV{ 'QUERY_STRING' }; @group = split(/&/,$mes); foreach $ans(@group) {($name,$value) = split(/=/,$ans); $value =~ s/%(..)/pack("c",hex($1))/ge; $ok_mes{$name}= $value;} $id = $ok_mes{'ID'}; $move = $ok_mes{'MOVE'}; #データ読み込み $datafile = "lib/id$id.cnt"; open(TXT,"<$datafile"); $or_data = <TXT>; close(TXT); @dt = split(/,/,$or_data); #(重要!ゲームデータに元からあるデータ)$dt[0] 幅, $dt[1] 高さ, $dt[2]制限時間(秒) #(重要!ゲーム中開始後に作成されるデータ)$dt[4] ゲーム名(数値のみ), $dt[5] ゲーム名, $dt[6] スタート時のタイム, $dt[7] 手数, $dt[8] 完成時のタイム, $dt[9] 完成時の手数 #(重要!)$dt[10~] タイル配置データ(ファイル名データ) $width = $dt[0]; $height = $dt[1]; $dt[7] = $dt[7] + 1; #手数 + 1 $max_val = @dt - 1; #読み込み最大値(要素数-1) $time_now = time - $dt[6]; #タイル移動 if ($move =~ /u/i){ #上に移動 $move =~ s/u//ge; $i = 0 * $width + $move + 9; #一番上のタイルの情報を取っておく $rsv = $dt[$i]; #一番上のタイルの情報を取っておく for ($y = 1 ;$y <= ($height - 1) ;$y++) { $i = ($y) * $width + $move + 9; $i_next = ($y - 1) * $width + $move + 9; $dt[$i_next] = $dt[$i]; } $i_next = ($height - 1) * $width + $move + 9; #一番下に一番上のタイルを移動 $dt[$i_next] = $rsv; #一番下に一番上のタイルを移動 } if ($move =~ /d/i){ #下に移動 $move =~ s/d//ge; $i = ($height - 1) * $width + $move + 9; #一番下のタイルの情報を取っておく $rsv = $dt[$i]; #一番下のタイルの情報を取っておく for ($y = ($height - 1) ;$y >= 1 ;$y--) { $i = ($y - 1) * $width + $move + 9; $i_next = ($y) * $width + $move + 9; $dt[$i_next] = $dt[$i]; } $i_next = 0 * $width + $move + 9; #一番上に一番下のタイルを移動 $dt[$i_next] = $rsv; #一番上に一番下のタイルを移動 } if ($move =~ /r/i){ #右に移動 $move =~ s/r//ge; $i = ($move - 1) * $width + $width + 9; #一番右のタイルの情報を取っておく $rsv = $dt[$i]; #一番右のタイルの情報を取っておく for ($x = ($width - 1) ;$x >= 1 ;$x--) { $i = ($move - 1) * $width + $x + 9; $i_next = ($move - 1) * $width + ($x + 1) + 9; $dt[$i_next] = $dt[$i]; } $i_next = ($move - 1) * $width + 1 + 9; #一番左に一番右のタイルを移動 $dt[$i_next] = $rsv; #一番左に一番右のタイルを移動 } if ($move =~ /l/i){ #左に移動 $move =~ s/l//ge; $i = ($move - 1) * $width + 1 + 9; #一番左のタイルの情報を取っておく $rsv = $dt[$i]; #一番左のタイルの情報を取っておく for ($x = 1 ;$x <= ($width - 1) ;$x++) { $i = ($move - 1) * $width + ($x + 1) + 9; $i_next = ($move - 1) * $width + $x + 9; $dt[$i_next] = $dt[$i]; } $i_next = ($move - 1) * $width + $width + 9; #一番右に一番左のタイルを移動 $dt[$i_next] = $rsv; #一番右に一番左のタイルを移動 } #データ書き込み $w_dt = join("\,", @dt); $datafile = "lib/id$id.cnt"; open(TXT,">$datafile"); print TXT $w_dt; close(TXT); #ゲームデータ読み込み $datafile = "lib/game$dt[4]\.cnt"; open(TXT,"<$datafile"); $or_data = <TXT>; close(TXT); @do = split(/,/,$or_data); $ununi = 0; #完成したかチェック for ($i = 10 ;$i <= $max_val ;$i++) { if ($dt[$i] ne $do[$i]){ $ununi = $ununi + 1; } } #制限時間オーバーかチェック $time_now = time - $dt[6]; if ((($dt[2] - $time_now) < 0)&&($ununi > 0)) { $ununi = -1; } if ($ununi == 0) { #完成の場合 #HTML1 print <<"end_mark"; <HTML> <HEAD> <TITLE>タイルdeパズル</TITLE> <STYLE TYPE="TEXT/CSS"> <!-- /* STYLE */ A:link {color:#EAEAEA; text-decoration:underline;} A:visited {color:#BFBFBF; text-decoration:underline;} A:hover {color:#FFDDDD; text-decoration:underline;} --> </STYLE> </HEAD> <BODY background=/bg.gif bgcolor=#8888FF> <META http-equiv="Refresh" content="0;URL=finish.cgi?ID=$id"> <SMALL><FONT color=#EAEAEA> 自動的にジャンプしない場合は<A href="finish.cgi?ID=$id">ここ</A>をおしてください。 </FONT></SMALL> </BODY> </HTML> end_mark exit(0); } if ($ununi == -1) { #時間オーバーの場合 #HTML1 print <<"end_mark"; <HTML> <HEAD> <TITLE>タイルdeパズル</TITLE> <STYLE TYPE="TEXT/CSS"> <!-- /* STYLE */ A:link {color:#EAEAEA; text-decoration:underline;} A:visited {color:#BFBFBF; text-decoration:underline;} A:hover {color:#FFDDDD; text-decoration:underline;} --> </STYLE> </HEAD> <BODY background=/bg.gif bgcolor=#8888FF> <META http-equiv="Refresh" content="0;URL=failed.cgi?ID=$id"> <SMALL><FONT color=#EAEAEA> 自動的にジャンプしない場合は<A href="failed.cgi?ID=$id">ここ</A>をおしてください。 </FONT></SMALL> </BODY> </HTML> end_mark exit(0); } #HTML1 #通常の処理 print <<"end_mark"; <HTML> <HEAD> <TITLE>タイルdeパズル</TITLE> <STYLE TYPE="TEXT/CSS"> <!-- /* STYLE */ A:link {color:#EAEAEA; text-decoration:underline;} A:visited {color:#BFBFBF; text-decoration:underline;} A:hover {color:#FFDDDD; text-decoration:underline;} --> </STYLE> </HEAD> <BODY background=/bg.gif bgcolor=#8888FF> <META http-equiv="Refresh" content="0;URL=game.cgi?ID=$id"> <SMALL><FONT color=#EAEAEA> 自動的にジャンプしない場合は<A href="game.cgi?ID=$id">ここ</A>をおしてください。 </FONT></SMALL> </BODY> </HTML> end_mark exit(0);
|