カオス写像乱数
カオス写像乱数生成とは、ロジスティック写像などの「カオス理論」の数式を乱数生成器として使います。
カオス写像は一見ランダムに見えますが「一度ある特定の数値が出ると数回先までその周辺の数値が出やすくなる」という強い局所的相関(偏り)を持たせることができます。この特性を利用するとパチンコなどにおいて状態変数を持つことなく「連チャンゾーン」を実装することができます。
実装例: Z80 編集
この乱数は、一度「32〜64」あたりの値に入ると、数回転の間、連続してその周辺の値を出力し続ける特性(カオスの局所性)を持ちます。大当たり値を「40」などに設定しておけば、状態変数なしで数珠連チャンが発生します。
;---------------------------------------------------
; カオス乱数生成 (ロジスティック写像 8bit)
; 入力: なし (前回の値をRAMの [RAND_SEED] から読み込む)
; 出力: Aレジスタ = 生成された乱数 (0〜255)
;---------------------------------------------------
NEXT_CHAOS:
LD A, (RAND_SEED) ; A = X_n
LD B, A ; B = X_n
CPL ; A = ~X_n (255 - X_n と等価)
LD C, A ; C = (255 - X_n)
; ここから 8bit × 8bit の簡易乗算 (B * C)
; 結果の上位8bitをAレジスタに残すことで、自動的に「>> 8」の処理になる
; 最後に「<< 2」をすることで「>> 6」を再現する
LD HL, 0 ; HLをクリア
LD D, 0 ; Dをクリア
LD E, C ; DE = C
LD M, 8 ; ループカウンタ (8回)
MULT_LOOP:
SRL B ; Bの最下位ビットをキャリーへ
JR NC, NO_ADD
ADD HL, DE ; キャリーがあれば HL に DE を足す
NO_ADD:
SLA E ; DEを左シフト (16bit)
RL D
DJNZ MULT_LOOP ; 8回繰り返す
; この時点で Hレジスタ = (B * C) >> 8
; これを4倍 (左に2回シフト) して「4 * X * (1-X)」を完成させる
LD A, H
SLA A ; 2倍
SLA A ; 4倍
LD (RAND_SEED), A ; 次回のために保存
RET ; Aレジスタに乱数が入った状態で戻る
実装例: C# 編集
using System;
public class ChaosRandom
{
private byte _seed;
// 初期シード(0や255、128は固定化しやすいので避ける。1〜254の間)
public ChaosRandom(byte initialSeed = 105)
{
_seed = initialSeed;
}
/// <summary>
/// カオス写像による乱数生成 (0〜255)
/// </summary>
public byte Next()
{
unchecked
{
// 数式: X_next = (X * (255 - X)) >> 6
// Z80のコードと完全に同じビット演算ロジック
int inverse = 255 - _seed;
int mult = _seed * inverse;
_seed = (byte)((mult >> 6) & 0xFF);
return _seed;
}
}
}
さらに連チャン性を調整したい場合 編集
- 写像の強度を変える
>> 6 を >> 5 にすると局所性が強くなる
- 写像を2段構えにする
X = f(f(X)) とすると連チャンが伸びる