ゲームにはランダムな要素がだいたい必要です。ランダムな要素が無い場合は、パターンプレーが可能になります。それはそれでちゃんと計算されてゲームデザインされれば楽しいのですが、例えばカードゲームとかで、毎回同じ手しか出てこないのは大問題となります。今回はこの乱数に実装について解説していきます。
- 乱数を初期化する
乱数はC言語に標準でサポートされています。乱数を使うには <stdlib.h> を #include します。必要な命令は、乱数の初期化と取得の二つです。
srand(乱数の種);
これが初期化です。乱数の種は unsigned int です。ここで初めて unsigned という型が出てきました。unsigned とは、符号無しを指定する型指定子です。int や char 等の整数型にのみ指定する事が出来ます。特に指定がなければ、これらの整数型は符号付きですが、signed と符号付きとして明記する事も出来ます。※ 私は signed を使った事はありませんが…
話を乱数の種に戻します。乱数の種が同じだと、以後、乱数の取得は同じ順番でランダムな値が取得できるようになります。つまり再現性のある乱数が作れます。例えば、迷路の自動生成などで、この乱数の種を保存しておければ、出来あがった迷路データを保存しておかなくても、種さえ保存しておけば以前の迷路が再現できたりします。ドルアーガの塔の迷路はこのような仕組みでデータ量を減らしています。
再現性がない乱数にしたい場合は、この乱数の種は起動毎に変化する値が好ましいです。そこでオススメするのが時間です。C言語では、時間も最初から使えるようにライブラリ化されています。時間を使うには <time.h> を #include します。時間の取得は
再現性がない乱数にしたい場合は、この乱数の種は起動毎に変化する値が好ましいです。そこでオススメするのが時間です。C言語では、時間も最初から使えるようにライブラリ化されています。時間を使うには <time.h> を #include します。時間の取得は
time_t t = time(NULL);
こんな記述となります。time が時間取得関数です。NULL を引数に与えていますが、戻り値で処理する場合は NULL を指定します。値の受け取りで time_t という不思議な型になっていますが、これは時間を受け取る別名定義された専用の型です。余談ですが、この型のサイズが32bitなシステムで2038年問題が起きます。最新のシステムでは64bitに拡張されています。
time() で取得できるのは現在時刻の連番ですが、これをそのまま乱数の種として扱ってしまいます。特に拘りがなければ乱数の初期化には
srand((unsigned)time(NULL));
このような記述で問題ないと考えます。この初期化は最初に一度呼び出しておくだけで良いため、main() の最初に記述しておくのが良いかと思います。なお、キャストの (unsigned) は unsigned int の省略形です。unsigned とすると自動的に符号無しの int として扱われます。この明示的なキャストがないと、VS2022 先生に警告を受けますのでご注意ください😁
【Amazon】
Logitec HDDケース 3.5インチ (HDD4台用) USB3.1(Gen1) / USB3.0 + eSATA接続 ガチャベイ LHR-4BNHEU3 ロジテックダイレクト限定
Logitec HDDケース 3.5インチ (HDD4台用) USB3.1(Gen1) / USB3.0 + eSATA接続 ガチャベイ LHR-4BNHEU3 ロジテックダイレクト限定
Logitec
- 乱数を使う
初期化が出来たら次は取得です。取得は rand() 関数を使います。
int num = rand();
たったこれだけで、num にランダムな値が入ります。ランダムな値の範囲はシステムによって異なりますが、VS2022 だと 32767 となっています。この最大値は RAND_MAX という定数がシステムによって定義されています。気になる場合は確認してください。
ランダムな値と言うだけあって、呼び出す毎に異なる値が返ります。例えば、
srand((unsigned int)time(NULL)); printf("%d\n", rand()); printf("%d\n", rand()); printf("%d\n", rand());
この単純なプログラムを動かすと実行するたびに…



このように表示される値が毎回変わります。範囲が大きいランダム値のままだと使いづらいので、自分が希望する範囲に乱数を変更したいですよね。そこで役に立つのが % 剰余算なのです。例えば、0 ~ 9 のランダムな値が欲しければ
int num = rand() % 10;
このように記述すれば、欲しい範囲のランダム値が手に入ります。-5 ~ +5 の範囲が欲しければ…
int num = (rand() % 11) - 5;
このように記述します。0 ~ 10 の値が剰余算で抜き出されてから、5 が引かれますので、目的の範囲を得る事が出来ます。% 剰余算の計算優先度に不安がある場合は、上記サンプルのように () を付けておくと良いでしょう。ちなみに今回の場合は計算優先度的には不要です。0 ~ 10 までの偶数が欲しければ…
int num = (rand() % 6) * 2;
これで OK です。
>> C言語 実力確認テスト03 ゲーム制作っぽい何かに進む
※ NASでRAIDもとなるとお値段的にはこちらがオススメ。どうしても単にPC直付けと比べると少しお高くなりますが、データの信頼性は高くなります。長い目で見ればこちらがオススメです。
コメント