クロサワ式乱数
レトロハードに最適な、機種依存の無い高速な乱数発生ルーチンです。 何処の誰が作ったか知りませんが、 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回発生させるケースが無い事から、 さほど問題にならない様です。