開発日誌

テクニック

[ テクニック ] 変数を使いこなそう(2) 剰余の活用法

2022-12-08 00:00:43

本記事は「ツクールアドベントカレンダー 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回も近いうちに解説記事を上げると思います。そちらもどうぞお楽しみに。

コメント
お名前
コメント
※ 確認画面はありません。