プログラムリスト
Version 1.3.0、533ステップです.11行に続くのは16行です.
P0
1 E=B:F=G*90:H=SIN F-COS F*9:I=SIN F*9+COS F:FOR J=0 TO 2:F=J*6-1
2 FOR K=1 TO 2:IF FRAC (1ᴇ3*SQR (E+H*K<.5;F=F+K:K(J*ABS O)=2
3 NEXT K:E=B-H+I:I=-I:O(J)=F:NEXT J:PRINT :IF B+H=51+D*46;K=8
4 PRINT A;MID(P,1);MID(7+K-O,1);MID(Q,1);MID(G+1,1);R;CSR 3;
5 IF B≦13+D*43;C=362:D=7:PRINT "♥( Fin":GOTO #1
6 IF K=A+5;O=4:PRINT " ";
7 W=X+7:IF B=C+99;R=INT W*4:PRINT "'";
8 IF RAN#<.1 THEN 16
9 IF KEY="5";IF O≠0;B=B+H:GOTO O*O
10 T=5:IF KEY≠"4";T=3:IF KEY≠"6" THEN 9
11 G=4*FRAC ((G+T)/4:GOTO 1
16 V=O+7+INT ABS (COS B*4:S=V*5:PRINT CSR 3;MID(V+10,1)
17 R(J)=R(J)-INT (RAN#*V(J):PRINT :PRINT R;S;:IF R<1 THEN #1
18 J=RAN#↑RAN#↑RAN#+FRAC π:IF KEY="0";IF J≧1 THEN 1
19 IF S>0 THEN 17
20 IF V(J)=A+9;A=A+1:PRINT "♦"
21 X=X+SQR V/W:GOTO 1
P1
1 A=0:B=C+99:$="↑←↓→ )○>・○ (○<□syπΩS& @¥"
移動画面がもたつきますがバグではありません.なるべく高速な機種、PB-100 等のいわゆる Pocket BASIC Version 1機でのプレイを推奨します.
シミュレータ用リスト
Windows 用アプリ Pocket BASIC Simulator 0.12で動作確認しています.Android 用アプリ PokecomGO - CASIO PB simulator で動作確認しています.
以下のプログラムリストをコピーしてファイルを作成する、または次のリンクからダウンロードします. toronekos-adventure4_v130.bas をダウンロード(831 bytes)
[P0]
1 E=B:F=G*90:H=SIN F-COS F*9:I=SIN F*9+COS F:FOR J=0 TO 2:F=J*6-1
2 FOR K=1 TO 2:IF FRAC (1EX3*SQR (E+H*K<.5;F=F+K:K(J*ABS O)=2
3 NEXT K:E=B-H+I:I=-I:O(J)=F:NEXT J:PRINT :IF B+H=51+D*46;K=8
4 PRINT A;MID(P,1);MID(7+K-O,1);MID(Q,1);MID(G+1,1);R;CSR 3;
5 IF B<=13+D*43;C=362:D=7:PRINT "\HT( Fin":GOTO #1
6 IF K=A+5;O=4:PRINT " ";
7 W=X+7:IF B=C+99;R=INT W*4:PRINT "'";
8 IF RAN#<.1 THEN 16
9 IF KEY="5";IF O<>0;B=B+H:GOTO O*O
10 T=5:IF KEY<>"4";T=3:IF KEY<>"6" THEN 9
11 G=4*FRAC ((G+T)/4:GOTO 1
16 V=O+7+INT ABS (COS B*4:S=V*5:PRINT CSR 3;MID(V+10,1)
17 R(J)=R(J)-INT (RAN#*V(J):PRINT :PRINT R;S;:IF R<1 THEN #1
18 J=RAN#^RAN#^RAN#+FRAC PI:IF KEY="0";IF J>=1 THEN 1
19 IF S>0 THEN 17
20 IF V(J)=A+9;A=A+1:PRINT "\DI"
21 X=X+SQR V/W:GOTO 1
[P1]
1 A=0:B=C+99:$="\UA\LA\DA\RA )\CI>\DT\CI (\CI<\SQsy\PI\OMS& @\\"
既知の問題
ボスからも逃げることができてしまう!
ボスから逃げることができます.今(2024年)は、トロネコは戦士ではなく冒険家ですからそれで良いのかな、と考えていますが、 シミュレータ用(2004年公開)ではボスからの逃走を塞いでいます.良くないな、と考えていた時期もあったようです.
因みにボスは倒しても、または逃げても、白亜の扉を通過する度に出現します.
技術情報
変数表
変数 | 内容 | ノート |
---|---|---|
A | オーブの数 | 0~3 |
B | 座標 | 99~ |
C, D | 裏面用 | 表面:C=0:D=0 、裏面:C=362:D=7 |
E | 座標計算用 | |
F | 向き計算用, 視界計算用 | F=G*90 |
G | 向き | 0:↑, 1:←, 2:↓, 3:→ |
H | 前方と現在地の差 | G=0:9, G=1:1, G=2:-9, G=3:-1 |
I | 左(右)隣と現在地の差 | G=0:1, G=1:9, G=2:-1, G=3:-9 1行目の値(左隣)、3行目では反転する(右隣). |
J | FOR ~NEXT 、攻撃側またはオーブ獲得判定とウェイト | 1~3行目では 0:前方を調査, 1:左と左前を調査, 2:右と右前を調査 17行と20行については行番号マップを参照. |
K | FOR ~NEXT 、白亜の扉のフラグ | 3:前方は白亜の扉ではない, 8:前方は白亜の扉 |
O | 視界前・前進処理用 | -1: , 0:○, 1:・, 4:白亜の扉の通過、ボス出現 |
P | 視界左 | 5: , 6:), 7:○, 8:> |
Q | 視界右 | 11: , 12:(, 13:○, 14:< |
R | トロネコの HP | |
S | 敵の HP | |
T | 方向転換用 | |
V | 敵の種類(強さ) | 6~14 |
W | トロネコの強さ | |
X | トロネコの経験値 | |
L, M, U | 未使用(破壊) | |
N, Y, Z | 未使用 |
行番号マップ
行番号 | 処理概要 | ノート |
---|---|---|
1 | 視界計算準備 | |
2~3 | 視界計算 | K(J*ABS O)=2 について.IF K*O=0;K=2 から1ステップ減らしたもの.前方を調査(J=0 )している場合はループを抜ける.1マス前が壁(O=0 )の場合はループを抜ける. |
3~4 | 迷宮移動画面表示、前方は白亜の扉か? | |
5 | エンディング | |
6 | 白亜の扉が開く | |
7 | 妖精さんによる HP 回復他 | |
8 | 敵の出現 | |
9 | 前進 | O=0 以外、O=-1, O=1, O=4 のいずれかなら1歩前進.O=4 ならばボス戦、16行へ.それ以外は1行へ. |
10 | キー入力を待つ | |
11 | 方向転換 | |
16 | 敵設定、敵キャラクタ表示 | 出現する敵は座標と視界前(O)から求めている.スタート地点周辺の敵が最も弱くなるように計算式を設定している.裏面ではトロネコが充分強くなっているのでこの配慮は無い. O を絡めることで出現する敵をバラつかせ、ボスを出現させる. |
17 | ダメージ計算、戦闘画面表示、ゲームオーバー | 0<J<1 :敵の攻撃, 1≦J<2 :トロネコの攻撃 |
18 | 攻撃側またはオーブ獲得判定、ウェイト、逃げる判定 | |
19 | 勝利判定 | |
20 | オーブ入手 | 0<J<1 :他の条件が揃えばオーブを獲得, 1≦J<2 :獲得しない |
21 | 経験値獲得 | |
P1-1 | 初期設定他 |
今作で解説すべきは1~3行の視界計算だけでしょう.
迷路データは数式から
IF FRAC (1ᴇ3*SQR (E+H*K<.5;F=F+K:K(J*ABS O)=2
まず、壁や通路の情報の入った迷路データの見当たらないないことに驚かれることでしょう.なんと本作では数式から迷路を生成しています. これは昔の雑誌の PB-100 用投稿ゲームでは、しばしば見かけたテクニックです.
2行目の FRAC(1000 × √座標)
が0.5より小さければその座標は壁、0.5以上なら通路になります.
しかしこれだけで迷路の形が決まるのではありません. 座標(B)は、X 方向に1歩進む時は+1、または-1、そして Y 方向には+9、または-9しています.この Y 方向の値が変わることでも迷路の形が変わります.
1つの変数で2つのデータを扱う
X・Y 座標の2つの値を1つの変数で扱うのは、これもよく見かけたテクニックです.
その理由は、マップは二次元ですがメモリ上の地形データは線形に格納されていることが多く、地形データを参照する際に、二次元座標から線形座標に変換する計算を省ける利点が考えられます.
一方で、変数から X・Y 座標を取り出すのにコストが掛かります.しかし、このような省メモリテクニックを必要とするゲーム作品では、そもそも X・Y 座標の表示を諦めることが多いと思います.
30文字まで格納できる特殊文字変数($)は、しばしば迷路データの格納に使われました.16進数的にデータを扱い、1フロアにつき最大6×5マスの迷路を PB-100 に出現させたのでした.
本作では省メモリに加えて、広大で不定形な迷路をつくるのに一役かっているのですが、簡潔に説明するうまい言葉が見つかりません…
3歩進んで2歩下がる
F=G*90:H=SIN F-COS F*9:I=SIN F*9+COS F
1行目で求めている前(H)と左(I)のとる値は、 それぞれ -9,1,9,-1(H)、1,9,-1,-9(I)となります.
これは、トロネコの向き(F)から求めた前方と左方の値になります.(なんかこの辺り、うまい表現じゃありませんね…) 例えば、現在位置(B)に対して左斜め前の座標は B+H+I
に、右隣は B-I
に、 2マス前は B+2*H
になります.
これだけわかれば2~3行や6行、12行の解析は容易でしょう.ちなみに前進は B=B+H
でできますね.
変数 | 説明 | ↑ | ← | ↓ | → |
---|---|---|---|---|---|
G | トロネコの向き | 0 | 1 | 2 | 3 |
F | G*90 した値 | 0 | 90 | 180 | 270 |
H | 前方のマスと現在の座標の差 | -9 | 1 | 9 | -1 |
I | 左側のマスと現在の座標の差 | 1 | 9 | -1 | -9 |
コラム
ひとつのステートメントで複数の仕事をする
J=RAN#^RAN#^RAN#+FRAC π
ここでは、15行目の J=RAN#↑RAN#↑RAN#+FRAC π
について解説します. この命令では、戦闘中の表示用ウェイトと敵もしくは自分の攻守の決定をしています.
まずウェイトについては、π↑π↑π
を実行すると0.5秒程度のウェイトになることは、 ポケコンジャーナル誌上でも紹介されています.BASIC でウェイトといえば FOR
~NEXT
が真っ先にあがりますが、 こういった負荷の高い計算が有効なウェイトになる場合があります.
今作ではこの π
を RAN#
に置き換えることで、攻守を決する乱数を得ています.
R(J)=R(J)-INT(RAN#*V(J))
ここで14行目のダメージ処理の R(J)=R(J)-INT(RAN#*V(J))
の変数をずらせば FRAC
を外せるのでは?、 と考えた方は PB-100 プログラミングが板についています.しかし今作では他の処理との絡みで FRAC
を外せない理由があります.
敵に遭遇し戦闘ルーチンに突入するとすぐに R(J)=R(J)-INT (RAN#*V(J))
が実行されます. このときに J の値が敵のターン(0<J<1
)または自分のターン(1≦J<2
)の どちらでもないことを示す値(2≦J
)でないと、どちらかが不当にダメージを負うことになってしまいます.
しかし :J=2
などとしていては4ステップを消費してしまいそれは可能な限り避けたいところです.
敵の出現時点の HP をばらつかせるために、敵がダメージを負うぶんにはアリか?とも考えましたが、トロネコの攻撃力が上がるとどうしようもなくなる、と断念しました.
そこで今作では、移動画面表示時点で必ず一定の値をとる視界計算用のループの FOR J=0 TO 2
~NEXT J
を利用することにしました. 視界表示の終了時点では常に J=3
になっているので、これを戦闘前のターン用変数の初期化と兼ねます. 戦闘が連続で発生することが無く必ず一度は視界表示を挟むのも、このようなことができた一因です.
ある時点で値が一定であることが確実な変数は、以降の処理の初期化を兼ねることができないか、検討します.
ということで、J=3
で戦闘ルーチンに入ってくるので、14行目の FRAC
を外すと具合が悪いのでした.
敵のターン(3≦J<4
)・自分のターン(4≦J<5
)になってしまい戦闘突入の度に敵が攻撃してきます.
以上の例のように PB-100 作品では、リストの各部が入り組んだモザイクのように影響しあうことがしばしばです.PB-100 プログラミングが パズルのような魅力を持つと言われる所以でもあります.
ひとつの作品が誕生する過程では、推敲を重ねる毎に各命令の位置と意図が変化していきます. その様はまるでソレ本来の姿に辿り着くべく胎動しているようでもあり、プログラマはもはやそのエネルギーに惹きずられるに任せるほかないのです.
もはや末期です、ハイ.