《第9回》ギコ猫アタッカー!『リアルタイム・アクションゲームを作る』
新時代のリアルタイム・ゲームは、これ。高速CPUやブロードバンド技術が可能にし
た、最新手法である。

※後記。このスクリプトは、一画面=一リロードという、究極のネットワーク・アクシ
ョンゲームなのですが、このシャレは、プログラマーの人でないと、ピンと来ないよう
です……。
※ダウンロードのコーナーから、windows用(jperl用sjis)と、Li
nux用(perl用euc)をダウンロードできます。
※windowsは、「http://localhost/cgi-bin/dea
th.pl」。linuxは、「http://localhost/cgi-bin
/death.cgi」です。
※インターネットに接続されているサーバからは、ネットワーク越しにもこのゲームを
愉しめます。
※ネットワークでこのゲームを愉しむには、最初からやるとスピードが遅いので、途中
からはじめると良いでしょう。「http://localhost/cgi-bin
/death.pl?db=00+x=3+s=2000+on=1+go=2+」




リアルタイム・アクションゲーム!

 Perlでゲーム作りに挑戦する。オセロのような"思考型"や、ライフ・ゲームの
ような"ありがち"、そして、RPG(文字ベース)など手法的に簡単なゲームではな
く、ずばり「リアルタイム・アクションゲー」である。

 まずは、起動画面を見ていただこう。

 障害物(岩?)の間に空いた、隙間の道(?)を落下していくキャラ……を操作して
、ただひたすら、命を長引かせるゲームである。クリアはない(笑)。
 パソ歴の長い読者は、この画面に見覚えがあるかもしれない。MSXや、それ以前、
パソコンがまだ8ビットだった時代に、BASICで繰り返し書かれたゲームである。


 ゲームを開始すると、DOS窓が開いて……。ちょっと待った! まさか、ギガ級P
entium4時代にこんなクソゲーをまじめに回顧する意義はないだろう。
 マシンの性能をフルに生かしたい。すなわち、通常のゲームは「1ステージごと」に
CDやHDDからプログラムやデータを読み込んで進行する。本スクリプトは、「1ア
クションごと」に、Webサーバに読みに行くのである(^ ^;)。
 8ビット時代に、BASICインタープリタでも余裕で動いたこのゲームも、1アク
ションごとのリロードは、さすがに負担が大きいらしく、PentiumV-700M
Hzでも速度が速くなると、操作がほとんどきかなくなる。途方もなく非効率的なこの
手法は、まさに、新時代のプログラム手法なのだ(?)。
@ マシンリソース大食らい。
A ネット帯域大食らい。
B サーバリソース大食らい。
C そして動いたゲームが、誰がやってもつまらない、ただのクソゲー。
 これこそ、贅沢中の贅沢。

スクリプト

 では、さっそくスクリプトを見てほしい(リスト1)。エンドロール・アニメに、行
を割いているわりには、あっさりしている。
 手法的には、「<BODY onLoad=setTimeout('loc
ation.href="URL"',TIME>」のタグにより、矢継ぎ早に
、次画面をリロードし続けることで、ゲームが進行する。
 今回は「getメソッド」。スクリプトの「$qs = $ENV{'QUERY_
STRING'}」に注目しよう。ブラウザのURL欄に「http://local
host/abc.pl?zzz」と記述してabc.plを起動すると、「$qs」
には、「zzz」が格納されるという寸法だ。この性質により、「1アクションごとの
画面推移=全変数」を、すべてURL欄に記述して、スクリプトに渡している。

《変数》
 変数の扱い方そのものが、このスクリプトのミソなので、変数を紹介しておこう。

$zenx=45…定数
 この定数を増やすと、横軸空間が広くなる(最大97)。デフォルトでは、横軸には
47個の障害物(=■)があるが、左端と右端は、常に障害物が存在する。この二つを
除外した、「47−2=45」が、x軸方向の障害物の最大値(dbの項目参照)。

$zeny=30…定数
 この定数を増やすと、縦軸空間が広くなる(最大99)。0〜30で、計31行の空
間をもっている。

db…$db…変数
 障害物のデータベース。10進数2桁で、横軸1行分の障害物を描画できる。
簡略図で描くと、
■     ■■■■00
■■     ■■■01
■■■     ■■02
■■■■     ■03

…のように、2桁の数字は岩の中の道の位置を表わしている(45で最右端)。
 障害物はぜんぶで31行あるので、2桁の数字が31並ぶ。たとえば、上図の3行の
岩と道は、00010203の8桁の数字で表わすことができる。

x…$ichi…変数
 キャラ猫の位置。障害物と同じ数字になると左がぶつかり、「障害物+7」になると
右がぶつかり、猫は死ぬ。「障害物−1」「+6」で障害物に接触するので、顔が恐怖
にひきつる(操作の項の図を参照)。

on…$on…変数
 1で通常の状態。0で起動初期。2〜7でキャラ猫が死ぬアニメの状態。8でアニメ
が終了して、スコアを表示している状態。

m…$m…変数
 0で猫が左を向く。1で右。

s…$s…変数
 スコア。記事の行数の制限から、スコア・パラメータが、落下スピードも兼ねている
(大きいほど速い)。

go…$go…変数
 キャラ猫の進行方向。0で連続左。1で1つ左。2で下。3で1つ右。4で連続右。


手法

 注意が必要な手法を解説しよう。

●&getiwa(→for(0..30){$iwa[$_]=substr($d
b,($_ * 2),2);})により、ズラズラと数字が並ぶ$dbを2桁ずつの
変数に分解し、$iwa[X]に入れている。
●&rotateでは、キャラ猫を1つ分落下させている。正確には、$iwa[X]
を一つずつズラし、障害物を上昇させているのだ。
最下端では、「$iwa[30]=($iwa[30]+ int(rand(3))
-1)」により、乱数で障害物の間の道の位置を、±1の範囲で変化することでうねら
せている。
 最上端では、数値がズレると、キャラ猫がズレるので、いちばん上と二番目は必ず同
じ数字になるようにしている。
 何のことか分からない読者は、「$iwa[0]=$iwa[1]」を削除すれば、
納得すると思う。
●&prnmainでは、実際に障害物を描いている。「for(0..$zeny)
」のループが、「$_=0」「$_=1」のときは、キャラ猫の上部分と下部分を描い
ている。キャラ猫の位置により、左右に描く全角空白の個数を調整している部分が少し
面倒なところ。

操作・起動

 キャラ猫はネットで流行っているネコキャラのバリエーションで作った。

 非公開のローカルWebサーバを起動させ、cgi-binフォルダにdeath.
plをコピー(リネーム不可)し、ブラウザから、「http://localhos
t/cgi-bin/death.pl」を起動すれば、ゲームが始まる。最初は、イ
ラつくほど遅いが、だんだん、スピードアップする。スコア1000くらいから、まと
もな速度になるだろう。

 中速度からはじめたい場合は、「http://localhost/cgi-bi
n/death.pl?db=00+x=3+s=2000+on=1+go=2+」
のようにパラメータを与えて起動する。sを大きくすると速くなる。

 操作は、実に単純。画面上の「<←↓→>」をクリック。左から、「連続左」「一つ
左」「下(連続解除)」「一つ右」「連続右」。


 猫の向きが変わったり、岩にぶつかりそうになると、顔が変わる。



 いずれにしてもクソゲー。救いようはない。これは、ゲームそのものを楽しむのでは
なく、ゲームで猫を殺したいS(サド)か、ネコのアニメを見て、最後に罵倒されたい
M(マゾ)が1分、時間をつぶすためのゲームである(笑)。


ネット上で公開

 ローカルWebサーバのためのゲームだが、ブロードバンド・ユーザーや、学校の専
用線につないだサーバを触れるユーザーなら、ネットで公開することもできるだろう。
回線の速度は、速ければ速いほどよい。
 Webサーバの設定を代え、ポートを外にも開き、ゲームを公開してみよう。

 以下私見だが、HTTPDを公開するなら、「AN HTTP Server」など
の歴史の浅いWebサーバより、思い切って「apache」を導入しよう。「IIS
」に関しては、「AN HTTP」より脆弱だとも思えないが、普及しているので、タ
ーゲットにされやすい。Webサーバを公開したとたんに、「IIS」を狙った連続攻
撃に、ただちにさらされるので、マメなアップデートを行なえない素人は手を出さない
ほうが無難かもしれない。

 外部に対してポートを開いたら、自分のマシンのIPアドレスを調べよう。IPが「
www.xxx.yyy.zzz」だとしたら、「http://www.xxx.y
yy.zzz/cgi-bin/death.pl」にアクセスすれば、Win以外の
OSからでもこのゲームを楽しむことができる。実はこのクソゲー、マルチプラットホ
ームだったのだ(当たり前)。

 Linuxマシンへ対応させるのも簡単である。1行目を「#!/usr/bin/
jperl」などとしてjperlにパスを通し、「charset=ShiftJI
S\">」のタグを「charset=x-euc-jp\">」にする
など、文字コードを気にすれば、まず動くだろう。

高速ブロバン時代こそ、Webサーバ+Perlスクリプトのクソゲー
 次にくる、さらなる高速ブロードバンド時代、光ファイバーFTTH時代にはいった
いどのようなコンテンツを供給したらよいのか。ちまた巷では、話題が尽きない。映画
?ミュージックビデオ?そう、動画。やっぱり動画なのか、結局は。行きつく先は、そ
こしかないのか。

 しかし、私はこう考える。Perlによるクソゲーを、ギガ級の高速回線で楽しむこ
とをこそ、人は、豊かと呼ぶのだ……と。
 誰かこの方法で『パックマン』をつくってほしい。
(辻 豊史)

 HP「今日からPerlプログラマー(http://www.geocities
co.jp/SiliconValley-Cupertino/6103/)」
 

リスト1 「リアルタイム・アクションゲーム」スクリプト(death.pl)
sjis保存。jperlで起動させる。
※注! 以下の「□」は、総て、「 」(全角空白)に置換して使用すること!

#!C:/Perl/bin/MSWin32-x86-object/jperl
#↑apache者は、パスを書く必要がある。↓□は、総て全角空白のことである
$qs = $ENV{'QUERY_STRING'};
$aki = "□□□□□□□□□□□□□";
$zenx=45;$zeny=30;$db=&ps("db");
$ichi=&ps("x");$on=&ps("on");
$m=&ps("m");
$s=&ps("s");
$go=&ps("go");
if ($on eq "") {
  $db ="20";$db x= ($zeny + 1);
  $ichi=23;$on=1;$m=0;$s=0;$go=2;srand;
}
$kgo = $go;
($kgo==0)&&($kgo=1);
($kgo==4)&&($kgo=3);
$ichi = $ichi + $kgo - 2;
($ichi < 0) && ($ichi = 0);
($ichi > ($zenx + 6)) && ($ichi = $zenx + 6);
($go >= 1)&&($go <= 3)&&($go=2);
&getiwa;
&rotate;
$br = "<BR><BR><BR><BR><BR><BR><BR><BR>";
$sp="□□□□□□□";#←全角空白7ケ
$deadz="<HR></BODY></HTML>";
$dead[1]="□ ∧∧□あ……!<BR>□(  ゚◆゚)∩<BR>⊂ ・**;∴<BR>□〜\□・ヽ.<BR>□□□□U U<BR>$br<BR>";

#dead処理
$dead[2]="$sp□(´⌒(´<BR>□□□□□□(´⌒;;;<BR>□□□(´⌒(´⌒;; <BR><BR>ひゅ〜<BR>□□・*<BR>□*;∴<BR>□□□□ノ∩ <BR>□□⊂□ ヽ <BR>□□□/(□。A。 )っ<BR>□□ U□∨□∨ <BR><BR><BR><BR>";
$dead[3]="$sp ・<BR><BR>$sp□*<BR><BR>$sp□∴;<BR><BR><BR><BR>$sp□□□*;<BR><BR>$sp□∴;*<BR><BR>□□□□∧∧□□|□□□どさりっ!<BR>\⊂(□□ ⊂⌒`つ□/<BR>";
$dead[4]="$br$sp$spふら〜.....<BR>$sp$sp$sp ∧∧<BR>$sp$sp$sp(; ゚д゚)<BR>$sp$sp$sp/□づつ<BR>$sp$sp□□□□〜/□ /<BR>$sp$sp□□□□□(/□∪";
$dead[5]="<BR>$br<BR><BR><BR>$sp$sp$sp□□(□□□∧∧<BR>$sp$sp$sp□⊂⌒つ*゜◇゜)つバタッ!";$dead[6]="<BR><BR><BR>□□□□⊂⊃<BR>□□□□∧ ∧<BR>□□□□( ゚Д゚)□ヴヴヴヴ...<BR>□□□|⌒つ□つ<BR>□□□川 |□|<BR>□□□□U□U<BR><BR><BR><BR>□□∧∧<BR>つ*゜◇゜)つ";$dead[7]="<BR>⊂⊃<BR>∧ ∧<BR>(゚Д゚ )ヘタクソッ<BR>⊂ □)⌒|<BR>□|□|川<BR>□U U$br";
if ($on==8) { 
  $speed="";
  &head;
  print"score□$s";exit;
}
if (($on > 1) || ($iwa[2] >= $ichi)||($iwa[2]+7<=$ichi)){ 
  $speed=2000;  $on++;&head;print $dead[($on-1)];print $deadz;exit;
}
$r1="□(□□∧∧♪";$l1="□ ∧∧□□)□";
$r2="⊂'⌒つ'Д`)つ";
$l2="⊂(゚Д゚⊂⌒'つ";
if (($iwa[2]+1 == $ichi) || ($iwa[2]+6 == $ichi)) {
  $l1=" Σ∧∧□く∩";$l2 = "∩(゚◆゚⊂⌒' )";
  $r2="( '⌒つ゚◆゚)∩";$r1="∩/ ∧∧□□";
}
$s=$s+10;$speed = 900-int($s/2);
($speed < 20) && ($speed = 20);
#game main;
&head;
&scline;
&prnmain;
print $deadz;

sub scline { 
  $s = sprintf("%05d", $s);
  print "$aki<FONT SIZE=+3>score□$s$aki<A HREF=\"${url}m=0\+go=0\+\"><</A>□<A HREF=\"${url}m=0\+go=1\+\">←</A>  <A HREF=\"${url}m=$m\+go=2\+\">  ↓</A>  <A HREF=\"${url}m=1\+go=3\+\">→</A>□<A HREF=\"${url}m=1\+go=4\+\">></A></FONT><BR>\n";
}

sub head {
  $url = "death.pl\?db=${db}\+on=${on}\+s=$s\+x=$ichi\+";
  $dead0="Content-type: text/html\n\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0   Transitional//EN\"><HTML><HEAD><TITLE>DEAD</TITLE><META http-equiv=Content-Type   content=\"text/html;
 charset=Shift_JIS\"><BODY   onLoad=setTimeout('location.href=\"${url}m=$m\+go=$go\+\"\',$speed)>";
  print $dead0;
}

sub getiwa { 
  for (0 .. $zeny) { 
    $iwa[$_] = substr($db, ($_ * 2), 2);
  }
}

sub prnmain {
  for (0 .. $zeny ) {
    $chara = $aki;
    if ($_ < 2){
      $c1=($ichi-$iwa[0]-1);
      $c2=5-$c1;$chara="";
      for (1..$c1) {
        $chara.="□";
      }
      ($m==0)&&($_==0)&&($chara.=$l1);
      ($m==1)&&($_==0)&&($chara.=$r1);
      ($m==0)&&($_==1)&&($chara.=$l2);
      ($m==1)&&($_==1)&&($chara.=$r2);
      for (1..$c2) {
        $chara.="□";
      }
    }
    $now = $_;
    for (0 .. ($iwa[$now] ) ) { 
      print "■"; 
    }
    print $chara;
    for (0 .. ($zenx - $iwa[$now]) ) {
      print "■";
    }
    print "<BR>\n";
  }
}

sub rotate {
  for (0 .. ($zeny - 1) ) {
    $iwa[$_] = $iwa[($_ + 1)];
  }
  $iwa[0]=$iwa[1];
  $iwa[$zeny] = ( $iwa[$zeny] +  int (rand (3)) - 1);
  ($iwa[$zeny]<0) && ($iwa[$zeny] = 0);
  ($iwa[$zeny] > $zenx)&&($iwa[$zeny]=$zenx);
  $db = "";
  for (0 .. $zeny) {
    $db .= sprintf("%02d", $iwa[$_]);
  }
}

sub ps { 
  local ($hensu) = @_;
  local ($psl) = $qs;
  $psl =~ s/^$hensu=([^+]*)\+?.*$/$1/;
  $psl =~ s/^.*\+$hensu=([^+]*)\+?.*$/$1/;return ($psl); 
}


−−−−−−−−−上記は、雑誌「I/O」掲載版−−−−−−−−−−−−−
-------以下は書籍「今日からPerl/CGIプログラマー」掲載の機能アップ版--------
---以下に関しての詳細は、書籍「今日からPerl/CGIプログラマー」を参照のこと---
---(書籍「今日からPerl/CGIプログラマー」は、図書館や大型書店にあります。)--
#!C:/Perl/bin/perl
#↑apache者は、パスを書く必要がある。↓□は、総て全角空白のことである
#ギコ猫アタッカー
#リアルタイムCGIゲーム
#
#perlスクリプトである。jperlでは動作しない。
#EUC+LFで保存すること。
#
#1行目を「#! /usr/bin/perl」などと、パスを通せば
#Unix系サーバでも動作可能
#
#copyright 2003 『今日からPerl/CGIプログラマー』 辻豊史
#http://www.geocities.co.jp/SiliconValley-Cupertino/6103/
#
#註・「□」は、総て全角空白のことである

#---定数決定
$zenx=45;#画面全体の横軸の大きさ
$zeny=30;#画面全体の縦軸の大きさ
$aki = "□□□□□□□□□□□□□";
#---QUERY_STRINGを変数に分解する
@get = split(/&/, $ENV{'QUERY_STRING'});
foreach (@get) { ($x ,$y) = split(/=/, $_);$q{"$x"} = $y;} 
$db=$q{"db"};$ichi=$q{"x"};$on=$q{"on"};$m=$q{"m"};$s=$q{"s"};$go=$q{"go"};
#---最初の起動の場合変数を初期値に(スコアがある場合のみスコアクリアしない)
if ($on eq "") {$db ="20"; $db x= ($zeny + 1);
  $ichi=23;$on=1;$m=0;$go=2;srand;(!($s>10))&&($s=0);}
#---$go 進む方向 $kgo goの「0」「1」は左「3」「4」は右なのでkgoで調整
$kgo=$go;($kgo==0)&&($kgo=1);($kgo==4)&&($kgo=3);$ichi=$ichi+$kgo-2;
#---$ichiが画面からはみ出ないように
($ichi < 0) && ($ichi = 0);($ichi > ($zenx + 6)) && ($ichi = $zenx + 6);
($go >= 1)&&($go <= 3)&&($go=2);
#---障害壁位置決定・障害壁ローテイト
@iwa = &getiwa($zeny,$db);($db,@iwa) = &rotate($zeny,@iwa);
#---描画定数
$br="<BR><BR><BR><BR><BR><BR><BR><BR>";$sp="□□□□□□□";#←全角空白7ケ
$page_end="<HR></BODY></HTML>";
#---死去アニメ画像
$dead[1]="□ ∧∧□あ……!<BR>□(  ゚◆゚)∩<BR>⊂ ・**;∴
<BR>□〜\□・ヽ.<BR>□□□□U U<BR>$br<BR>";#dead処理
$dead[2]="$sp□(´⌒(´<BR>□□□□□□(´⌒;;;<BR>□□□(´⌒(´⌒;; 
<BR><BR>ひゅ〜<BR>□□・*<BR>□*;∴<BR>□□□□ノ∩ <BR>□□⊂□ ヽ 
<BR>□□□/(□。A。 )っ<BR>□□ U□∨□∨ <BR><BR><BR><BR>";
$dead[3]="$sp ・<BR><BR>$sp□*<BR><BR>$sp□∴;<BR><BR><BR>
<BR>$sp□□□*;<BR><BR>$sp□∴;*<BR><BR>□□□□∧∧□□|□□□どさりっ!
<BR>\⊂(□□ ⊂⌒`つ□/<BR>";
$dead[4]="$br$sp$spふら〜.....<BR>$sp$sp$sp ∧∧<BR>$sp$sp$sp(; ゚д゚)
<BR>$sp$sp$sp/□づつ<BR>$sp$sp□□□□〜/□ /
<BR>$sp$sp□□□□□(/□∪";
$dead[5]="<BR>$br<BR><BR><BR>$sp$sp$sp□□(□□□∧∧<BR>
$sp$sp$sp□⊂⌒つ*゜◇゜)つバタッ!";
$dead[6]="<BR><BR><BR>□□□□⊂⊃<BR>□□□□∧ ∧
<BR>□□□□( ゚Д゚)□ヴヴヴヴ...<BR>□□□|⌒つ□つ
<BR>□□□川 |□|<BR>□□□□U□U<BR><BR><BR><BR>□□∧∧
<BR>つ*゜◇゜)つ";
$dead[7]="<BR>⊂⊃<BR>∧ ∧<BR>(゚Д゚ )ヘタクソッ<BR>⊂ □)⌒|
<BR>□|□|川<BR>□U U$br";
#---終了
if($on==8){$speed="10000";&head(undef,undef,$speed,undef,undef,$s,undef);
  print"score□$s<BR><BR>10秒後に再開します →
  <A HREF=$ENV{'SCRIPT_NAME'}?on=9&>NO</A>";exit;}
if($on==9){$speed="300000";&head(undef,undef,$speed);
  print"最初からやる → <A HREF=$ENV{'SCRIPT_NAME'}>click</A>";exit;}
#---死去アニメ
if (($on > 1) || ($iwa[2] >= $ichi)||($iwa[2]+7<=$ichi)){ $speed=2000;
  $on++;$url = &head($go,$m,$speed,$db,$on,$s,$ichi);print $dead[($on-1)];
  print $page_end;exit;}
#---キャラ猫アニメ
$r1="□(□□∧∧♪";$l1="□ ∧∧□□)□";
$r2="⊂'⌒つ'Д`)つ";$l2="⊂(゚Д゚⊂⌒'つ";
if(($iwa[2]+1==$ichi)||($iwa[2]+6==$ichi)){$l1=" Σ∧∧□く∩";
  $l2="∩(゚◆゚⊂⌒' )";$r2="( '⌒つ゚◆゚)∩";$r1="∩/ ∧∧□□";}
#---スピード計算(スコアより算出)
$s=$s+10;$speed = 900-int($s/2);($speed < 20) && ($speed = 20);
#--game main
$url = &head($go,$m,$speed,$db,$on,$s,$ichi);
&scline($s,$url);#操作パネル
&prnmain($zeny,$zenx,$ichi,$m,$r1,$r2,$l1,$l2,@iwa);#メイン描画
print $page_end;
#---サブルーチン
#---操作パネル表示
sub scline { my $s = shift;my $url =shift;
  $s=sprintf("%05d", $s);print "$aki<FONT SIZE=+3>score□$s$aki
 <A HREF=\"${url}m=0\&go=0\&\"><</A>□<A HREF=\"${url}m=0\&go=1\&\">←</A>
 <A HREF=\"${url}m=$m\&go=2\&\">  ↓</A>  <A HREF=\"${url}m=1\&go=3\&\">→
 </A>□<A HREF=\"${url}m=1\&go=4\&\">></A></FONT><BR>\n";}
#---HTMLヘッダと次画面読み込み表示
sub head {my $go = shift;my $m = shift;my $speed = shift;
  my $db = shift;my $on = shift;my $s = shift;my $ichi = shift;
  my $url = "$ENV{'SCRIPT_NAME'}?db=${db}\&on=${on}\&s=$s\&x=$ichi\&";
  my $dead0 = "Content-type: text/html\n\n<!DOCTYPE HTML PUBLIC \"-//
W3C//DTD HTML 4.0 Transitional//EN\"><HTML><HEAD><TITLE>CAT ATTACKER</TITLE>
<META http-equiv= Content-Type content=\"text/html;
 
charset=x-euc-jp\">
<BODY onLoad=setTimeout('location.href=\"${url}m=$m&go=$go\&\"\',$speed)>";
  print $dead0;return($url)}
#---障害物(岩壁)の位置を確定($dbには岩壁のない位置が入っている。
#---例えば、03 04 04……のように2桁分で区切れる。
#---2桁分で画面1行分の岩壁の位置が計算できる
sub getiwa { my $zeny = shift;my $db = shift;my (@iwa);
 for (0 .. $zeny) { $iwa[$_] = substr($db, ($_ * 2), 2);}
 return(@iwa); }
#---メイン部分描画
sub prnmain { ($zeny,$zenx,$ichi,$m,$r1,$r2,$l1,$l2,@iwa) = @_;
  for (0 .. $zeny ) { my $chara = $aki;my $now = $_;
    #--最初の二行はキャラ猫を描くので$akiを作成しなおす
    if($_<2){$chara="";my $c1=($ichi-$iwa[0]-1);my $c2=5-$c1;
      for(1..$c1){$chara.="□";}
      ($m==0)&&($now==0)&&($chara.=$l1);
      ($m==1)&&($now==0)&&($chara.=$r1);
      ($m==0)&&($now==1)&&($chara.=$l2);
      ($m==1)&&($now==1)&&($chara.=$r2);
      for(1..$c2) {$chara.="□";}
    }
    #---障害壁の中にキャラ猫or空白($aki)を描画
    for (0..($iwa[$now])){print "■";} 
    print $chara;
    for(0..($zenx - $iwa[$now]) ) { print "■"; } 
    print "<BR>\n"; 
  }
}
#---障害壁を一つアップ
sub rotate { my $zeny = shift;my @iwa = @_;my $db = "";
  for (0 .. ($zeny - 1) ) { $iwa[$_] = $iwa[($_ + 1)];}
  #---一行目は二行目と一緒にしてキャラ猫の場所を確保
  $iwa[0]=$iwa[1];$iwa[$zeny]=($iwa[$zeny]+int(rand(3))-1);
  ($iwa[$zeny]<0) &&($iwa[$zeny]=0);($iwa[$zeny]>$zenx)&&($iwa[$zeny]=$zenx);
  for (0 .. $zeny) { $db .= sprintf("%02d", $iwa[$_]);}
  return($db,@iwa); }