Manuke Station : LRProblem

LRProblem

ここは、『一画面詰めロードランナー』を紹介するページです。
……えっ、「元々ロードランナーは一画面だ」って?
確かにおっしゃる通り。しかし、ここで紹介するのはゲームの面データではなく、プログラムのソースコード(Java)が一画面に収まるものなんです。

L.java : 79文字x16行

import java.awt.*;import java.io.*;class L extends Frame{int W,H,T,U=12,p,t,g,e
,l,r,u,d,a,b,i,j,k,x,y,m[],w[];char[]q={'□','田','田',' ', ' ̄','#',' ','◎',
'★'};L(String n){try{BufferedReader f=new BufferedReader(new FileReader(n));W=
Integer.valueOf(f.readLine()).intValue();H=Integer.valueOf(f.readLine()).
intValue();m=new int[T=W*H];w=new int[T];for(;i<T;g+=m[i++]>6?1:0){n=(j=i%W)<1?
f.readLine():n;if((m[i]=(int)n.charAt(j)-48)>7)m[p=i]=3;}Canvas c=new Canvas(){
{resize(W*U,H*U);}public void paint(Graphics g){for(k=T;k-->0;)g.drawChars(q,m[
k],1,k%W*U,k/W*U+U);g.drawChars(q,8,1,p%W*U,p/W*U+U);}};add(c);pack();show();m:
for(;g>0|p>W*2;Thread.sleep(20)){e=0;for(i=T;i-->0;)if(w[i]>0&&--w[i]<1){e=m[i]
=1;if(i==p)break m;}if((i=m[p])>6){m[e=p]=3;if(--g<1)for(g=T;g-->0;)m[g]-=m[g]>
5?1:0;}if(t>0)t--;else{p+=i=i!=4&i!=5&(j=m[p+W])>1&j!=5|d>0&j>1?W:u>0&i==5&m[p-
W]>2?-W:l>0&m[p-1]>2?-1:r>0&m[p+1]>2?1:0;if(i!=0)e=t=4;if(i==0&(i=a>0?p+W-1:b>0
?p+W+1:0)>0&m[i]==1)if((j=m[i-W])==3|j==6){m[i]=3;e=w[i]=500;}}if(e>0)c.repaint
();}}catch(Exception e){}}public boolean handleEvent(Event e){y=(x=402-e.id)>=0
&x<2?e.key-48:0;l=y==4?x:l;r=y==6?x:r;u=y==8?x:u;d=y==2?x:d;a=y==42|y==74?x:a;b
=y==40|y==72?x:b;return 1>0;}public static void main(String[]a){new L(a[0]);}}

上記のソースをコピー/テキストエディタを使って「L.java」という名前で保存し、Javaコンパイラでコンパイルしてみてください。
(ちょっと古めの関数を使ってますので、コンパイル時に警告が出るかもしれません)
立派(?)な『詰めロードランナー』アプリケーションが出来上がります。:-)
(ただし、面データは別途テキストファイルで用意しなければいけませんが……)
実行は、以下のように面データを引数で指定します。

java L map.txt

ちなみに、画面はこんな感じ。

詰めロードランナー画面

操作はおなじみの2/4/6/8で移動、Z/Xで穴掘りです。
すべての金塊を取って、画面一番上にたどり着いたらゲームクリアです。
プログラムは終了処理が入っていませんので、終わるときはCtrl+Cで中断させてください。(もしくはプロセス自体をKILL)
画面上の要素は

□ : ブロック(掘れない)
田 : レンガ(掘れる)、または落とし穴
 ̄ : バー
# : はしご
◎ : 金塊
★ : プレイヤー

となります。
「番兵がいないじゃないか」って? そう、ですから『詰めロードランナー』なんです(^^;)

なお、ゲームをプレイするにあたっては、面データをテキストファイルで作っておかなければいけません。
以下に、画面スナップショット用の面データファイルを示します。

map.txt

12
7
000000000000
033333333360
033334337360
075112115360
035177715360
035177715860
000000000000

1行目に幅、2行目に高さを指定します。
配置するものの番号は

0 : ブロック(掘れない)
1 : レンガ(掘れる)
2 : 落とし穴(外見はレンガと同じ)
3 : 空白
4 : バー
5 : はしご
6 : 脱出はしご(金塊を全て取った時に出現)
7 : 金塊
8 : ロードランナー

です。
なお、プログラムの都合で、面データの周囲は必ずブロックを配置してください。
(従って、上から2段目が最上段扱いになります)

おまけとして、逆転掘り面データ。
(ブロック復活の時間差を利用する高等テクニックです)

map2.txt

7
10
0000000
0353330
0353330
0158310
0131510
0151310
0131510
0151710
0111110
0000000

1