Hello,
As title say, I want to generate random non repeating numbers so I can assign them to an array or variables
any help would be appreciated.
Steve
Posted 16 August 2015 - 08:53 AM
You should be able to get what you need from this returning strnum. There's more snippets here: Script Guy Blog
'This will produce a non repeating random numbers.
intHighNumber = 24
intLowNumber = 1
Dim isUsed(24)
For i = 1 to 100
Randomize
intNumber = Int((intHighNumber - intLowNumber + 1) * Rnd + intLowNumber)
If IsUsed(intNumber) <> "Y" Then
IsUsed(intNumber) = "Y"
strnum = strnum & " " & Cstr(intNumber)
End If
Next
scoretext.text = strnum
Bump maps are the new auto-tune ![]()
VPX - RSS Updates ---- blog.flippingflips.xyz/en/ -- Visual Pinball No.1 (2021) . Est.2000
Posted 16 August 2015 - 05:22 PM
I tried in VP before I posted here and it was fine. If you check the very bottom (scoretext.text = strnum), you could test that in the default table VP10 and see the result displayed.
What is in the script that FP can't handle there? WIll try it out...
Bump maps are the new auto-tune ![]()
VPX - RSS Updates ---- blog.flippingflips.xyz/en/ -- Visual Pinball No.1 (2021) . Est.2000
Posted 16 August 2015 - 06:08 PM
Hmmm...this is weird.
it seem to work now :
**************************************************************
Dim intHighNumber,intLowNumber,intNumber,strnum
intHighNumber = 20
intLowNumber = 1
Dim isUsed(24)
Dim i
For i = 1 to 100
Randomize '(Left out because it is already initiated in FP script at the beginning)
intNumber = Int((intHighNumber - intLowNumber + 1) * Rnd + intLowNumber)
If IsUsed(intNumber) <> "Y" Then
IsUsed(intNumber) = "Y"
strnum = strnum & " " & Cstr(intNumber)
End If
Next
AddDebugText "Ran Int : "&strnum
*************************************************************************
But I know what I did wrong. I took out "Randomize" because there were comment in the thread saying it was better to do so.
Thanks a lot Chepas. I will give you the credit on the table (Tribute to 80's : Warlock)
Posted 16 August 2015 - 06:18 PM
No worries. I've saves both versions now and could be of use to me sometime too!
Bump maps are the new auto-tune ![]()
VPX - RSS Updates ---- blog.flippingflips.xyz/en/ -- Visual Pinball No.1 (2021) . Est.2000
Posted 16 August 2015 - 06:34 PM
One last thing chepas, How would you modify the script
so every new generated integer is stored as his own unique variable?
e.g.
myNewVar1=12
myNewVar2=16
myNewVar3=7
myNewVar4=6
myNewVar5=14
myNewVar6=5
myNewVar7=11
myNewVar8=4
myNewVar9=10
myNewVar10=13
myNewVar11=3
myNewVar12=8
myNewVar13=9
myNewVar14=19
myNewVar15=2
myNewVar16=5
myNewVar17=17
myNewVar18=20
myNewVar19=18
myNewVar20=1
myNewVar1=15
(It would be so much easier if FP would be able to deal with array.push and array.shuffle...) ![]()
Posted 16 August 2015 - 06:49 PM
I tried to modified this line :
strnum = strnum & " " & Cstr(intNumber)
With :
strnum = strnum & Cstr(intNumber)&","
so it give me a string that sort of look like an array...
1,6,18,5,14,13,17,4,12,19,15,7,16,3,10,8,11,9,2,20,
but it need something more to be a usable array.!?
'************************************************************************************ ' Non repeating random numbers. '************************************************************************************ Dim intHighNumber,intLowNumber,intNumber,strnum intHighNumber = 20 intLowNumber = 1 Sub SeedRandomInteger() Dim isUsed(24) Dim i For i = 1 to 100 Randomize intNumber = Int((intHighNumber - intLowNumber + 1) * Rnd + intLowNumber) If IsUsed(intNumber) <> "Y" Then IsUsed(intNumber) = "Y" strnum = strnum & Cstr(intNumber)&"," End If Next end sub SeedRandomInteger() AddDebugText "Ran Int : "&strnum
Edited by Steve Paradis, 16 August 2015 - 06:50 PM.
Posted 16 August 2015 - 06:52 PM
Have you tried a dictionary? They definitely work in VP but there could be problems because of COM object??
Dim dict
Set dict = CreateObject _
("Scripting.Dictionary")
dict.Add KeyIndex, YourNumber
Retrieve key at 1
dict.Item(1)
returns YourNumber
More info here:
http://windowsitpro....ernative-arrays
Bump maps are the new auto-tune ![]()
VPX - RSS Updates ---- blog.flippingflips.xyz/en/ -- Visual Pinball No.1 (2021) . Est.2000
Posted 16 August 2015 - 07:15 PM
Heh, had to try it myself but already knew that even a dictionary would be blocked...
Dim MyArray(24) 'This will produce a non repeating random numbers. intHighNumber = 24 intLowNumber = 1 Dim isUsed(24) For i = 0 to 24 Randomize intNumber = Int((intHighNumber - intLowNumber + 1) * Rnd + intLowNumber) If IsUsed(intNumber) <> "Y" Then IsUsed(intNumber) = "Y" strnum = strnum & " " & Cstr(intNumber) MyArray(i) = intNumber End If Next scoretext.text = "Ran Int : " & MyArray(3)
Surely that does the job in FP?
Edited by chepas, 16 August 2015 - 09:56 PM.
Bump maps are the new auto-tune ![]()
VPX - RSS Updates ---- blog.flippingflips.xyz/en/ -- Visual Pinball No.1 (2021) . Est.2000
Posted 16 August 2015 - 08:49 PM
You all do it realy wrong way (and not efective).
Here is correct way:
Init
Step 1: Fill table with values without repetition. For example if we want 10 values we create tab with values 1, 2, 3, .. 10. Remember also number of not used values in this tab, (so at start it is 10)
Thats all about init
Get random number:
Step 1: genereate random number between 1 and [number of not used values]. Generated random value = tab(x)
Step 2: now we swap this value with value at index [number of not used values] in tab. So in next iteration we will not hit this number again.
Setp 3: decrese number of not used numbers;
Example of how it work:
At begin in tab we have: 1,2,3,4,5,6,7,8,9,10 and [number of not used value] = 10;
step 1: calc random position in tab between 1 and [number of not used value]. Lets say it is 3.
step 2: we sawp values in tab at index 3 and 10. So tab will be: 1,2,10, 4,5,6,7,8,9, 3
step 3: decres [number of not used values],.... = 9.
At next iteration we will have random number between 1 and 9, so we will not get "3" again
If [number of not used numbers] is equal to ZERO, this means we already used all numbers, so we set [number of not used values] to intial value = 10.
Bellow is my code example. Use it this way:
1. Set "numOfRandomVals" to need number and set size of "rndTab" to same value
2. Call once RndReset();
3. Call any number of times "GetRnd()" tihs will return unique values
If you need to restart random number genertar all you need is to set rndCurrentIndex = numOfRandomVals. You don't need to call RndReset, because "rndTab" at begin must have al needd unique vales. That values don't have to be in any specyfic order.
numOfRandomVals = 10
Dim rndTab(10)
rndCurrentIndex = numOfRandomVals
Randomize
Sub RndReset()
For i = 1 to numOfRandomVals
rndTab(i) = i
Next
rndCurrentIndex = numOfRandomVals
end sub
Function GetRnd()
REM get rendom index in rndTab between 1 ... rndCurrentIndex
x = int(rnd * rndCurrentIndex) + 1
REM we will return value from tab
GetRnd = rndTab(x)
REM now we will swap this value with value with value at end of range
tmp = rndTab(rndCurrentIndex)
rndTab(rndCurrentIndex) = rndTab(x)
rndTab(x) = tmp
REM decrease tab range
rndCurrentIndex = rndCurrentIndex - 1
REM restart if we used all values
if rndCurrentIndex = 0 then
rndCurrentIndex = numOfRandomVals
end if
End Function
Edited by ravarcade, 16 August 2015 - 08:56 PM.
BAM page: http://www.ravarcade.pl
current BAM version: v1.5-317, released: Oct 11, 2020
Posted 16 August 2015 - 09:15 PM
You all do it realy wrong way (and not efective).
Sure. Wrong that it's a simple working function? The effective / faster comment I can take, but you'd be best posting that kind of reply on the blog it came from originally and not to blind leading blind. http://blogs.technet...g-a-script.aspx
Bump maps are the new auto-tune ![]()
VPX - RSS Updates ---- blog.flippingflips.xyz/en/ -- Visual Pinball No.1 (2021) . Est.2000
Posted 16 August 2015 - 09:56 PM
The last example I pasted over from VP was incorrect. I missed a couple of things like "next" in the loop
, I've edited that now.
Bump maps are the new auto-tune ![]()
VPX - RSS Updates ---- blog.flippingflips.xyz/en/ -- Visual Pinball No.1 (2021) . Est.2000
Posted 17 August 2015 - 01:15 AM
It's not a matter of not trying but I have been crushing my head over this for 3 hours
now and none of the above example works in FP even if I declare every DIM at the start.
I am terribly sorry for the waste of your time. I go plan B and bake a bunch of pre randomized
Arrays and use "select case random..." to have my "pseudo different scenario."
Again, thank you Chepas for you time.
@Rav. It is not working also. Calling RndReset() then GetRnd doesn't return anything.
Edited by Steve Paradis, 17 August 2015 - 01:20 AM.
Posted 17 August 2015 - 01:32 AM
Try this:
Dim MyArray(24) Dim intHighNumber, intLowNumber,intNumber intHighNumber = 24 intLowNumber = 1 Dim isUsed(24) Dim i,d d=0 Sub GenRandomInts() For i = 0 to 100 intNumber = Int((intHighNumber - intLowNumber + 1) * Rnd + intLowNumber) If IsUsed(intNumber) <> "Y" Then IsUsed(intNumber) = "Y" MyArray(d) = intNumber d = d+1 End If Next ENd Sub
Then in your beginPlay
GenRandomInts() AddDebugText "Ran Int : " & MyArray(3)
Edit: loop 0 - 23
Edited by chepas, 17 August 2015 - 01:57 AM.
Bump maps are the new auto-tune ![]()
VPX - RSS Updates ---- blog.flippingflips.xyz/en/ -- Visual Pinball No.1 (2021) . Est.2000
Posted 17 August 2015 - 01:58 AM
Check the update.........The 100 there is enough for it to fill the empties. Which isn't good enough.
Dim RandomInts(24) Sub FuturePinball_BeginPlay() Randomize RndReset() for i = 0 to 23 RandomInts(i) = GetRnd() AddDebugText "Ran Int : " & i & " " & RandomInts(i) Next ' initalise the player display reel to the last known player scores Player1Reel.SetValue(nvScore1) Player2Reel.SetValue(nvScore2) Player3Reel.SetValue(nvScore3) Player4Reel.SetValue(nvScore4) ' We want the player to put in credits (Change this bFreePlay = FALSE ' kill the last switch hit (this this variable is very usefull for game control) set LastSwitchHit = DummyTrigger ' initialse any other flags bOnTheFirstBall = FALSE bEnteringAHighScore = FALSE BallsOnPlayfield = 0 BallsInLock = 0 EndOfGame() End Sub numOfRandomVals = 24 Dim rndTab(24) Dim rndCurrentIndex,numOfRandomVals,x,tmp,i rndCurrentIndex = numOfRandomVals Randomize Sub RndReset() For i = 1 to numOfRandomVals rndTab(i) = i Next rndCurrentIndex = numOfRandomVals end sub Function GetRnd() REM get rendom index in rndTab between 1 ... rndCurrentIndex x = int(rnd * rndCurrentIndex) + 1 REM we will return value from tab GetRnd = rndTab(x) REM now we will swap this value with value with value at end of range tmp = rndTab(rndCurrentIndex) rndTab(rndCurrentIndex) = rndTab(x) rndTab(x) = tmp REM decrease tab range rndCurrentIndex = rndCurrentIndex - 1 REM restart if we used all values if rndCurrentIndex = 0 then rndCurrentIndex = numOfRandomVals end if End Function
Edited by chepas, 17 August 2015 - 02:14 AM.
Bump maps are the new auto-tune ![]()
VPX - RSS Updates ---- blog.flippingflips.xyz/en/ -- Visual Pinball No.1 (2021) . Est.2000
Posted 17 August 2015 - 02:13 AM
^^ try that edit with rav function , that should be 100%
Bump maps are the new auto-tune ![]()
VPX - RSS Updates ---- blog.flippingflips.xyz/en/ -- Visual Pinball No.1 (2021) . Est.2000