rnd

Last-modified: 2015-09-14 (月) 19:17:21

分類

数学関連命令

使用可能節

  • 定義節?
  • 実行節?

機能

乱数を発生させる。

書式

rnd (数値変数?1),(数値1)

解説

  • 0以上、(数値1)未満の乱数を発生させて、それを(数値変数1)に格納する。
  • (数値1)に32,768以上を指定しても、発生する乱数は32,767以下になる。
  • (数値1)に1を指定すると、仕様通りに0しか発生しなくなる。
  • (数値1)に0を指定すると、nscr.exeが動作を停止しました?と出してから落ちる。
  • (数値1)に0未満の数値を指定すると、絶対値に変換してそれを新たな(数値1)として使用する。

運用

  • たとえば、サイコロを意図して(数値1)に6を指定すると、0~5までの乱数が発生するので、そのままでは使えない。1を足すか、dice命令などを自作する必要がある。ただし、配列?などが0オリジンなので、そのままの方が使いやすい場合は多くあるはず。
  • 発生できる乱数が32,767以下なので、それよりも大きな幅の変数が必要な場合に困ったことになる。乱数を二つ発生させ、一つを何倍かして上位桁として扱う遣り方は、偏りがひどくなるので非推奨。代替手段を当たった方がいい。
  • アルゴリズムが線形合同法なので、暗号用途には使ってはならない。そういう状況はまずないと思われるが。
  • 起動時に一回とか、一回のプレイで一回だけ乱数が必要な場合は、time?命令の(数値変数3)や、NSLuaのNSTimer?関数を使うかするといい。

詳細

  • 内部的にANSIC++のrand関数とrandomseed関数が使われている。
  • randomseed関数は最初の使用時に自動で呼ばれるようだ。セオリー通りなら、乱数の種としてepoch秒かWindowsの起動時からの経過時間(ミリ秒)が使われているはず。なので、再現性は期待できない。
  • 乱数生成アルゴリズムは線形合同法になる。周期は2^32になる。
  • 内部的にには、0から65,535までの乱数を作成し、それを(数値1)で割った余りを、さらに2分の1した数値を実際の乱数として返していると推測される。なので発生させられる乱数に限界が生じているし、(数値1)に0を指定した時にゼロ除算エラーを起こす。2分の1するのは、線形合同法の奇数偶数交代現象の解消のためと思われる。

関連

rnd2

代替

  1. NScript?でrndを再実装する。(実行時の環境依存度がほぼゼロ、難易度は最高)
  2. dll?で別の乱数発生ルーチンを実装する。(実行時の環境依存度はDLLの扱いによる。別言語の知識が必要だし、DLL作成の知識が必要。難易度は高)
  3. NSLua?でmath.randomを使用する。(実行時の環境依存度はNSLuaが使えるかの一点に尽きる。既に有り物を使うので難易度は低。また、再現性も任意で付与できる)
    最も実装コストが少なくて済むのは3。