変数

変数とは

女の子の好感度について考えてみましょう。

初期値が5で、ある行動をとったら+1されて、別の行動ならば-1されちゃうような内容だとしましょう。その好感度を計算をする(正確にいえばTJS式を評価(実行)する)タグである eval タグで書くと次のようになります。

*scene1
[link target="*scene1-1"]そっとする[endlink][r]
[link target="*scene1-2"]なぐさめる[endlink]
[s]
*scene1-1
[eval exp="5+1"]
[jump target="*scene2"]
[s]
*scene1-2
[eval exp="5-1"]
[jump target="*scene2"]
[s]

*scene2

eval タグは exp 属性の値を評価(実行)します。その結果、"5+1"や"5-1"は実行されてそれぞれ6と4になります。

それだけです。

計算によって6もしくは4を求めた次の瞬間、その値は破棄されてしまいます。あとから計算結果を知りたくなっても手立てはありません。考えていただければわかると思いますが、計算結果をすべて記憶しておくことは無理なのです。メモリが少なく高価だった昔はもちろん、今のパソコンでもそんなことをしたらすぐにメモリ不足になります。

コンピュータはどの値があとから必要になるのかわかりませんから、計算した直後にすべての値を捨てます。その代わり、人間様であるプログラマの人たちが必要な情報だと指定することで、強制的に記憶させることができます。

そのための場所を変数というのです。

ロッカーみたいなものをイメージしてください。値を入れることができる箱がいっぱいあって、個々のスペースは数値で管理されています。スペースは膨大ですし、毎回同じのナンバーのところが使えるとは限りません。

ですのでプログラマは、a とか b とか number とか layer とかといったような名前で箱を識別しています。そして a という名前は何番のロッカーを使ってもいいですよ、と具体的に指示しているのがOS(Windows)です。たぶんね(よく知らない)。

代入と参照

変数を使って、さっきのサンプルを書き直してみましょう。

*scene1
[link target="*scene1-1"]そっとする[endlink][r]
[link target="*scene1-2"]なぐさめる[endlink]
[s]
*scene1-1
[eval exp="f.love = 5 + 1"]
[jump target="*scene2"]
[s]
*scene1-2
[eval exp="f.love = 5 - 1"]
[jump target="*scene2"]
[s]

*scene2

変数に値を格納することを変数に代入するといって、「変数名 = 式」と書きます。「5 + 1」のような記号を使ったものや、記号を使わずに単なる「3」と書いたものなどを式といいます。これで「f.love」という名前の変数に値が入りました。これによって、ゲームの後半でも好感度を確認することができるようになりました。逆に、変数の中身を見ることを変数を参照するといいます。「変数名」と記述すれば、変数の中身が必要なタイミングで参照されます。

[eval exp="f.a = 4"]
[eval exp="f.b = 9"]
[eval exp="f.c = 2"]
[eval exp="f.love = f.a + f.b * f.c"]

詳しくは式と演算子のページで説明しますが、「*」は掛け算の記号です。多くのプログラミング言語では「×」の代わりによく使われています。そして、TJSで書かれていますが内容は算数ですから、掛け算から先にやって足し算を後でやるというのは予想がつくでしょう。

まず、掛け算の方が優先度が高いため「f.b * f.c」が先に評価されます。評価するためには f.b と f.c の中身を知る必要があるので、それぞれ値を参照します。するとそれぞれ9と2ですので「f.love = f.a + 9 * 2」の計算を行えばいいのだとわかります。すなわち「f.love = f.a + 18」です。

そして、次に評価しないといけないのが「f.a + 18」です。同様に f.a を参照すると4なので、「4 + 18」を計算すればいいわけです。22のことですね。

最後に「f.love = 22」によって f.love に22を代入します。つまり、「f.love = f.a + f.b * f.c」は f.a などの値に左右されますが、この場合は f.love に22を代入する式だということがわかります。

加える

たとえば、f.love が10なのか20なのか具体的な数値はわかりませんが、その数値に+2したいというときはどうしたらいいのでしょうか。

答えは以下のとおりです。

[eval exp="f.love = f.love + 2"]

数式のように見てしまうと「0=2」となる不思議な式ですが、TJSの場合「=」は両辺が等しいことを保証する記号ではなく右辺を評価した結果を左辺の変数に代入するための記号です。

順に見ていきましょう。代入するのは一番最後ですので「f.love + 2」を先に評価する必要があります。f.love の値を参照した結果、仮に10だとすると、すなわち「10 + 2」という式になります。つまり12です。

そして「f.love = 12」を評価します。すると f.love に12を代入され、前の10は上書きされてしまいます。結果として、f.love は10から12へと2増加することになるのです。

この方法で、f.love が当初20でも-5であったとしても期待通りに動きます。

システム変数・ゲーム変数・一時変数について(蛇足)

KAGシステムの復習です。

KAGシステムがユーザ(KAGを使ってゲームを開発する人)に対して提供している変数は3種類あります。それぞれシステム変数・ゲーム変数・一時変数と呼ばれており、sf.foo, f.foo, tf.foo と記述します。ここで「foo」は適当な文字列です。(プログラミングの世界では花子さんみたいな適当な例を挙げるときに、よくfooやbarといった名前が使われます。)

一時変数(temporary flags)は、一般的なプログラミングにおける変数の使われ方のときに利用されます。つまり、今回使ったサンプルは一時変数でおきかえてもらっても構いません。ただし、ファイルへの書き込みが行われません。つまりセーブデータとして保存されませんので、ゲームを終了すると、一時変数の中身はすべて破棄されます。

それに対して、システム変数とゲーム変数は栞ファイルに保存されるので、途中でゲームを終了しても整合性をとる必要があるデータに用います。

ゲーム変数(game flags)は、各セーブデータ固有に保存される変数です。つまり栞1、栞2、栞3……と別々の値が書き込まれます。いわゆる好感度であったり、イベント通過したかしてないかなどを保存するときに用いられます。

システム変数(system flags)は、ゲームに対し保存される変数で、各セーブデータ共通のデータのとき用います。おまけモード発生条件(クリア回数など)やBGMの音量などを保存したいときに用います。

フラグについて(蛇足)

英語で旗を意味するフラグ(フラッグ)は、立っている状態と倒れている状態に大別できます。そのため、2種の状態を管理する変数のことをフラグというようになったそうです。

アドベンチャーゲームなどでもイベント通過の有無などをフラグ変数していたことから、転じて、それっぽいシーンやセリフのことをフラグと呼ぶようになりました。詳しくはja.wikipedia - フラグでも参照してください。

「変数」自体の英語は variable で、変化する(vary)ことができる(-able)ものという意味です。吉里吉里/KAGの変数には flag の f が使われていますが、2状態しか格納できないわけではありませんので。念のため。

 
tjs/variable.txt · 最終更新: 2008/09/14 19:30 by tohka