Tietääkö kukaan, millä periaattella RND-funktio satunnaislukunsa tekee. Joku kaavahan siinä on pakko olla, tekeehän se aina samat luvun tietyllä siemenluvulla. Kerran muuten huomasin, että RND rupesi toistamaan tiettyä säännönmukaisuutta.
Tässä pieni asiaa ilmentävä koodinpätkä.
SCREEN 13 FOR a = 1 TO 2000 RANDOMIZE TIMER PSET (INT(RND * 320), INT(RND * 200)), 15 NEXT a
Tietysti tuo RANDOMIZE TIMER voisi olla sílmukan ulkopuolella. Jatkuva siemenluvun vaihto kuitenkin lisää säännönmukaisuutta. Mutta ilman sitäkin huomasin selvää säännönmukaisuutta. Tietääkö joku kaavaa, jota RND käyttää. Yritin tehdä omaa Randomizea, mutta siitä tuli vielä säännönmukaisempi. Joka tapauksessa se kai perustuu päättymättömien desimaalilukujen yksittäisten desimaalien Sini tai Kosini-arvoihin tai jotain sinne päin.
Ulkomuistista:
uusi x lasketaan vanhasta
x = (a*x+c) mod m
satunnaisluku= x/m
mod m tarkoittaa että jaetaan M:llä ja otetaan jakojäännös.
Laskenta tehdään 32 bittisesti ja vb6:ssa on long 31 bittinen, joten menee vaikeaksi.
Kokeilepa saada kaksi erittäin pientä satunnaislukua tulemaan peräkkäin!
Hmm... Voisikos joku tehdä ohjelmanpätkän, joka tuottaisi noita satunnaislukuja tuolla sinun kaavallasi :)
mitä nuo a, c ja m on? Vai onko se suoraan tuo x/m? Ei taida tuo 32 bittinen sitten toimia. Kattoitteko tuon koodin? Siinä näkyy kait aika selvästi säännöllisyyttä.
Tuotanoin, tossa on toi RANDOMIZE TIMER ton for-silmukan sisällä. Kun sen ottaa sieltä riviä ylemmäs, niin jopas toimii ;)
lainaus:
mitä nuo a, c ja m on? Vai onko se suoraan tuo x/m?
Muakin kiinnostaisi...
Totaa, mikä yksi koodi vinkki olikaan jonka mukaan ei edes RANDOMIZE TIMER ole täysin säännötön?
leikin vähän randomilla:
SCREEN 13 DO PSET (INT(RND * INT(RND * INT(RND * 320))), INT(RND * 200)), 14 PSET (INT(RND * INT(RND * INT(RND * 320))), INT(RND * 200)), 2 PSET (INT(RND * INT(RND * INT(RND * 320))), INT(RND * 200)), 1 PSET (INT(RND * INT(RND * INT(RND * 320))), INT(RND * 200)), 3 LOOP UNTIL INKEY$ <> ""
Kokeilkaas tuota... hmm... miksi tietyt värit jäävät tiettyyn kohtaan ruutua??
lainaus:
Tuotanoin, tossa on toi RANDOMIZE TIMER ton for-silmukan sisällä. Kun sen ottaa sieltä riviä ylemmäs, niin jopas toimii ;)
Niin minähän sanoin tuossa ekassa viestissä, että RANDOMIZE TIMER on silmukan sisällä. Tästä voidaan päätellä, että jatkuva siemenluvun vaihtaminen lisää säännönmukaisuutta. Mutta jos siemenlukua vaihtaa kesken kaiken niin uusi sarja ei alakaan samalla tavalla, jos aikaisemmin on käytetty toista sarjaa.
Ja tuossa T.M:n koodissa on seuraava vikana:
Sen pitäisi olla
PSET(INT(RND*320), INT(RND*200)),14
Miksi tuo INT(RND*320) pitää vielä kertoa INT(RND):llä?
Sen takia värit pakkautuvat vasemalle enemmän.
lainaus:
Totaa, mikä yksi koodi vinkki olikaan jonka mukaan ei edes RANDOMIZE TIMER ole täysin säännötön?
Tietenkään RANDOMIZE TIMER ei ole täysin säännötön. Pakkohan siinä jokin kaava on olla, kun aina samat luvut tulevat samalla siemen luvulla. TIMER:han vaan estää käyttäjää päättämästä siemenlukua. Mutta miten se RND saa ne satunnaisluvut generoitua siemenluvusta, sitä en tiedä, mutta joku kaava on pakko olla. Ei niitä lukuja tyhjästäkään voi nyhtäistä.
Niimpä. Mutta joskus on käynyt mielessä,että emarille on ängetty jokin satunnais luku laskia. Kyllä elektroniikalla sellaista pitäisi saada aikaan.
En oo ite mielestäni nähny mitään basic ohjelmaa jossa tuo random tosiaan toimii satunnaisesti. Monessa pelissä missä oon arponu esim nimiä tauluun, tulevat samat nimet aina esille. Yksi ratkaisu on miten ongelmasta päästään eroon on kun tallennat pelissä arpomisen jälkeen kerran alussa randomi luku tiedostoon josta se alussa avaat sen, tässä esimerkki periaate, ei koodi:
lataa tallennettu numero tiedostosta
aja kerran randomi läpi : int (avattu numero*rnd(1))+1
nyt voit pyöräyttää randomin, ja se toimii tosiaan satunnaisesti.
tallenna viimeksi saatu random luku tiedostoon.
Ei todellakaan järkevä ratkaisu, mutta toimiva :)
lainaus:
Miksi tuo INT(RND*320) pitää vielä kertoa INT(RND):llä?
Sen takia värit pakkautuvat vasemalle enemmän.
Tarkoitus ei ollut tehdä samaa kuin sinä. Toi oli vain jokin testi :)
mutta näyttää siltä että tuo testi todistaa kuinka huono QB:n randomi on.
Yhdellä värillä: http://koti.mbnet.fi/winuus/qbranplain.png
Tässä testissä nuo pikselit eivät enää menneet muualle kuin noihin samoihin paikkoihin.
Neljällä värillä: http://koti.mbnet.fi/winuus/qbranmulti.png
Sama juttu, mutta värit menivät eri alueille.
Ilman INT systeemiä: http://koti.mbnet.fi/winuus/qbrannoint.png
Tulee paljon säännöllisempiä pikseliryhmittymiä.
Testasin PHP:llä samaa, mutta pikselit menivät juuri niin kuin pitikin, eli epätasaisesti vasemmalta oikealle vähentyen. Tosin kuin QB-systeemissä pikselit ryhmittyivät.
Outoa...
Ohjeet oman satunnaislukugeneraattorin tekemiseksi: http://www.physics.helsinki.fi/~fyl_tlpk/
QBasicin satunnaislukugeneraattorin jakso näyttäisi olevan 16777216. Asian voi havaita seuraavalla ohjelmalla, joka katsoo, milloin aluksi arvotut 10 satunnaislukua tulevat jälleen uudestaan.
DEFINT A-Z RANDOMIZE TIMER CLS DIM alku(10) AS SINGLE FOR i = 1 TO 10 alku(i) = RND NEXT tila = 0 DO s& = s& + 1 l! = RND IF s& MOD 10000 = 0 THEN LOCATE 1, 1: PRINT s& END IF IF alku(tila + 1) = l! THEN tila = tila + 1 IF tila = 10 THEN PRINT "Jakson pituus:"; s& END END IF ELSE tila = 0 END IF LOOP
Joku voi testata muilla ohjelmointikielillä. :)
Joo'o, aivan. 16777216:han se.
Aihe on jo aika vanha, joten et voi enää vastata siihen.