51. 組み込みRandomを
オブジェクト化する例
public class MyRandom {
private Random.State state;
public MyRandom() : this((int)System.DateTime.Now.Ticks)
public MyRandom(int seed) {
setSeed(seed);
}
public void setSeed(int seed) {
var prev_state = Random.state;
Random.InitState(seed);
state = Random.state;
Random.state = prev_state;
}
public int Range(int min, int max) {
var prev_state = Random.state; // 使用前の状態
Random.state = state; // 前回の状態にセット
var result = Random.Range(min, max);
state = Random.state; // 現在の状態を記録
Random.state = prev_state; // 使用前の状態に
return result;
}
Random.state を
保存・復活する
52. Xorshift
C#実装例
public class MyRandom {
private uint x, y, z, w;
public MyRandom() : this((uint)DateTime.Now.Ticks) {}
public MyRandom(uint seed) {
setSeed(seed);
}
public void setSeed(uint seed) {
x = seed;
y = x*3266489917U+1;
z = y*3266489917U+1;
w = z*3266489917U+1;
}
public uint getNext() {
uint t = x ^ (x << 11);
x = y; y = z; z = w;
w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
return w;
}
}
参考
56. for (var y = 0; y < texture.height; ++y) {
for (var x = 0; x < texture.width; ++x) {
texture.SetPixel(x, y,
Random.Range(0, 2) == 0 ? white : black);
}
}
良さげな結果
すべての座標で白か黒を
乱数で決定
57. var i = 0;
for (var y = 0; y < texture.height; ++y) {
for (var x = 0; x < texture.width; ++x) {
Random.InitState(i);
++i;
texture.SetPixel(x, y,
Random.Range(0, 2) == 0 ? white : black);
}
}
失敗例
シードを毎回設定している
シードを設定
62. var i = 0;
for (var y = 0; y < texture.height; ++y) {
for (var x = 0; x < texture.width; ++x) {
Random.InitState(i);
++i;
texture.SetPixel(x, y,
Random.Range(0, 2) == 0 ? white : black);
}
}
失敗例のコード(再掲)
自然にこうなる
最初にボスの性別を決めるとする
63. 何がいけないのか
var i = 0;
for (var y = 0; y < texture.height; ++y) {
for (var x = 0; x < texture.width; ++x) {
Random.InitState(i);
++i;
texture.SetPixel(x, y,
Random.Range(0, 2) == 0 ? white : black);
}
}
←ここ。単純な増加がダメ
64. シードも乱数にしてみよう
var i = 0;
var rand = new System.Random(1234);
for (var y = 0; y < texture.height; ++y) {
for (var x = 0; x < texture.width; ++x) {
Random.InitState(rand.Next());
texture.SetPixel(x, y,
Random.Range(0, 2) == 0 ? white : black);
}
}
←乱数
さあ、結果は?
69. xxHash の実装例
※入力を32bitにした
int xxhash(int data, int seed) {
uint v = (uint)seed + 374761393U + 4U;
v += (uint)data * 3266489917U;
v = ((v << 17) | (v >> 15)) * 668265263U;
v ^= v >> 15;
v *= 2246822519U;
v ^= v >> 13;
v *= 3266489917U;
v ^= v >> 16;
return (int)v;
}
参考
71. var i = 0;
for (var y = 0; y < texture.height; ++y) {
for (var x = 0; x < texture.width; ++x) {
Random.InitState(xxhash(i));
texture.SetPixel(x, y,
Random.Range(0, 2) == 0 ? white : black);
}
}
xxHashでシードを作る
xxHashを呼ぶ
さあ、結果は?