random generator issue
Monkey Forums/Monkey Beginners/random generator issue
| ||
I want to create a random piece using a class function. Inside the function i set the seed to Millisecs() and each time i use Rnd the result is 3. Any ideas why? If I set the seed somewhere else in the code it works fine. This is the code:Function CreateNewPiece:TPiece(bx:Int, type:Int = -1) Local piece:TPiece = New TPiece Seed = Millisecs() If type = -1 Then 'randomize piece type type = Rnd(13.0) Print "t=" + type + " ms:" + Seed EndIf |
| ||
Millisecs() returns the number of seconds the game itself has been running. Hence why you keep getting the same result each time you start it. You need an external milliseconds function that gets the unix timestamp. Example External Functions: https://bitbucket.org/Goodlookinguy/xaddon/src/default/basic/externalfuncs.monkey?at=default&fileviewer=file-view-default Example Native Implementation: https://bitbucket.org/Goodlookinguy/xaddon/src/default/basic/native/?at=default |
| ||
I understand that it is normal to get the same Millisecs() result but I get the same Rnd result every time! I run the function 5 times and each time it returns the value "3" even though the seed itself changes! |
| ||
as Goodlookinguy said Millisecs count fromt the start of the game. so if it takes 3 millisecs for the game to reach the point were you asign seed than the seed will always be 3. so if the seed is the same every time so will your Rnd value will be the same. that's what you keep getting the same result. to verify try changing the seed manually to different values and see the results. my simplest suggestion is to add pause until the user presses a button then set the seed millisecond counter and Rnd Value. you can also do a menu instead of a key press. |
| ||
I am not making myself clear. There is enough time passing for the seed to be different. And even when it is different Rnd produces the same random which is 3. |
| ||
Good luck then. Best I can tell you is to look at the source code for the module and try to figure out why it's not doing what you want. Rnd is a simple 5 line function. its not hard to figure out why it's doing what it's doing. [edit] I did some test and this is what I got with seed 7,8 and 9 respectively, seed 7 23.878079652786255 91.34932160377502 61.24916076660156 92.69814491271973 4.934114217758179 85.57835221290588 36.09851002693176 5.310630798339844 6.878399848937988 98.39369654655457 97.28050231933594 53.12507748603821 45.18575668334961 54.783934354782104 60.50359606742859 77.74173021316528 77.98123359680176 41.807734966278076 47.41079807281494 85.21434664726257 seed 8 23.916834592819214 0.41970014572143555 29.719990491867065 96.39977812767029 71.58073782920837 60.349440574645996 79.2022168636322 96.9259262084961 57.74991512298584 4.13854718208313 42.6530659198761 21.606290340423584 42.871880531311035 49.96569752693176 83.33626389503479 24.351251125335693 93.29665303230286 43.32776665687561 77.26922035217285 73.89242053031921 seed 9 23.955589532852173 9.490078687667847 98.19082021713257 0.10141730308532715 38.22736740112305 35.12052893638611 22.305917739868164 88.54122161865234 8.621424436569214 9.883397817611694 88.02562952041626 90.08750915527344 40.55800437927246 45.14746069908142 6.168931722640991 70.9607720375061 8.612078428268433 44.847798347473145 7.127636671066284 62.57048845291138 I did noticed that the first and only the first are similar, the rest of the results are different. |
| ||
You need an external milliseconds function that gets the unix timestamp. Example External Functions: https://bitbucket.org/Goodlookinguy/xaddon/src/default/basic/externalfuncs.monkey?at=default&fileviewer=file-view-default Example Native Implementation: https://bitbucket.org/Goodlookinguy/xaddon/src/default/basic/native/?at=default Similar to the original Diddy solution :) I tend to use the internal MonkeyX date/time commands now, so you don't have to extern them yourself: Strict Import mojo Function Main:Int() Local date:Int[] = GetDate() Print date[5] + "." + date[6] Seed = date[5] + date[6] Print Rnd(0, 1000); Return 0 End |
| ||
Still using Diddy.RealMillisecs() I have my own integer rand() copied from MSVC, though. I don't trust FP. |
| ||
I tend to use the internal MonkeyX date/time commands now, so you don't have to extern them yourself: I have a function called DateToUnixTime which can give the unixtime from Monkey's GetDate function. I just prefer to use fast external functions. I am not making myself clear. There is enough time passing for the seed to be different. And even when it is different Rnd produces the same random which is 3. What platform(s) is this occurring on? Can you provide a reproducible sample that acts like your code. |
| ||
Doing this at the entry point has so far worked for me.Seed = (Millisecs() + GetDate()[5]) |
| ||
I have a function called DateToUnixTime which can give the unixtime from Monkey's GetDate function. Cool... is that part of XAddon? If so, which file? I just prefer to use fast external functions. FYI, MonkeyX's GetDate process flow: Function GetDate:Int[]() which calls Function GetDate:Void( date:Int[] ) defined in mojo.app: Function GetDate:Int[]() Local date:Int[7] GetDate date Return date End Function GetDate:Void( date:Int[] ) _game.GetDate date End _game is the global BBGame defined in brl.gametarget and is an extern. Extern ... Class BBGame Extends Null ... Method GetDate:Void( date:Int[] ) Which in turn calls the Extern function GetDate within the native gametarget files (eg. gametarget.as, gametarget.cpp, gametarget.java etc). |
| ||
Cool... is that part of XAddon? If so, which file? https://bitbucket.org/Goodlookinguy/xaddon/src/c6adde9be6843572e2c0be0dadac67c13b81a5ef/mojoplus/datetimefuncs.monkey?at=default&fileviewer=file-view-default The file is part of my horrible, and very old, Mojo+ framework. The problem is, I need to move it into xaddon.basic and as I recall, in a recent console app I wrote for a friend's minecraft backup on linux, I had to adjust the date by 21 days and 8 hours (I think). So take the function with a grain of salt as I believe the time gap is a combination of leap years and my time zone GMT-8. (It also comes out of a negative number because it's supposed to be an unsigned integer, but you know, limitations...) Edit: Actually, I don't see my DateToUnixTime function in there. Uh...hmm...I must have misplaced that. I'll do some digging but since I can't access my main computer right now, I may be at a loss. |
| ||
This is happening on PC, tested as html5. Here is a link to my project: https://drive.google.com/open?id=0B3GmHPif2yaCNGtyRVJSRTBiT1E (this is using fantomEngine) Uncomment the seed line in CreateNewPiece function. But I guess the result is similar to what Jesse got, if you follow his random number results you will see that the Int value of them is the same for first random. Will use GetDate() and look into the Ditty Framework. Thanks guys. |
| ||
Hmm, that's just a side-effect of typical random number generation. My suggestion is that you set the seed once, then call Rnd something like 5 times before to make sure it starts on a random value or, as I like to do, do it randomly the number of times the random function has calculated ignoring the initial value.Seed = YourSeedMethod Rnd() ' ignore Local timesToRandomize := Rnd(Rnd(7, 13), Rnd(17, 23)) For Local i:Int = 0 Until timesToRandomize Rnd() Next ' now when you call Rnd who knows what you'll get... |
| ||
I was going to suggest the same. Call it a few times if you want the first value to be different, Random numbers use multiplication and modulus to build up increasing differences in seeds that start close together, but it takes a couple of calls to get going from a tiny difference until the difference gets comparable to the size of the seed, or the portion of it that's used to generate the random number. |
| ||
@goodlookinguy that sounds pretty good, I will do that. Thank you guys. |