トーク:ゲームプログラミング

出典: フリー教科書『ウィキブックス(Wikibooks)』
ナビゲーションに移動 検索に移動

乱数に rand() を使ってはいけない[編集]

rand関数で生成された乱数を、割り算(÷6)で割って、あまりは0以上5以下なので、余りに +1 するのが、rand関数による割り算プログラムの定石である。

最初読んだときは目を疑いました。

  1. rand()関数は擬似乱数を生成します。これは真の乱数(真性乱数)とは違います。四則演算やシフト演算を駆使して「乱数っぽい値」を返しているだけです。再現性や周期性があります。
  2. rand()関数の下位ビットは周期が短いことがあります。場合によっては「偶数の次は必ず奇数、奇数の次は必ず偶数」といった法則性が生まれてしまいます。
  3. rand()関数は線形合同法を利用しており質が低いので、MTやXorShiftなど別の実装を使うことが推奨されています。

ですから、普通rand()は使いませんし、使うとしても下位ビットは切り捨てて使います。常識です。細かい話は[1][2]を読むといいでしょう。

ところで、すじにくシチューさんが書かれているのは「ゲームプログラミング」ではなく「ゲームを題材にしたCプログラミング」ではないでしょうか? C言語の使い方はここで書くことではないと思いますが……。--Siglite3 (トーク) 2018年7月8日 (日) 03:36 (UTC)


(すじにくシチューのコメント)「乱数でrand関数を使うのが定石」とは言ってません。もしrand関数でサイコロを作る場合には、割り算を使うのが定石であると言おうとしているのです。「rand関数による割り算プログラムの定石である。」と書いてあります。
せいぜい、私(すじにくシチュー)の「言い回しが不適切」くらいでしょう。
アマチュア向けのゲームの場合、あまり完全な乱数は不要でしょう。科学実験用やセキュリティ用の乱数ならともかく。


もし、あなたが世間のゲーム作家にも分かりやすく手短かに、乱数のプログラムを説明してくれるなら、どうぞ、お書きになってください。ただし、RPGツクールなどでゲームを作ってるような多くのアマチュアゲーム作家は、線形合同法やハードウェア乱数生成やメルセンヌツイスタの概念なんて知らないと思います。
情報科学の知識があっても、まったくゲームを作れない人もいます(大学にも多くいますよね?)。いっぽう、情報科学の知識が少なくても、なんとかゲームを作る人もいます。
ゲーム制作で必要なのは、とりあえず、なんとかゲームを作れるようになる能力です。


  • 「すじにくシチューさんが書かれているのは「ゲームプログラミング」ではなく「ゲームを題材にしたCプログラミング」ではないでしょうか?」について
それの何が悪いのか、さっぱり分かりません。ゲームプログラム初心者の多くのは、そもそもCプログラミング自体に不慣れだと思いますので(世間には学歴が情報系の専攻でない人も多くいます)、当『ゲームプログラミング』で、ゲーム用のCプログラム例を記載することで、おさらいする事の、何が悪いのですか?
また、いくつかの例外はありますが、私は実際にプログラミングでゲームを作りながら、コードを書いています(少なくとも、RPGのコードは、そうしている)。
なお、市販の書籍でも、C言語のゲームプログラミングの入門書を読むと、C言語の使い方をおさらいしつつ、説明する本が多くあります。たとえば、大槻有一郎 (著)『12歳からはじめる ゼロからのC言語 ゲームプログラミング教室』[3] など、その例でしょう。
あと、関数や構造体などの概念を知っていても、それをどう組み合わせればいいかは、初心者には分かりません。実際に私自身、C言語の関数の概念は大学2年の19歳くらいの時点では知ってましたが、しかし、それを実際にゲームプログラミングにどう応用すればゲームを作れるのかを知ったのかは、30歳過ぎになった、ごく最近です
何箇所かコードをコンソールアプリとして書いたのは、コード量を短くするためです(GUIアプリだとコードが長くなりかねないので)。多くのゲームプログラマーが知りたいのは、実際にどういうコードを書けば動作をするのかが知りたいわけですので、実際に動くコードを書くのは当然です。コードのない抽象的な考え方は、不要です。Linuxの創始者のリーナスさんも、(代案のコードを書かずに)「技術について話すだけの奴はクソ野郎(Bullshit)だ」とか言ってます。 --すじにくシチュー (トーク) 2018年8月24日 (金) 01:29 (UTC)
横から失礼しますが、「「乱数でrand関数を使うのが定石」とは言ってません。もしrand関数でサイコロを作る場合には、割り算を使うのが定石であると言おうとしているのです。」というのは全く反論になっていません。Siglite3さんは「もしrand関数でサイコロを作る場合」であってもその使い方は不適切である(下位ビットは切り捨てて使うべき)とおっしゃっているのです。「ゲームの場合、あまり完全な乱数は不要」というのはあまりにもゲームを馬鹿にした発言で、そのようなことをおっしゃる方がこのような記事を執筆されるのは不適切なのではないでしょうか。たとえばサイコロを2個同時に振る動作を含むテーブルゲームはありふれていますが、そのようなゲームを「偶数の次は必ず奇数、奇数の次は必ず偶数」となるサイコロを順に2回振ることで実装した場合、目の合計は必ず奇数で、特にぞろ目は絶対に出ない、ということになります。そんなサイコロでバックギャモンやモノポリーを再現しようとすれば、それは現実のゲームとはゲームバランスの全く異なる、違うゲームになってしまいます。--2402:6B00:464A:8200:DE8:5811:B9ED:BBF9 2018年8月24日 (金) 09:02 (UTC)
すじにくシチューさん。私は「知らなかったこと」や「間違えたこと」は問題にしていません。執筆者は全知全能ではありませんから知らないこともあれば間違えることもあります。私もよく間違えます。しかし、執筆する前に下調べを怠ること(知らないことを知ろうとしないこと)は大問題だと思っています。
正直なところ、乱数の項はきちんと下調べをして書いたとは思えません。なので議論ページで問題提起しています。私は調査不足を批判しているのであって、結果的に間違えてしまったことを批判しているのではありません。トーク:オブジェクト指向でも同じことを指摘しましたが、調べてから書いてください
上記の点だけ理解していただければ十分です。乱数の項については私が書き直しましょう。
また、「ゲーム用のCプログラム例を記載することで、おさらいする事の、何が悪いのですか?」についてですが、C言語について多少解説するのは構いません。しかし、同じプログラムを様々な方法(グローバル変数、ポインタ、構造体、etc...)で実現することに意味はあるんでしょうか? 読者はゲームプログラミングのテクニックやベストプラクティスを知りたいのであって、実装方法がN通りあることを知りたいわけではありません。私は最良の手法を一つ紹介すれば十分だと思います。それ以上は「C言語の使い方」講座ですし、内容が冗長になってしまうデメリットがあります。--Siglite3 (トーク) 2018年8月25日 (土) 02:46 (UTC)