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);


初めてのPerl (単行本)
初めてのPerl (単行本)をAmazon.co.jpでチェック


ホームへ



Copyright (C) 2008 KUNISAN.JP. All Rights Reserved.