Ich habe eine umfassende Zufallszahlen-Maschine geschrieben, die mir bei meinen Spielereien große Dienste leistet.
Code: Alles auswählen
Rnd(min,max,[Mode])
Features:
• wenn man sich mit dem min und max-Wert vertut, werden die Werte automatisch korrigiert
• es dürfen negative Zahlen übergeben werden (auch beide Werte!)
• Der [Mode]-Parameter ist optional. Wenn man hier nichts eingibt, wird einfach nur stumpf eine Zahl innerhalb der übergebenen range erzeugt (#Rnd_Default)
• #Rnd_BellCurve erzeugt Zahlen gemäß der Gauß'schen Normalverteilung, will heißen, die range wird auf 2 Würfel aufgeteilt
• #Rnd_WellCurve erzeugt Zahlen gemäß einer invertierten Normalverteilung, d.h. extreme Werte in beiden Achsen werden bevorzugt
• #Rnd_GaußCeil erzeugt einen Gauß'schen Würfel mit Wichtung zum oberen Wert hin (z.B. erzeugt der Bereich 1-10 einen Würfel mit 55 Seiten)
• #Rnd_GaußFloor erzeugt einen Gauß'schen Würfel mit Wichtung zum unteren Wert
Viel Spaß!
//EDIT:
Update 20.06.2019
Code: Alles auswählen
EnableExplicit
Enumeration
#Rnd_Default
#Rnd_BellCurve
#Rnd_GaussCeil
#Rnd_GaussFloor
#Rnd_WellCurve
EndEnumeration
Declare Rnd(min,max,rndMode = #Rnd_Default)
Define dice
Define a
Define low = -10
Define high = -2
Define offset = -low ;offset for Dim(), in case negative numbers are involved
Dim nr(high+offset)
For a = 1 To 1000000 ;roll 1 mio. numbers
dice = Rnd(low,high,#Rnd_GaussCeil)
nr(dice+offset) +1 ;count, how often each number appears
Next
For a = low To high
Debug ""+a+": "+nr(a+offset)
Next
Procedure Rnd(min,max,rndMode = #Rnd_Default)
Define newValue
Define minus
Define a
Define sum, add
Dim dice(1)
Define lowMedian, highMedian
Define absLow, absHigh
If min > max ;wrong values will be corrected
Swap min,max
EndIf
max - min ;always work with numbers from 0 to x
Select rndMode
Case #Rnd_Default
newValue = Random(max) ;roll a die, duh
Case #Rnd_BellCurve
If max % 2 = 0 ;if difference is even ...
dice(0) = max/2 ;... create 2 even dice
dice(1) = max/2
Else
dice(0) = (max-1)/2 ;otherwise create 2 different dice (0-x and 0-(x+1))
dice(1) = (max+1)/2
EndIf
newValue = Random(dice(0)) + Random(dice(1))
Case #Rnd_GaussCeil, #Rnd_GaussFloor
max +1 ;temporarily increase max by 1 (Small Gauss only works with numbers > 0)
sum = (max+1)*(max*0.5) ;sum of all numbers from 1 to the chosen maxValue = Small Gauss
newValue = Random(sum,1) ;roll a random number between 1 and the Small Gauss
For a = 1 To max
add = add+a
If add >= newValue ;find the corresponding value
If rndMode = #Rnd_GaussCeil : newValue = a - 1 : EndIf ;get high values
If rndMode = #Rnd_GaussFloor : newValue = (max-a) : EndIf ;get low values
Break
EndIf
Next
Case #Rnd_WellCurve
lowMedian = max/2
highMedian = max/2
If lowMedian + highMedian < max
highMedian +1
EndIf
dice(0) = Random(lowMedian) ;get a low DieRoll (0 to lowMedian)
dice(1) = Random(max,highMedian) ;get a high DieRoll (highMedian to max)
absLow = Abs(dice(0)-lowMedian) ;determine, which roll is farther away from the Median value ...
absHigh = Abs(dice(1)-highMedian)
;... and pass it back
If absLow = absHigh
newValue = dice(Random(1))
EndIf
If absLow > absHigh
newValue = dice(0)
EndIf
If absHigh > absLow
newValue = dice(1)
EndIf
EndSelect
ProcedureReturn newValue + min ;Add back the initially subtraced min-Value
EndProcedure