|
|
2008/3/27(Thu) 09:07:11|NO.14615
screen 0,ginfo_dispx,ginfo_dispy
randomize
x=ginfo_dispx/2
y=ginfo_dispy/2
repeat
;c=rnd(256)
;color c,c,c
pset x,y
r=rnd(4)
if r=0 : x++
if r=1 : x-- ;
if r=2 : y++ ;
if r=3 : y--
wait 1
loop
乱数に関していろいろとプログラムを組んでいたのですが
自分には理解できないことが起こってしまいました。
乱数で進行方向を決めて進んで(描いて)いくプログラムなのですが
しばらく動かし続けていると線対称な図形が描かれます。
そしてその後同じ道を進みます。(6・7行目のコメントを外すと動きが分かります。)
これは乱数に一定のパターンがあるということでしょうか。
それともただ単に私の使い方が悪いのでしょうか。
できるだけ考えてはみたのですが結論には至りませんでした。
どなたかご教授ください。
|
|
2008/3/27(Thu) 10:12:40|NO.14617
if r!5:pset x,y
r=rnd(5)
に変えたらいかが?
|
|
2008/3/27(Thu) 10:17:04|NO.14618
hxさんので遊んでいたら面白いのできた
buffer 3,ginfo_dispx,ginfo_dispy
color
boxf
screen 0,ginfo_dispx,ginfo_dispy
width ,,0,0
a=256
l=64
rh=64
dim x,a
dim y,a
dim xs,a
dim ys,a
dim r,a
randomize
repeat a
x(cnt)=ginfo_dispx/2+rnd(l*2+1)-l
y(cnt)=ginfo_dispy/2+rnd(l*2+1)-l
xs(cnt)=x(cnt)
ys(cnt)=y(cnt)
r(cnt)=rnd(2)
c(cnt)=rnd(128)+128
loop
gmode 3,ginfo_dispx,ginfo_dispy,8
boxf
repeat
color ,c(n),
line xs(n),ys(n),x(n),y(n)
xs(n)=x(n):ys(n)=y(n)
if r(n)=0 : x(n)=xs(n)+rnd(rh+1)-rh/2:r(n)=1:else: y(n)=ys(n)+rnd(rh+1)-rh/2:r(n)=0
x(n)=limit(x(n),0,ginfo_winx):y(n)=limit(y(n),0,ginfo_winy)
n+
if n=a:n=0{
pos 0,0
gcopy 3,0,0,ginfo_dispx,ginfo_dispy
redraw 1:wait 0:redraw 0
}
loop
|
|
2008/3/27(Thu) 17:22:42|NO.14625
こ、こりゃおもしろい(笑
|
|
2008/3/27(Thu) 17:38:35|NO.14626
if r!4:pset x,y
だった
|
|
2008/3/27(Thu) 18:04:46|NO.14628
おもしろすぎ笑
スクリーンセーバーにしてみたが、CPU消費がこのままだと100%なので
でも、確かにパターンになってますね。
|
|
2008/3/27(Thu) 18:55:03|NO.14631
実際同じパターンに入り込んでしまっているのは事実ですね。
まぁ適当に手を加えればそこから脱出できるみたいですけどね。
もう関係ないけど↓
#define mmousex (ginfo(0)-(ginfo(4)+(ginfo(10)-ginfo(12))/2))
#define mmousey (ginfo(1)-(ginfo(5)+(ginfo(11)-ginfo(13))-(ginfo(10)-ginfo(12))/2))
buffer 4,ginfo_dispx,ginfo_dispy
buffer 5,ginfo_dispx,ginfo_dispy
buffer 3,ginfo_dispx,ginfo_dispy
color
boxf
bgscr 0,ginfo_dispx,ginfo_dispy
width ,,0,0
amax=500;最大個数ニョロニョロ
w=0
a=1
l=1
h=2
bb=32
dim x,a
dim y,a
dim xs,a
dim ys,a
dim r,a
dim rh,a
randomize
repeat a
x(cnt)=mmousex+rnd(l*2+1)-l
y(cnt)=mmousey+rnd(l*2+1)-l
xs(cnt)=x(cnt)
ys(cnt)=y(cnt)
r(cnt)=rnd(2)
rh(cnt)=rnd(96)+32
c(cnt)=rnd(256-64)+64
loop
gmode 3,ginfo_dispx,ginfo_dispy,16
boxf
font "",64
repeat
color ,c(n),
boxf xs(n),ys(n),x(n),y(n)
xs(n)=x(n):ys(n)=y(n)
if r(n)=0 {
x(n)=xs(n)+rnd(rh(n)+1)-rh(n)/2:r(n)=1
if rnd(h)=0:{
if x(n)>mmousex:x(n)=xs(n)-rnd(rh(n)/2+1):else:x(n)=xs(n)+rnd(rh(n)/2+1)
}
}else{
y(n)=ys(n)+rnd(rh(n)+1)-rh(n)/2:r(n)=0
if rnd(h)=0:{
if y(n)>mmousey:y(n)=ys(n)-rnd(rh(n)/2+1):else:y(n)=ys(n)+rnd(rh(n)/2+1)
}
}
x(n)=limit(x(n),1,ginfo_winx-1):y(n)=limit(y(n),1,ginfo_winy-1)
n+
if n=a:n=0{
pos 0,0
gcopy 3,0,0,ginfo_dispx,ginfo_dispy
if hassan&i\10=0:pos 12,12 :color ,255,:if rnd(10):mes "ハッサン":else:mes "オッサン"
if hassan=0:pos 12,12 :color ,64,:mes "ダンゴ"+a+"="+amax+""
redraw 1:wait w:redraw 0
i+
if a!amax&i\1=0{
x(a)=mmousex+rnd(l*2+1)-l
y(a)=mmousey+rnd(l*2+1)-l
xs(a)=x(a)
ys(a)=y(a)
r(a)=rnd(2)
rh(a)=rnd(96)+32
c(a)=rnd(256-64)+64
a+
}
if a=amax:h=10:w=3:hassan=1
}
loop
どんどん増えてマックスになったら発散します。マウスによってきます。
| |
|
2008/3/27(Thu) 19:25:08|NO.14633
おっしゃるとおり、乱数には一定のパターンがあります。
コンピュータ上では、適当に数値を割り振るというのが困難なため、
擬似的に乱数のようなものを返す関数を使用しています。
「擬似乱数」等で調べてみるといいと思います。
|
|
2008/3/27(Thu) 20:03:06|NO.14634
HSPでは乱数を生成するときに何らかの擬似乱数生成法をもちいて
$00000000〜$ffffffffの範囲(かな?)で膨大な大きさの数字を生成し
Aまでの乱数を取得するとき
Aで割ったときの余りを返す(のかな)
だから
b=rnd(0)
とかすると0で割るから
---------------------------
Error
---------------------------
#Error 19 in line 1 (???)
-->0で除算しました
---------------------------
OK
---------------------------
のエラーが出るんだろうね (間違ってたらごめんなさい)
|
|
2008/3/28(Fri) 02:23:19|NO.14647
>>begriffさん
これ面白いから流用してもいいですか?
|
|
2008/3/28(Fri) 04:44:43|NO.14649
nodataさん
解説ありがとうございます。
自分にも理解することが出来ました。
begriffさん
解決法・応用例などたくさんの知識をありがとうございました。
|
|
2008/3/28(Fri) 08:03:57|NO.14650
・・・。
・・・!!
いかん、見た目の面白さに、これが質問だったと言う事を忘れていた・・・・。
|
|
2008/3/28(Fri) 09:17:01|NO.14651
>>これ面白いから流用してもいいですか?
かまいませんww
|
|
2008/3/28(Fri) 09:42:30|NO.14652
お使いになられるのでしたらコメントがあったほうがいいですよね…
#define mmousex (ginfo(0)-(ginfo(4)+(ginfo(10)-ginfo(12))/2))
#define mmousey (ginfo(1)-(ginfo(5)+(ginfo(11)-ginfo(13))-(ginfo(10)-ginfo(12))/2))
winx=ginfo_dispx/2 ///ウィンドウサイズX
winy=ginfo_dispy/2 ///ウィンドウサイズY
win_mode=1 ///フルかウィンドウか
w=3 ///ウエイト
a=100 ///最大個数ニョロニョロ
l=1 ///初期位置にランダム性を与える
h=2 ///hの値が大きくなればなるほどマウスから離れることができる。(ハッサン)
dim x,a
dim y,a
dim xs,a
dim ys,a
dim r,a
dim rh,a
buffer 3,winx,winy
color
boxf
if win_mode:screen 0,winx,winy:else:bgscr 0,winx,winy
width ,,0,0
randomize
///配列に初期値を入れる
repeat a
x(cnt)=mmousex+rnd(l*2+1)-l///初期位置X
y(cnt)=mmousey+rnd(l*2+1)-l///初期位置Y
xs(cnt)=x(cnt)
ys(cnt)=y(cnt)
r(cnt)=rnd(2)///縦から動きが始まるか、横からか
rh(cnt)=rnd(96)+32//それぞれの一フレームで動ける最大
c(cnt)=rnd(256-64)+64//それぞれの色
loop
gmode 3,ginfo_dispx,ginfo_dispy,16
///透明率でフェードアウトする早さ
boxf
///メイン
repeat
color ,c(n), : boxf xs(n),ys(n),x(n),y(n)
xs(n)=x(n)
ys(n)=y(n)
if r(n)=0 {
x(n)=xs(n)+rnd(rh(n)+1)-rh(n)/2:r(n)=1
if rnd(h)=0:{///hの値が大きくなればなるほどマウスから離れることができる。
if x(n)>mmousex:x(n)=xs(n)-rnd(rh(n)/2+1):else:x(n)=xs(n)+rnd(rh(n)/2+1)
///h回に一回、目標の地点に誘導
}
}else{
y(n)=ys(n)+rnd(rh(n)+1)-rh(n)/2:r(n)=0
if rnd(h)=0:{///hの値が大きくなればなるほどマウスから離れることができる。
if y(n)>mmousey:y(n)=ys(n)-rnd(rh(n)/2+1):else:y(n)=ys(n)+rnd(rh(n)/2+1)
///h回に一回、目標の地点に誘導
}
}
x(n)=limit(x(n),1,ginfo_winx-1):y(n)=limit(y(n),1,ginfo_winy-1)
///画面外禁止
n+
if n=a:n=0{
///一通り終わったら描画
pos 0,0
gcopy 3,0,0,ginfo_dispx,ginfo_dispy
///フェードアウトっていうやつかな(buffer画面の真っ黒を半透明でコピーしているだけ)
redraw 1:wait w:redraw 0
}
loop
| |
|
2008/3/28(Fri) 20:10:21|NO.14660
もう解決してるみたいでだけど、参考になると思うのでウンチク垂れさせて。
rndで使っている疑似乱数は合同線形法といって余り精度のいい乱数ではない。
詳しくは言わないけど周期が下位ビットほど悪く、rndの最下位ビットの周期は2^17で、
hxさんのスクリプトで使っているrnd(4)の周期は2^18しかない。
よって対応策としてはもっと周期の長い乱数を使うか、計算方法を工夫すればいい。
HSPにも周期の長い乱数としてrndf_getiが用意されてるし、rndを使う場合でもrnd(4)ではなく
(rnd(32768)/(32767/4+1))を使えば周期は2^31になる。
rnd(4)の周期が2^18なのは以下を実行すれば分かると思う。
randomize
repeat 25,1
a=""
repeat 35
a+=","+rnd(4)
loop
mes strf("%02d週目",cnt)+a
repeat (1<<18)-35
b=rnd(4)
loop
await 0
loop
|
|
2008/3/29(Sat) 21:57:58|NO.14689
>>begriff
ありがとうございます。
|
|