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


  • 追加された行はこの色です。
  • 削除された行はこの色です。
*乱数 [#lbd455fe]

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

rand関数を使うには、''stdlib.h''という標準のライブラリーをインクルードする必要があります。
#geshi(c){{
#include <stdio.h>
#include <stdlib.h>

int main(void) {
  int r;

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



*srand関数で乱数のシードを初期化する [#rdffca73]
上のプログラムを実行すると、毎回、同じ結果になります。

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

そこで、''srand関数''を使ってスタート地点(これを''乱数のシード''といいます)を変更します。
そこで、''srand関数''を使って擬似乱数を生成するスタート地点(これを''乱数のシード''といいます)を変更します。
#geshi(c){{
#include <stdio.h>
#include <stdlib.h>

int main(void) {
  int r;
  
  srand(1);
  r = rand();
  printf("%d\n", r);
}
}}

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


*time関数で時刻を取得して乱数のシードにする [#n824096f]

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

現在の時刻を取得するには、''time''関数を使います。
time関数を使うには、''time.h''という標準のライブラリーをインクルードする必要があります。
#geshi(c){{
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void) {
  int r, t;
  int r;
  
  t = time();
  srand(t);
  srand((unsigned int) time(NULL));
  r = rand();
  printf("%d\n", r);
}
}}

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

*サイコロを作る [#n9c27942]


*サイコロを作る [#r207a8e2]
まず、rand関数が生成した値を6で割ったときの余りを求め、生成した乱数から0から5までの整数を作ります。
これに1を加えて、1から6までの整数を作ります。
#geshi(c){{
#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);
}
}}

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



*計算ゲーム [#rb9308ee]







*おまけ:もうすこしマシなサイコロを作る [#n9c27942]
rand関数が生成する最も小さな数は0、最も大きな数はstdlib.hの中で''RAND_MAX''として定義されています。

1から6までの整数を一様なランダムに生成するには、次のようにします。
+生成した乱数を RAND_MAX + 1 で割って0以上1未満の実数(0から0.999999999...)を作る
これを使って1から6までの乱数を生成するには、次のようにします。
+生成した乱数を RAND_MAX + 1.0 で割って0以上1未満の実数(0から0.999999999...)を作る
+これを6倍して0以上6未満の実数(0から5.999999999...)にする
+その整数部分(0から5)を取り出す
+最後に、1を加える(1から6)

#geshi(c){{
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void) {
  int r, t;
  int r;
  
  t = time();
  srand(t);
  r = (int) (rand() / (RAND_MAX + 1) * 6) + 1;
  srand((unsigned int) time(NULL));
  r = (int) (rand() / (RAND_MAX + 1.0) * 6) + 1;
  printf("%d\n", r);
}
}}

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

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