random generator issue

Monkey Forums/Monkey Beginners/random generator issue

Ashmoor(Posted 2016) [#1]
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



Goodlookinguy(Posted 2016) [#2]
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


Ashmoor(Posted 2016) [#3]
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!


Jesse(Posted 2016) [#4]
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.


Ashmoor(Posted 2016) [#5]
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.


Jesse(Posted 2016) [#6]
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.


therevills(Posted 2016) [#7]


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



Gerry Quinn(Posted 2016) [#8]
Still using Diddy.RealMillisecs()

I have my own integer rand() copied from MSVC, though. I don't trust FP.


Goodlookinguy(Posted 2016) [#9]
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.


Steve Ancell(Posted 2016) [#10]
Doing this at the entry point has so far worked for me.

Seed = (Millisecs() + GetDate()[5])



therevills(Posted 2016) [#11]
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).


Goodlookinguy(Posted 2016) [#12]
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.


Ashmoor(Posted 2016) [#13]
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.


Goodlookinguy(Posted 2016) [#14]
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...



Gerry Quinn(Posted 2016) [#15]
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.


Ashmoor(Posted 2016) [#16]
@goodlookinguy that sounds pretty good, I will do that.

Thank you guys.