はるかのひとりごと > サイエンス > オンラインゲームの確率について
確率というのは、算数の中でも、
結構わかりやすく、実用的な物だと思います。
今回は難しい話はパスで、簡単な説明をしてみようと思います。

ピグのゲームでは、よく確率1%と表記されたガチャがあります。
これは内部で、どんな動作をしているのでしょうか?

まず、抽選には2種類あると思って下さい。
それは、
1.疑似乱数による抽選
2.乱数による抽選
です。
難しい話しないっていったのに・・・

まず、言葉の説明からです。
乱数というのは、サイコロで言えば1~6の数字をユニークに発生させる事を言います。
random
こんな感じです。
この例では、1~6の乱数を1度取り出しています。

乱数を生成するには2種類あると上述しました。
サイコロを振る行為は、1,2で言えば
「2の乱数による抽選」
になります。サイコロは完全な正6面体であれば
出目の確率は確率は1/6の数字となるはずです。
機械的に乱数を生成しているのですね。
また、サイコロを振る前には何が出るか分かりません。
この方式は、パチンコの大当たりする抽選とか、スロットマシンの抽選で使われています。
実際はサイコロを振るのとよく似た装置で発生させています。
装置と言っても、高速で回転しているルーレットに矢を当てる(宝くじの抽選)ような
仕組みを使っています。

では、今回の本題である1の疑似乱数です。
疑似乱数は2と根本的に違い「計算により算出できる乱数」です。
ですので、抽選をする前から結果が分かっているものです。←(ここ重要・・・テストに出ます)
計算して乱数を取り出しますので、
当たり前ですが、計算する前には結果が分かっているはずです。
1+1はいくつでしょう?と言われて
その答えが分かるのと全く同じ理由です。

疑似乱数を生成するためには、様々な手法があります。
では、どんな方式なのか?
私たちの身近にあるもので説明しましょうか。
そうですね、パイとかいいですね。
3.1415926535897・・・・・・
この小数点以下の出現率は、現在の計算技術で算出できる範囲で
ほぼ乱数だという事が分かっています。

パイの文字列は0~9の10通りの乱数だと言えるのです。

1%の確率を生成するのも容易にできます。
単に値を2回取ってくれば良い訳ですね。
それで00~99までの100通りの乱数が生成可能です。
逆に0~4なら0、5~9なら1とすることにより、
0か1の1/2の乱数を生成する事も出来ます。

さて、この仕組み、オカシイと思いませんか?
小数点以下を利用することとすれば、
1度目は必ず「1」になり二度目は「4」三度目は「1」四度目は「5」という
決まった値になってしまいます。

具体的には、AさんとBさんの二人がこの乱数を取り出すと
A:141592
B:141592
となり、全く乱数として利用できません。

これを打破するために、乱数テーブルをリセットするという方式があります。
一般的にランダマイズとか言われます。

具体的な方法ですが、Aさんはパイの101桁目からスタート
Bさんは、パイの201桁目からスタートとすることにより、
A:8214808651
B:4428810975
という数値を得られますね。
これにより、個人にパーソナライズされた乱数のように見えてきます。

この乱数を初期化するデータ(例では101とか201という数字を使いました)の事を
乱数の種(SEED)と呼びます。
SEEDは非常に重要だという事がおわかり頂けたかと思います。
SEEDを、時間(日付+時間+分+秒)とID等で生成することにより
より複雑なSEEDを得ることができます。

今回は、
・抽選は疑似乱数で行われている
・疑似乱数は生成する前から結果が分かっている
・SEEDは非常に重要である

という事がおわかり頂けたかと思います。

ここで、話を変えてオンラインゲームの特徴です。
オンラインゲームでは、重要な情報ほど
クライアント(使用者のPC)で処理を行いません。
ピグゲームのように、ガチャの実施や抽選自体は、
全てサーバーで行っていると言ってもいいでしょう。

もし、クライアントにこのような判断がある場合
Flashプログラムを改造する事により
必ず切手が出るようにすることが簡単に出来てしまいます。
ですので、サーバー側にあると断言しています。

疑似乱数を生成したりSEEDを与えていたりするのは
全てサーバー側のプログラムがやっているという事ですね。
ここで、サーバー側のプログラムミング技術が未熟な人が
設計した例を出してみます。

たとえば、収穫毎やログイン毎にSEEDを変えていたら
どうなるでしょうか?
前の話に戻りますが、パイの101桁目は8という数字になります。
収穫時ランダマイズしたら101を得ました。
もう一度ランダマイズしたら101を得ました
さらにランダマイズしたら101を得ました。
もし、このような事をしてしまうと毎回「8」になり
これはとてもじゃなく「乱数」とは呼べません。
偏っているとかではなく、検定に合格しない乱数という事になります。

そうです。SEEDは、何度も弄る物ではなく
その人固有のデータなのです。
逆にSEEDを弄りすぎると、サンプルが多くても
想定通りの確率になりません。

このようにプログラムミスひとつで、
とんでも無い事が発生するのです。

今回は、わかりやすく(自分ではw)
説明しましたが、ピグのサーバーにどのような仕組みが
実装されているのか、全く分かっていません。
しかしながら、正規分布を逸脱するような確率は
やはり何かしらのミスがあると思っています。

全く役に立たない話ですが、
暇つぶしにはなったと思います(^^ゞ

ではでは。またね~♪

コメント一覧

  1. どっかの電波ちゃん
    概ね同意です。
    piggの中身は謎ですが、だいたい想像はつきます。
    ミスというか、手抜きな感じ。
    この問題には要因がいくつかあって、

    (1)企画屋が単に”乱数”とオーダーを出したら
    現場は単純にrand()呼ぶだけの実装になりがち。
    んで、企画屋はseedがどうとか専門的な知識なくて
    現場は企画外の蛇足な実装をしたがらない。
    ここで既にハマっているというオチ。

    (2)オンラインゲームでは頻繁なデータベースの
    読み書きが好まれないので、抽選の度にseedを保存
    なんて設計は却下されがち。
    なのでおそらくseedは全体共通か、抽選処理が
    走る度に時刻とかから拾ってきてる。

    まー、抽選の度になんか保存できるなら
    seedよりも結果をスコアリングして運の悪い
    人向けに救済措置を施すとかする方が確実でし。

    (3)抽選結果をちゃんとテストしてない
    (1)(2)がダメでもここさえちゃんとしてれば調整の
    しようはあるんですが、そこまで気がまわってなさげ。
    というか、なんかリリースする度にエンバグやらかして
    いるようなワークフローでは基礎的なデバッグもできて
    なくて、調整面は完全放棄な気がしないでも。
  2. はるか
    >どっかの電波ちゃん
    コメントありがとうございますでし(^^ゞ


    >(2)抽選処理が走る度に時刻とかから拾ってきてる。

    これ、私は一番疑っているところです^^
    目の付け所が同じで、安心しました。
    電波ちゃんと同じ読みなら、おそらく核心を突いているような
    気がします。

    >(3)
    これは、致命的ですよね。
    おそらくCA云々より、法規が追いついていない
    感じですよね。景品表示法で、確率表示をすればいいか?
    ・・・と言うレベルではなく、
    その確率はどっからどうやって算出したの?
    という「検定」の仕掛けが無いのが問題だと思います。

    前回のコルクの確率表示は
    「あきらかな間違い」
    でしたので、3については根拠があると言っても良いでしょうね。


    余談ですが、キッチンをクリックして
    切手を作ると連続ミスが無い
    という噂を聞いた事があります。
    私は、オカルトだとは思って居ますが、
    単なるオカルトでは済まなく、
    キッチンクリックでランダマイズしているかも
    しれないのですw
    ランダマイズ時のSEEDが不完全なもの
    たとえばIDと秒のxorとかにしてしまうと、
    必ず偶数秒では「成功する」などの操作が
    可能になります。
    しかも、別の人やサブでやっても再現しなかったりw
    という現象も発生します。
    こんな色々な事を想像するだけでも、
    算数の世界は楽しいです。
  3. 中っぽい人
    ふつう、こう作るよ。

    1. 乱数は擬似乱数。
    開発言語のライブラリについているやつか、MTという有名なアルゴリズムのやつ。

    2. seedを設定するのはサーバプログラム起動時。
    何度もseedを設定することはない。一度だけ。
    サーバが何台もあれば、サーバごとに(正確にはプロセスごとか)違うseedになる。
    最近のプログラミング言語だとseedの設定すらプログラマがやる必要ない場合もある。
    seedに使う値は暗号論擬似乱数という、ほぼ予測不能な乱数を使う。詳しくは /dev/random とかでググるといい。

    3. サーバは同時に何十何百というユーザーを相手にしているので、ユーザー側から次に出る乱数を予測は事実上不可能。
    同じユーザーが次に乱数を取得するまでの間に何回乱数を生成したかはわからないから。
    • はるか
      >中っぽい人さん
      コメントありがとうございます。

      >3.ユーザー側から次に出る乱数を予測は事実上不可能
      この通りだと思います。

コメントする

Gravatarに登録してログインすると自分専用のアバターを表示できます。

コメントを残す





鈴木はるかのプロフィール画像
(Haruka Suzuki)
仕事:金融システムのSE
好きな物:スイーツ、絶景
趣味:お菓子/アニメ/多趣味

月別の記事を見る