Future Driver

クロサワ式乱数

レトロハードに最適な、機種依存の無い高速な乱数発生ルーチンです。 何処の誰が作ったか知りませんが、 2012年4月現在はgoogleで検索しても自分のtwitterのぼやきくらいしか出てこないから、 ここに載せて置きます。

;int *rnd()
;
;0〜65535までの乱数を返す。
;
	.text
	.globl	_rnd
_rnd:
        move.w  _rndLatest, d0
        eori.w  #$9630, d0
        subi.w  #$6553, d0
        rol.w   #2, d0
        move.w  d0, _rndLatest
	rts

乱数のパターンは65536回で1周します。 つまり65536回を超えた時点で同じパターンが出現し始めるので、 目的によっては使い物になりません。

/* 256個の乱数を発生させるサンプル コード */
extern int rndLatest;
extern int rnd();
main(){
	int c;
	int r;
	rndLatest = 6502; /* 初期値 */
	for(c = 0; c < 256; c++){
		r = rnd();
	}
}

68000もZ80も除算とビットシフトは苦手なので、 例えば 0〜15 の範囲の乱数を求める場合はANDすると良いでしょう。 ちなみに最近のゲーム機はビットシフトより除算のほうが速い様です。

	r = rnd() & 0x000F;

この乱数発生ルーチンは見ての通りコード量が少なく高速で、 その割りに発生させた乱数の偏りが少ないと言う特徴があります。 65536回で1周してしまう点については、 実際にゲームソフトで使ってみると、 ゲーム中はプレイヤーの行動によって1フレーム中の乱数を発生させる回数やタイミングが変わってくる事、 初期化時は65536Bytes程度のVRAM/メインメモリーしか無いハード上で連続して65536回発生させるケースが無い事から、 さほど問題にならない様です。

inserted by FC2 system