授業/C言語基礎/計算ゲーム のバックアップ(No.2)


乱数

rand関数で擬似乱数を生成する

C言語で擬似乱数を生成するための関数として、rand関数があります。

rand関数を使うには、stdlib.hという標準のライブラリーをインクルードする必要があります。

#include <stdio.h>

int main(void) {
  int i = 45, j = 76, a;

  printf("%d + %d = ", i, j);
  scanf("%d", &a);

  if (a == i + j) {
    printf("正解!\n");
  } else {
    printf("間違い!\n");
  }

  return 0;
}  

srand関数で乱数のシードを初期化する

上のプログラムを実行すると、毎回、同じ結果になります。

rand()関数は、毎回同じやり方で擬似乱数を生成するので、スタート地点が同じだと毎回同じ擬似乱数が生成されるのです。

そこで、srand関数を使って擬似乱数を生成するスタート地点(これを乱数のシードといいます)を変更します。

#include <stdio.h>
#include <stdlib.h>

int main(void) {
  int r;

  r = rand();
  printf("%d\n", r);

  return 0;
}

srand関数の()の中の数は、擬似乱数を生成するスタート地点を表していて、これを変えると生成される乱数が変わります。

time関数で時刻を取得して乱数のシードにする

乱数のシードを変更するたびにコンパイルし直すのは面倒なので、現在の時刻を取得して乱数のシードにします。

現在の時刻を取得するには、time関数を使います。 time関数を使うには、time.hという標準のライブラリーをインクルードする必要があります。

#include <stdio.h>
#include <stdlib.h>

int main(void) {
  int r;

  srand(2);
  r = rand();
  printf("%d\n", r);

  return 0;
}

time関数の結果をunsigned int型にキャストしてsrand関数に渡しています。 ちょっとややこしいですが、今はこういうものだと思って進めてください。

サイコロを作る

まず、rand関数が生成した値を6で割ったときの余りを求め、生成した乱数から0から5までの整数を作ります。 これに1を加えて、1から6までの整数を作ります。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void) {
  int r;

  srand((unsigned int) time(NULL));
  r = rand();
  printf("%d\n", r);

  return 0;
}

なお、この作り方で作った乱数は、ゲームで使うくらいならあまり問題はありませんが、科学的なシミュレーションなど精密な計算が必要なときには問題があることがわかっていて、そのような場合には他の方法で乱数を作ります。

計算ゲーム

おまけ:もうすこしマシなサイコロを作る

rand関数が生成する最も小さな数は0、最も大きな数はstdlib.hの中でRAND_MAXとして定義されています。

これを使って1から6までの乱数を生成するには、次のようにします。

  1. 生成した乱数を RAND_MAX + 1.0 で割って0以上1未満の実数(0から0.999999999...)を作る
  2. これを6倍して0以上6未満の実数(0から5.999999999...)にする
  3. その整数部分(0から5)を取り出す
  4. 最後に、1を加える(1から6)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void) {
  int r;

  srand((unsigned int) time(NULL));
  r = rand() % 6 + 1;
  printf("%d\n", r);

  return 0;
}

ちなみに、この作り方でもまだ問題があることがわかっています。 実は、問題はrand関数そのものにあるので、きちんとした乱数が必要なときにはrand関数を使ってはいけません。

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS