読者です 読者をやめる 読者になる 読者になる

WonderPlanet DEVELOPER BLOG

ワンダープラネットの開発者ブログです。モバイルゲーム開発情報を発信。

擬似乱数生成アルゴリズム「Xorshift」をC#で実装

C-Sharp アルゴリズム

今回のエンジニアブログを担当する加賀です。

高速な擬似乱数生成アルゴリズムのXorshiftを紹介したいと思います。
今回のコードはVisual Studio 2010 Pro SP1、C# 3.5で確認しています。

Xorshiftとは

Xorshiftとは、その名の通り、XOR(排他的論理和)とシフト演算のみを使用する乱数生成アルゴリズムです。
複雑な計算をしていないので、かなり高速に乱数を生成することが出来ます。
また、生成し続けて再び同じ数が出てくるまでの周期は2128-1と、精度も実用には悪くありません。

C# 実装例

public class Xorshift {  
  // 内部メモリ  
  private UInt32 x;  
  private UInt32 y;  
  private UInt32 z;  
  private UInt32 w;  
  
  public Xorshift () : this ((UInt64)DateTime.Now.Ticks) {  
  }  
  
  public Xorshift (UInt64 seed) {  
    SetSeed (seed);  
  }  
  
  /// <summary>  
  /// シード値を設定  
  /// </summary>  
  /// <param name="seed">シード値</param>  
  public void SetSeed (UInt64 seed) {  
    // x,y,z,wがすべて0にならないようにする  
    x = 521288629u;  
    y = (UInt32)(seed >> 32) & 0xFFFFFFFF;  
    z = (UInt32)(seed & 0xFFFFFFFF);  
    w = x ^ z;  
  }  
  
  /// <summary>  
  /// 乱数を取得  
  /// </summary>  
  /// <returns>乱数</returns>  
  public UInt32 Next () {  
    UInt32 t = x ^ (x << 11);  
    x = y;  
    y = z;  
    z = w;  
    w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));  
    return w;  
  }  
}  

Nextメソッドを見て分かるように、乱数生成部分は非常にシンプルです。
シード値の設定部分は、結構適当です。
4つの内部メモリがすべて0にならないようにしておけばいいようです。

あとはここに範囲内の乱数取得や、浮動小数で乱数取得などを追加すれば十分使えるものが出来ます。
Xorshiftの実装例については、検索するといろいろと見つかります。

最後に

速度が必要で、厳密な精度を必要としないなら、Xorshiftが十分使えると思います。
また、乱数発生器を簡単に別インスタンスにできるので、ローグライクのような自動生成のゲームで
同じマップをもう一度生成したい場合なども簡単にできます。
これからも、このような便利なものを見つけて、使っていきたいです。