The Blitz3D randomness is very predictable due to the randomness seed being set to a static number by default and it always yields the same results. After the randomness method has been executed, the random seed shifts to a new, again predictable random seed.
Code: Select all
a = Rand(10) ; integer
b = Rand(20) ; integer
c# = Rnd(50) ; float
Print(a) ; 4
Print(b) ; 15
Print(c#) ; 34.1473
Delay 1000
Code: Select all
a = Rand(999) ; integer (This one got changed)
; these stay the same
b = Rand(20) ; integer
c# = Rnd(50) ; float
Print(a) ; 356
; these one are unchanged
Print(b) ; 15
Print(c#) ; 34.1473
Delay 1000
There are two random functions in Blitz3D Rnd and Rand, Rnd is for floating points and Rand is for integers. Both functions scramble the random generator for the next call. They both require one parameter which is a number either integer or float, and this number is used to divide and modulo the actual random number that gets generated. This is unnoticable with comparably small numbers (0 - 65535) but after that the number becomes less precise to the point it generates the same number
Code: Select all
mode = 0
If (mode = 0) Then
a = Rand(2147483646)
Else
a = Rand(2147483647)
EndIf
Print(a)
Delay 1000
Something else that can be done is to use SeedRnd(Millisecs()) which will put a random seed on the program where Millisecs() is the time in Unix of the device, that pretty much solves most of the problems except that if you know the exact Millisecs() you can put it in your own program and continue to predict the randomization
Code: Select all
; pre prediction
x = MilliSecs()
SeedRnd(x)
a = Rand(100)
Print(x)
Delay 1000
; post prediction
x = 1219170 ; the time I started the program
SeedRnd(x) ; seed that and it will give the number that was given last time on the pre-prediction phase
a = Rand(100)
Print(a)
Delay 1000
For the sake of simplicity for the remainder of this post I will be exploring the WA3 POTZ v1.02 code
Unfortunately for us MS thought of our sneaky tricks and he put a randomizer scrambler code that looks like this
Code: Select all
; Randomize
For bla= 1 To MilliSecs() Mod 100
blabla=Rand(0,44)
Next
Code: Select all
; Randomize
PatrickRandomizer = MilliSecs() Mod 100
Print (PatrickRandomizer )
For bla= 1 To PatrickRandomizer
blabla=Rand(0,44)
Next
a = Rand(1000)
Print(a)
Delay(1000)
With all that, there are 100 possible outcomes for randomness after the application has started. From there we can check the code for simple random events such as scritter or coily movement and run it in our program with the appropriate seed and know the outcomes.
This still needs expanding because there are small particles random stuff that can scramble the generator to oblivion and you can get lost in the code, that's why I am leaving this article unfinished for now, but it's something I've been thinking for a month or so to share around just for the fun nerdy moments in life
Video soon if I don't forget and move on