本記事は「ツクールアドベントカレンダー Advent Calendar 2022」12月8日分の投稿記事です。
「変数を使いこなそう(1) ゲームデータの活用法」の続編でもあります。こちらも併せてご覧ください。
変数の計算
前回の記事では、RPGツクールにおける「変数」の概念と、主に「オペランド」の「ゲームデータ」で扱える値の活用法を解説しました。
ゲームデータでは、ゲーム内に登場する値を変数に代入する使い方が中心でしたが、「変数の操作」では代入だけでなく数値計算も可能です。
「操作」のところには「代入」以外に、「加算」(足し算+)、「減算」(引き算-)、「積算」(掛け算×)、「除算」(割り算÷)と、基本的な四則演算ができるようになっています。
ところで、その最後に「剰余」というあまり馴染みのない項目があります。
これは何でしょう。
剰余とは
「剰余」とは「じょうよ」と読み、小学校の算数でやった、割り算の「あまり」のことです。
「37÷3=12、あまり1」の「1」を求める計算ですね。
37が格納されている変数に対して、定数3で剰余の操作をすると、変数には1が入ります。
ツクールでは%
の記号で表されています。他のシステムやプログラム言語では\
やmod
で表されることも多いです。
剰余の概念自体はそんなに難しいものではありません。
問題は、こんなの何に使うんだ?ってことですよね。
今回は剰余の活用法について解説します。
剰余の活用法
プログラムを嗜む人はご存じかもしれませんが、剰余は純粋に余りを求めるというよりは、余りを応用した計算に使うことが多いです。
以下、代表的な使い方を解説します。
3の倍数でアホになる
剰余の最も多い使い方は、Nの倍数かどうかの判別です。
ある数をNで割って、余りが0ならば、ある数はNの倍数です。
Nが2であれば、2の倍数かどうか、すなわち偶数か奇数かの判定となります。
例えば、1から100までの数字をカウントして、3の倍数の時だけアホになる、懐かしいイベントを作ってみましょう。
◆変数の操作:#0001 変数A = 1
◆ループ
◆変数の操作:#0002 変数B = 変数A
◆変数の操作:#0002 変数B %= 3
◆条件分岐:変数B = 0
◆スイッチの操作:#0001 アホ = ON
:それ以外のとき
◆スイッチの操作:#0001 アホ = OFF
:分岐終了
◆条件分岐:アホがON
◆SEの演奏:Crow (90, 130, 0)
◆文章:なし. SF_Monster(3), ウィンドウ, 下
: :\V[1]\.\.\^
:それ以外のとき
◆文章:なし. Evil(3), ウィンドウ, 下
: :\V[1]\.\.\^
:分岐終了
◆条件分岐:変数A >= 100
◆ループの中断
:それ以外のとき
◆変数の操作:#0001 変数A += 1
:分岐終了
:以上繰り返し
3を含むとアホになる
さて、本家は3の倍数だけじゃなくて、3を含む数字(13や35など)もアホになる対象でした。
実際のプログラムであれば、いったん数字を文字列に変換して、3の文字を含むかどうかで判定するのが一般的かと思われますが、ツクールのイベントコマンドではそこまで器用なことはできません。
ではどうするのかというと、それぞれの桁で分けて、一の位が3かどうか、十の位が3かどうかで判定します。
カウントする数字は1から100までですが、100は明らかに3を含まないので、十の位までで十分です。
先ほどの「スイッチの操作:アホ = OFF」の直後に以下の判定を入れ込みます。
◆変数の操作:#0002 変数B = 変数A
◆変数の操作:#0002 変数B %= 10
◆条件分岐:変数B = 3
◆スイッチの操作:#0001 アホ = ON
:それ以外のとき
◆変数の操作:#0002 変数B = 変数A
◆変数の操作:#0002 変数B /= 10
◆条件分岐:変数B = 3
◆スイッチの操作:#0001 アホ = ON
:分岐終了
:分岐終了
一の位を求めるのに剰余を使いました。すなわち、10で割った余りが一の位の数字になります。これが3かどうかを確かめれば、一の位が3かどうかを判別できます。
十の位は除算を使います。ツクールでは除算の場合、小数点以下は切り捨てになるので、10で割った答えが3かどうかを確かめれば、十の位が3かどうかを判別できます。
今回は1~100だったので、一の位と十の位だけで足りましたが、これが1~1000だった場合は、十の位はもう一工夫必要になります。
1~1000の場合、一の位は変わらず10の剰余が3かどうかで判別します。百の位は100で除算して3かどうかで判別します。十の位は、まず10で除算して、その結果からさらに10の剰余を求めて、3かどうかで判別します。
桁数が増えるほど計算過程が増えていくので、桁数が5桁とかを超えるようであれば、スクリプトを使って判定した方が楽だと思います。
秒数を時分秒に変換
前述のように、剰余の計算は数値の一部を取り出すのに使えます。それの応用例をもう一つ見てみましょう。
変数の操作では「ゲームデータ」の「その他」から「プレイ時間」を取得することができます。
ただし、このプレイ時間は秒数で返されるため、ここから○時間○分○秒に変換するためには、除算と剰余を駆使する必要があります。
具体的には、秒はプレイ秒数を60で割った余り(剰余)。時間はプレイ秒数を3600(60分×60秒)で除算した結果。そして分がやや複雑で、まずプレイ秒数を60で除算して、さらにその結果から60の剰余を求めます。前述の1~1000までカウントする場合の、十の位を求めるのに似ていますね。
◆変数の操作:#0021 プレイ秒数 = プレイ時間
◆変数の操作:#0022 時間 = プレイ秒数
◆変数の操作:#0022 時間 /= 3600
◆変数の操作:#0023 分 = プレイ秒数
◆変数の操作:#0023 分 /= 60
◆変数の操作:#0023 分 %= 60
◆変数の操作:#0024 秒 = プレイ秒数
◆変数の操作:#0024 秒 %= 60
◆文章:あなたのプレイ時間は \V[22]時間 \V[23]分 \V[24]秒です。
トランプの札番号
カジノシステムやミニゲームなどでトランプを扱うことも多いでしょう。
トランプの札にはマーク(スペード、ハート、ダイヤ、クラブ)と数(A、2……10、J、Q、K)の2種類の要素がありますが、これを別々で管理するのは効率が悪いです。
トランプの札が何かを表すのに1~52の連番として扱い、1~13をスペードのA~K、14~26をハートのA~K、27~39をダイヤ、40~52をクラブとして扱うと、1つの値でマークと数の両方を表せるので効率が良いです。
この時、連番になった札番号からマークと数を取得するのに、除算と剰余が活躍します。
まず札番号から1を引きます。
マークは1引いた札番号を13で除算し、0ならスペード、1ならハート、2ならダイヤ、3ならクラブです。
そして数は1引いた札番号から13の剰余を求めます。これだと0~12になってしまうので、1加算して1~13を求めます。
◆変数の操作:#0032 マーク = 札番号
◆変数の操作:#0032 マーク -= 1
◆変数の操作:#0032 マーク /= 13
◆変数の操作:#0033 数 = 札番号
◆変数の操作:#0033 数 -= 1
◆変数の操作:#0033 数 %= 13
◆変数の操作:#0033 数 += 1
以上でトランプの札を効率的に管理することができるでしょう。
循環する数値
0、1、2とカウントして、次はまた0に戻るような、循環する数値のカウントをしたい場合があります。
例えば曜日を表す変数は、0=月曜日、1=火曜日……と加算していき、6=日曜日の次はまた0=月曜日に戻ります。
例えば3種類の台詞を順番に話すキャラを作る場合、台詞番号の変数を1つ用意して、その番号によって台詞を分岐させます。
そして変数が2だったら0を代入し、それ以外なら1加算します。
◆条件分岐:台詞番号 = 0
◆文章:ここは最初の村よ。
:分岐終了
◆条件分岐:台詞番号 = 1
◆文章:サンプルのために作られた村なの。
:分岐終了
◆条件分岐:台詞番号 = 2
◆文章:だから何もない村なのよ。
:分岐終了
◆条件分岐:台詞番号 = 2
◆変数の操作:台詞番号 = 0
:それ以外のとき
◆変数の操作:台詞番号 += 1
:分岐終了
生真面目に実装するとこうなりますが、剰余を使うことで、よりシンプルに実装できます。
……(台詞の分岐部分は同様)
◆変数の操作:台詞番号 += 1
◆変数の操作:台詞番号 %= 3
何をしているかというと、変数に1を加算して、さらに3の剰余を求めています。
変数の元の値が2だった時、1加算されて3になり、3の剰余を求めることで0になります。元の値が0や1だった時は、3の剰余をとっても変わらず、そのまま1や2になります。
番号が0から始まる場合は、このように1加算して、剰余を求めます。1~3のように番号を1から始めたい場合は、剰余を求めてから1加算すればOKです。
いにしえのプログラミングでは、条件分岐(IF文)のコストが非常に重かったため、このようなテクニックがよく使われていました。
最近ではそのコストはほぼ無視できるので、素直に条件分岐で実装した方が断然分かりやすいため、剰余を使った方法は推奨されません。
ただ、ツクールの条件分岐は無駄に行数を使って長くなりがちなため、この方法を使えば短くすることができます。MZの最新バージョン1.6.0では条件分岐等の折り畳みができるようになったので、あまり気にならないかもしれませんが。
まとめ
以上、今回は「変数の操作」でできる「剰余」について、活用法などを解説してきました。
そもそも剰余が何なのか知らなかった方も、余りが求められて何が嬉しいんだという方も、剰余の使い方がお分かりいただけたのではないかと思います。
いずれも純粋に余りを求めるのではない、応用的な使い方だったので、知らないとなかなか思いつけない利用法だと思います。この記事を読んで、剰余の便利さを知っていただければ幸いです。
2回にわたってRPGツクールの「変数」について、「ゲームデータ」と「剰余」の活用法を解説してきました。もう一つぐらい変数について書けそうなので、第3回も近いうちに解説記事を上げると思います。そちらもどうぞお楽しみに。