2016年12月30日

スクリプトの条件分岐をなるべく手抜きで実装する

年末年始でまとまった休みができました。
これで本腰を入れてゲームプログラミングするぞー

今回作り込むのはスクリプトの条件分岐部分。
シナリオスクリプトにifとかelseとか入れて、ある条件の場合だけシナリオを読み込むようにする



シナリオスクリプトに特定の命令を追加するタグは、[角括弧]で囲んだもので表すことにしている。
当然if文もこれで表すのが素直なんだけど、ある条件に合致しない行は読み込まないなどの分岐をどのように実装しよう?

ああああ
[if flag A = 12]
いいいい
[elseif flag A = 9]
うううう
[else]
ええええ
[endif]
おおおお

こんな感じの行な。これを読み込んだ時、flag Aが12の場合は「ああああ いいいい おおおお」、flag Aが9の場合は「ああああ うううう おおおお」 flag Aが存在しないか、9でも12でもない場合は 「ああああ ええええ おおおお」が表示されなくてはならない。

構文解析プログラムの定石では、このような場合はツリー構造を取るように実装する。
すなわちこんなメモリレイアウト

screenshot.17.png
うわあ面倒くせえ

別にifは入れ子にしなくてもいいんで。つーか恐らくゲームブックのプログラム化ごときで複雑なifの入れ子なんてつかわないんで。
元のゲームブックがそんな複雑な構造だったら文章にできないでゲソ。
つーわけで単にif〜elseif〜else〜endifが1階層だけ分岐するような構造を考える

ツリーをシリアルに展開するには?

ツリー構造になっているスクリプトはノードごとにグローバルな数値をつけることでシリアル化できる。
すなわちスクリプト例の構造だと

0 : ああああ
1 : [if flag A = 12]
1 : いいいい
1 : [elseif flag A = 9]
1 : うううう
2 : [else]
2 : ええええ
0 : [endif]
0 : おおおお

こんな感じ。これでどのように制御構造を管理するのか?
ノードの数値(以降行レベル)の他に「現在の制御レベル」のようなものを用意するとよい。

最初の制御レベルは「0」だ。[if]か[elseif]に到達するまで制御レベルはかわらない
ifタグに到達した場合、現在のフラグ状況がifタグに合致するかどうかを確認する。

《合致する場合》
制御レベルを「3」に更新する。こうすることで行レベルが1以上の行はパースしない

《合致しない場合》
制御レベルを「1」に更新する。次の[elseif]に到達するまで行レベルが1以上の行はパースしない


ラベル:龍の宝珠
posted by LoyalTouch at 07:51| Comment(0) | TrackBack(0) | ゲーム | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:


この記事へのトラックバック