2018年 10月31日
また更新が 1ヶ月も伸びてしまいました。
いやあ夏いらい調子が戻らないのもそうなんだけど、今の所ずっとバグ取りしてる。
プログラムやった事のある人なら分かると思うけど、プログラムとはバグ取りだ、と言えるくらい次から次から不具合が出て頭を悩ましてくれる。
もうちょっとで一応通しでゲームできるようになるので、とりあえずそこまでしないと報告する事が無かったという事だ。
合わせてバランスの調整もちょっとしないとゲームにならない。
さて、今回はバグ取りの途中で HSPの乱数についてとんでもない事を今更見つけたので、それについて報告する。
どうもユニットとアイテムの発見率がおかしいので調べていたらとんでもない事を発見した。
なんと HSPの rnd関数で作れるのは 32768までだったのだ。
えーそうなの?!みなさんは知ってました?自分は 10年も HSPいじっていて今まで気づかなかった。
どうしよう、もっと大きい乱数を使いたいのに、というか今までそういう乱数使った事無かったっけか?気づかなかいで最大32768で使っていた?
てな感じでちょっと冷汗ものです。
そこで大きい乱数の発生をどうしたらいいのかと、少し考えたんだけど、1.0を 100%とする少数を出したい乱数に掛ける事で擬似的に出来るようだ。
randomize pos 10,10 : mes "乱数" pos 100,10 : mes "を小数に" pos 200,10 : mes "最終的な乱数" r=1000000 ; 出したい乱数 repeat 20 r2=rnd(10000) ; % pos 10,cnt*20+40 : mes r2 f=double(r2)/10000.0 ; %を少数にする pos 100,cnt*20+40 : mes f n=int((double(r)*f) ; 出したい乱数に%を掛ける pos 200,cnt*20+40 : mes n loop
r = 出したい乱数
r2= 確率、%で 100でも良いけど折角だから 10000にする。
f = r2を 1.0を 100%とする実数(少数)にする、r2を 10000で割る。
例えば r2が 3245だったとしたら 0.3245になる。
n = 100%である rと確率の fを掛ける。
例えば出したい乱数 r=100だった場合、100 × 0.3245 = 32(切捨て)となり、乱数としては 32が最終値になる。
この方法だと、例えば出したい乱数が 32458478だったとして、32458478通りの乱数という訳では無くて、あくまでも確率は 1/10000であり、確率が 1なら 3245で 2なら 6490という飛び々の数字になる。
今回は勉強しなかったが、やり方は色々あるらしいがめんどくさいし(自分には難しそうなので)これなら割と簡単に擬似的な値が出るかな?
ちなみに小数点切捨てでは無くて、四捨五入したい場合は round命令を使うが、命令を#includeしないといけない。
#include "hspmath.as" ; 計算(round用) randomize pos 10,10 : mes "乱数" pos 100,10 : mes "を小数に" pos 200,10 : mes "最終的な乱数" r=1000000 ; 出したい乱数 repeat 20 r2=rnd(10000) ; % pos 10,cnt*20+40 : mes r2 f=double(r2)/10000.0 ; %を少数にする pos 100,cnt*20+40 : mes f n=int(round(double(r)*f)) ; 出したい乱数に%を掛ける pos 200,cnt*20+40 : mes n loop
この方法だと細かい数字は出ないけど、最大の精度を求めるなら 32768で乱数を求めて 32768で割って出したい乱数値に掛ければいいのかな?
ちなみにちゃんと(完全では無いけど)出すなら実数で乱数を出すという方法があった(次の記事 HSPで大きな乱数を発生させる その2 実数乱数で確率を出すへ)
後は大きい乱数用の外部命令を #includeするのが手っ取り早いんだろうね、HSP Dishだと今の所外部 DLLは使えないみたいだけどね。