完全な初心者のためのWMLガイド/第10章:ロジック入門

Last-modified: 2017-03-25 (土) 20:50:40
 

もし、これ、それ、あれ

食料品を買うために食料品店に行ったとします。駐車場に車を停めて店に向かって歩き始めると、突然あなたは車のドアを閉めるかどうか覚えていないことに気づきました。あなたは、車のドアが開いているかどうかを調べるために戻ります...
...そして何が?
さて、車のドアが開いている場合、あなたはそれを閉じることを忘れていたことを知っているので、あなたは食料品店に入る前にそれを閉じます。車のドアが開いていない場合は、何もする必要はないので、店に向かって歩き続けます。
この種のロジック(条件付きロジックと呼ばれる)は、条件を評価し、その条件の状態に基づいて反応を決定します。上記の例では、車のドアが開いているかどうかが条件です。それが開いている場合は、あなたはそれを閉じます。それが開いていない場合、あなたは店に向かって歩き続けます。
WMLでは、条件を評価して反応するために多数の論理演算が利用できます。最初に行うのはif/then操作です。この操作の構文は次のとおりです。

 
[if]
    (condition)
    [then]
        (do something)
    [/then]
[/if]
 

その他
if節では、条件が真であれば何かをします。しかし、条件が真でない場合はどうすればよいですか?上記の例では、条件が真でない場合、WMLエンジンは何もしないので、実行し続けるだけで何もしません。ただし、タグセット[else]を使用して、条件が真でない場合にもゲームにタスクに実行させることは可能です。構文は次のとおりです。

 
[if]
    (condition]
    [then]
        (何かをする)
    [/then]
    [else]
        (何か他のことをする)
    [/else]
[/if]
 

車のドアの例に戻って、ドアが開いているかどうかを確認するために戻る前に、ドアが開いていればドアを閉じてドアを閉めることにします。あなたの天才を祝うためにバックフリップをして、駐車場を食料品店まであなたの旅を続けるでしょう。擬似コード:

 
[if]
    車のドアが開いているか?
    [then]
        開いていれば、それを閉じて店に向かう。
    [/then]
    [else]
        開いていないなら、バックフリップをして店に向かう。
    [/else]
[/if]
 

うう、またしても作者はこの章を完成させないまま放置したようです。頑張って続きを書いてみます。
次のセクションでは、これをWMLで書くとどうなるか考えてみましょう。

 

条件を設定する

[if]文の最初に来る項目は「もし~なら」という条件の設定です。WMLではこの条件の設定をたしか condition filter と言っています。[if]文で最も頻繁に使われる condition filter は変数です。
少し前の章で変数について軽く触れましたが、そこでは変数が具体的にどんな使い方をされるのか紹介していませんでした。ここで、その実例を見ることになります。

 

用途に合わせた変数の作成
車のドアが開いているか?という条件をWML的に表現するために変数を使います。まず、変数の作り方をもう一度見てみましょう。

 
[set_variable]
    name=variable_name
    value=variable_value
[/set_variable]
 

nameが変数の名前で、valueがその値です。今回はnameを状況に即した名前「Car_door_open」とします。valueには「yes」または「no」を割り当てます。

 
[set_variable]
    name=Car_door_open
    value=yes
[/set_variable]
 

今、車のドアが開いているという状況を変数が作り出しました。ドアが閉まっていることにしたいなら「 value=no」とします。

 

condition filter
車のドアの状況を表した変数があるので、それを[if]文で使えるようになりました。「車のドアが開いているか?」の部分はこうなります。

 
[if]
    [variable]
        name=Car_door_open
        equals=yes
    [/variable]
    [then]
        開いていれば、それを閉じて店に向かう。
    [/then]
    [else]
        開いていないなら、バックフリップをして店に向かう。
    [/else]
[/if]
 

[variable]というタグは変数の値を調べる時に使います。nameキーには調べる対象の変数の名前が入ります。equalsキーは調べる方法です。ここでは対象の変数の値がyesとイコールなら[then]、イコールで無いなら[else]が実行されます。
調べる方法を示すキーは他にnot_equals、greater_than、less_than_equal_toなど複数の種類があります。

 

条件に合わせて実行する内容を設定する

次は[then]と[else]それぞれの状況で発生するイベント内容を設定するだけです。とはいえ、今ここで車のドアを閉じるアニメーションを作るのは面倒なのでユニットに喋らせるだけにします。

 
[if]
    [variable]
        name=Car_door_open
        equals=yes
    [/variable]
    [then]
        [message]
            speaker=unit
            message= _ "I closed the door of the car. I will head to the store now."
        [/message]
    [/then]
    [else]
        [message]
            speaker=unit
            message= _ "The car door was closed, yeah! I will backflip!"
        [/message]
    [/else]
[/if]
 

うん、これで[if]文を使ったイベントが完成しました!次はさっき作ったドアの状況を表す変数とこの[if]文を一つにまとめて、シナリオファイルに書き込める形にしてみましょう。

 

イベントの体裁を整える

シナリオの中でこのイベントが発生するストーリーを考えてみましょう。
ユニット「driver」は座標x1,y1に車を駐車して少し離れた村のショップに向かっています。その途中で車のドアが気になり始め車に戻ることにしました。
ユニット「driver」が座標x1,y1に移動するとイベントが発生するようにするには、

 
[event]
    name=moveto
    first_time_only=no
    [filter]
        id=driver
        x,y=1,1
    [/filter]
    [set_variable]
        name=Car_door_open
        value=yes
    [/set_variable]
    [if]
        [variable]
            name=Car_door_open
            equals=yes
        [/variable]
        [then]
            [message]
                speaker=unit
                message= _ "I closed the door of the car. I will head to the store now."
            [/message]
        [/then]
        [else]
            [message]
                speaker=unit
                message= _ "The car door was closed, yeah! I will backflip!"
            [/message]
        [/else]
    [/if]
    [clear_variable]
        name=Car_door_open
    [/clear_variable]
[/event]
 

このようになります。idがdriverであるユニットが座標x1,y1へ移動すると変数Car_door_openが作成され、[if]文がその値を評価し、表示するメッセージを決定し実行する。最後に使用済みの変数Car_door_openを消去してイベントが終了します。

 

未確定の状況を作る

お気づきだとは思いますが、このイベントでは[else]が実行されることは一切ありませんね。これでは[if]文でイベントを作る意味がわからなくなります。
変数Car_door_openをnoにしておけば[else]が実行されますが、今度は[then]が実行されるチャンスが無くなります。この問題は変数Car_door_openがランダムに決定されるようにする事で解決できます。

 

value以外のキー
変数の値を決めるキーはvalue以外にも沢山あります。その中にはランダムな数字を割り当てるキーも存在します、このキーが問題を解決してくれます。

 
[set_variable]
    name=Car_door_open
    rand=1,2
[/set_variable]
 

randは指定された数字からランダムに一つを選択して変数に割りあてるキーです。この例では1か2どちらかの値がランダムに割り当てられます。
数字を指定する方法は上記のような使用する数字をコンマで区切って表す方法の他に、「rand=3..5」範囲を示す方法もあります。

 

これでCar_door_openの値は変数が作成されるまで1と2のどちらに決定するか、わからなくなりました。さらに、値が数字になったのでcondition filterの部分を修正しましょう。

 
[variable]
    name=Car_door_open
    equals=1
[/variable]
 

ようやく[if]文の真価が発揮できるようになりました。完成した[if]文イベントがこれです。

 
[event]
    name=moveto
    first_time_only=no
    [filter]
        id=driver
        x,y=1,1
    [/filter]
    [set_variable]
        name=Car_door_open
        rand=1,2
    [/set_variable]
    [if]
        [variable]
            name=Car_door_open
            equals=1
        [/variable]
        [then]
            [message]
                speaker=unit
                message= _ "I closed the door of the car. I will head to the store now."
            [/message]
        [/then]
        [else]
            [message]
                speaker=unit
                message= _ "The car door was closed, yeah! I will backflip!"
            [/message]
        [/else]
    [/if]
    [clear_variable]
        name=Car_door_open
    [/clear_variable]
[/event]
 

あなたは、かなり複雑なイベントを構築できるようになりました。この調子で次に進みましょう。

第9章へ戻る
第11章へ進む?
目次に戻る