CASIO pocket computer
PB-100の宇宙

rogue
by NUAO

公開日 2022/05/19

元祖 RPG をPB-100で!? 今宵、一次元ローグライクゲームがあなたのポケットにやってくる!

RUN DEG
_:B_@_:I7

ストーリー

あなたは戦士ギルドからの数年にわたる戦闘訓練を受け終わった.

これからギルドの一員となるに当たり、ギルドは試験としてあなたにひとつの課題を与えた.

その内容は、運命の洞窟に赴き、その地下5階で待つ魔物を討伐すること.成功の暁には、あなたはギルドの正式メンバーとして迎えられる.

この試練を達成するため、あなたは家族や友人に別れを告げ、与えられた武器や防具を携えて洞窟の迷宮へと入っていった.


ストーリーは、ウィキペディアのローグ > ストーリーと目的 の文章を元に一部を変更したものです.(PBロッキー 記)

操作方法

  1. 実行前に DEFM 5 と設定し ***VAR:31 の表示を確認しておくこと.
    • この操作は Pokecom GO で必要で、Pocket BASIC Simulator では不要です.(PBロッキー 記)
  2. shift0 でゲームスタートし、最初に地下1階のフィールドが表示される.自キャラは @

    RUN DEG
    IA_%@:!(I20
    
  3. 初期の自キャラのパラメータは、体力=5、攻撃力=2、満腹度=50.
  4. 4←自キャラの移動→6

    階段 % の上では8=上の階へ 2=下の階へ

  5. 階を移動すると、新たにマップ、敵、アイテムをランダムに生成する.
  6. 敵(A, B, C, , Ω)は階数に応じて1匹/階いる.倒せばその階にはいなくなる. 敵は自キャラに向かってきて、自キャラに隣接すると先制攻撃することがある.
  7. 敵に隣接したら4←→6で攻撃でき、乱数(自キャラの体力と攻撃力に応じた値を最大値とする)でダメージを与える.

    敵はカウンター攻撃することがある.敵の体力が0になれば倒れて時々食料を残す.

    バトル後は自キャラの体力が表示される.

  8. 移動、攻撃など1アクションごとに食料を1消費し、体力が0.2回復する.
  9. アイテムに重なると必ず拾い、対応した効果を得る.

    名称キャラクタ効果
    食料:満腹度+10
    水薬!体力を最大値まで回復
    武器(攻撃力が階数だけ up
  10. 敵を倒すと、敵の強さ応じて自キャラの体力、体力最大値、攻撃力が上がる.
  11. 満腹度が10を切ると自キャラが a となる.満腹度が0になると一歩ごとに体力を1消費する.
  12. 自キャラの体力が0になるとゲームオーバー.
  13. 地下5階においてラスボス Ω を倒すとゲームクリア.

PB-Sim形式プログラムリスト

[P0]
100 VAC
110 L=1:O=5:A=O:B=2:J=50:SET F0
150 GOSUB #2
200 GOSUB #1:J=J-1:IF J<0;J=0:A=A-1:IF A<0 THEN 720
202 A=A+.2:IF A>O;A=O
205 I$=KEY:IF I$="" THEN 205
210 IF I$="2";IF Q(C)=1;IF L<5;L=L+1:GOTO 150
215 IF I$="8";IF Q(C)=1;IF L>1;L=L-1:GOTO 150
220 IF I$="4";IF H=C-1 THEN 500
225 IF I$="4";IF C>0;C=C-1:GOTO 240
230 IF I$="6";IF H=C+1 THEN 500
235 IF I$="6";IF C<M-1;C=C+1
240 GOTO Q(C)*5+245
245 GOTO 300
250 GOTO 300
255 A=O:GOTO 270
260 J=J+10:GOTO 270
265 B=B+L
270 Q(C)=0
300 IF D<0 THEN 200
305 IF F<RAN#*10 THEN 200
310 P=.3:IF C>H;P=.7
315 IF RAN#<P THEN 330
320 IF H>0;IF H-1<>C;H=H-1
325 GOTO 350
330 IF H<M-1;IF H+1<>C;H=H+1
350 IF ABS(C-H)=1 THEN 510
400 GOTO 200
500 IF RAN#>.5 THEN 600
510 IF G>RAN#*10 THEN 700
520 GOTO 200
600 D=D-(A/2+B)*RAN#
610 IF D>0 THEN 510
620 IF RAN#<.5;IF Q(H)<>1;Q(H)=3
625 H=-2:B=B+E/2:O=O+E*2:A=A+E:IF A>O;A=O
630 IF L=5;PRINT "CLEAR !!    ":END
640 GOTO 200
700 A=A-(D/2+E)*RAN#
710 IF A>0 THEN 200
720 PRINT "GAME OVER...":END

[P1]
90 $=""
100 FOR K=0 TO 8
110 P=C+K-4
120 IF P>-1;IF P<M THEN 150
130 IF P>-2;IF P<M+1;$=$+"I":GOTO 260
140 $=$+" ": GOTO 260
150 GOTO Q(P)*10+160
160 $=$+"_": GOTO 260
170 $=$+"%": GOTO 260
180 $=$+"!": GOTO 260
190 $=$+":": GOTO 260
200 $=$+"("
260 NEXT K
265 PRINT CSR 9;"   ";CSR 8;A;
270 PRINT CSR 0;$;
290 IF D<0 THEN 320
300 $="ABC¥SG¥OM"
305 K=H-C+4
310 IF K>-1;IF K<9;PRINT CSR K;MID (L,1);
320 PRINT CSR 4;"@";:IF J<10;PRINT CSR 4;"a";
400 RETURN

[P2]
100 M=5+INT(RAN#*11)
120 FOR K=0 TO M-1
130 P=RAN#
140 Q(K)=0
150 IF P<.1;Q(K)=3
160 IF P<.05;Q(K)=2
170 IF P<.02;Q(K)=4
180 NEXT K
190 P=INT(RAN#*M):Q(P)=1:C=P
200 P=INT(RAN#*M):IF P=C THEN 200
210 H=P:GOTO (L-1)*10+250
250 D=2:E=1:F=3:G=2:RETURN
260 D=5:E=2:F=5:G=7:RETURN
270 D=10:E=4:F=7:G=9:RETURN
280 D=30:E=10:F=2:G=6:RETURN
290 D=80:E=20:F=1:G=4:RETURN

変数アサイン

変数説明
A自体力0~
B自攻撃力2~
C自位置0~M-1
D敵体力
E敵攻撃力
F敵移動力
G敵好戦性0~10
H敵位置0~M-1
I$キー入力用
J満腹度0~
Kカウンタ用
L現在の階数1~5
M現在の階のマップ長さ5~15
O自体力の最大値
P汎用
Q(0)~Q(14)マップデータ0=何もなし"_", 1=階段"%", 2=水薬"!", 3=食料":", 4=武器"("
$表示用及び敵キャラクタ用"ABCΣΩ"

行番号マップ

P0

行番号解説
100~110初期設定
150マップ生成
表示更新
200マップ表示し、腹を1減らし満腹度が0なら体力を1減らし体力が0なら死亡
202一歩歩くと体力が0.2回復する.最大値で飽和する.
キー入力とそれに応じた処理
205
210下層へ移動し、マップ生成へ
215上層へ移動し、マップ生成へ
220左:左隣に敵がいれば自攻撃ルーレットへ
225左:敵がいないので、左端でなければ左移動し、アイテム処理へ
230右:右隣に敵がいれば自攻撃ルーレットへ
235右:敵がいないので、右端でなければ右移動し、アイテム処理へ
アイテムが落ちていた場合の処理
240
245通路(何もしない)
250階段(何もしない)
255水薬(体力を最大値まで回復)
260食料(満腹度を+10)
265武器(階数だけ攻撃力をアップ)
270アイテムを取ったらマップから削除
敵の移動とそれに応じた処理
300敵が死んでいればパスして表示更新へ(次ターン)
305敵の移動力が低ければ、移動せず表示更新へ(次ターン)
310自のいる方向へ移動する確率を高めるためバイアス P を設定する
315
320左端でなく、左に自がいない場合は、左に一つ移動する
325隣接判定へ
330右端でなく、右に自がいない場合は、右に一つ移動する
350隣接判定 もし自と敵が隣接していたら敵攻撃ルーレットへ(先制被攻撃)
400隣接していなければ表示更新へ(次ターン)
攻撃ルーレット
500自攻撃ルーレット:1/2の確率で自攻撃ヒットへ
510敵攻撃ルーレット:(先制/カウンター攻撃)敵好戦性に応じた確率で敵攻撃ヒットへ
520自攻撃をミスand/or敵攻撃をミス ならば表示更新へ(次ターン)
自攻撃ヒット
600(自体力×0.5+自攻撃力)を最大値とした乱数で敵にダメージを与える
610敵が生き残ったら敵攻撃ルーレットへ(カウンター攻撃)
620敵が死んだら1/2の確率で食料を残す
625敵が死んだら敵位置を画面外に scope out し自パラメータを up(体力は最大値まで)
630死んだ敵がラスボス(地下5階)だったらクリア
640死んだ敵がラスボスでなかったら表示更新へ(次ターン)
敵攻撃ヒット
700(敵体力×0.5+敵攻撃力)を最大値とした乱数で敵からダメージを受ける
710自が生き残ったら表示更新へ(次ターン)
720自が死んだらゲームオーバー

P1 マップ及び敵・自キャラの表示

行番号解説
90
100K=表示対象のスクリーンアドレス
110P=K位置に対応するマップメモリのアドレス
120マップメモリのアドレスが通路内なら各キャラクタ書き込みへ
130マップメモリのアドレスが壁なら$に "I" を書き込む
140マップメモリのアドレスが通路外なので$に " " を書き込む
150各キャラクタ分岐テーブル
160マップメモリが0なら $"_" を書き込む
170マップメモリが1なら $"%" を書き込む
180マップメモリが2なら $"!" を書き込む
190マップメモリが3なら $":"を書き込む
200マップメモリがそれ以外(つまり4)なら $"(" を書き込む
260
265体力を表示する
270出来上がった画面データ $ を表示する
290敵が死んでいたらパス
300$ に敵キャラを描き戻す
305K=敵のスクリーンアドレス
310敵スクリーンアドレスが0~8の間なら描く
320自を描く(通常は "@"、腹減りで "a")
400

P2 マップ及び敵の生成

行番号解説
100マップ大きさをランダムで決める(5~15)
120
130
140まずマップには0を記載しておく
150もし乱数で0.1以下なら食料を置く
160もし乱数で0.05以下なら水薬を置く
170もし乱数で0.02以下なら武器を置く
180
190階段を決定し、自位置を階段の位置に設定する
200敵の位置を決めるが、自位置と重ならないようにする
210~290敵の位置を決定し、敵パラメータを設定する

PBロッキーより

Pocket BASIC 用ローグライクゲームはいかがでしたか?

僕は数度の戦死と餓死を経験した後に、クリアすることが出来ました.餓死でゲームオーバーした時は何ともいえない気分でした.

シミュレータ専用について

『rogue』は NUAO 氏がPB-100の宇宙に寄稿してくださったゲーム作品です.

HTML 化はPBロッキーが行い、その際に、他の掲載作とスタイルを統一するための変更を行いました.また、ストーリーはPBロッキーが用意しました.

実機を所有していない NUAO 氏は、本作品の開発を Pokecom GO で行ったそうです.寄稿に際して、動作速度の再現性のより高い Pocket BASIC Simulator で実行したところ、for 文を使っている「P1 マップ及び敵・自キャラの表示」に時間を要していることが判明しました.

この為に、シミュレータ専用とアナウンスして掲載することにしました.

1次元ローグライクゲームの鉱脈

ローグ(1980年 初版)の系譜に連なる NetHack(1987年~) の画面.nethack.alt.org を撮影.

PB-100 シリーズの Pocket BASIC はグラフィック機能を備えませんが、ゲームユースを意識した豊富なキャラクタを備えていて、時代毎の様々な人気ゲーム作品が無理やりにアレンジ移植されてきました.

ローグの PB-100 シリーズへの移植は、僕の知る限り初めてのことです.本作によっていよいよ、コンピュータ RPG 草創期の人気作品が移植されました.

他の移植作品がグラフィックをキャラクタで代替するのに難儀する中、誰が見てもどこから見てもローグに見える再現性で、無理やり感は皆無です!

2次元のフィールドを探索するローグを、1次元のフィールドにしたら、どのようなプレイ感になるのか? 作品はこれからの PB-100 用ゲームプログラマに示唆とインスピレーションを与えてくれることと思います.

NUAO 氏の厚意によって本作品は Public Domain で提供されます.存分に研究して改造して PB-100 用ローグライクゲームの可能性に挑戦してみてください!

成功の暁には、あなたはギルドの正式メンバーとして迎えられるでしょう… なんちゃって.