Denken Sie an den Unterschied zwischen 1 Würfel und 3 Würfel . 1 Würfel gibt Ihnen eine gleichmäßige Wahrscheinlichkeit für alle Werte, während 3 Würfel tendenziell eine höhere Wahrscheinlichkeit für die Werte in Richtung Mitte haben.
Je mehr "Würfel" in Ihrer Gleichung enthalten sind, desto größer ist Ihre Chance, etwas in Richtung Zentrum zu bringen. Definieren wir also eine Funktion, die jede Zahl gleichmäßig verarbeiten kann :
// Takes a random number between floor and ceil
// pow defines how strongly these results should gravitate towards the middle
// We also define a function TrueRand(floor, ceil) elsewhere where you should substitute your own random function
int CenterRandom(int floor, int ceil, int pow = 3)
{
if(ceil == floor)
return ceil; // don't care to compare
int total = 0;
for(int x = 0; x < pow; x++)
{
total += TrueRand(floor, ceil);
}
return total / pow;
}
Jetzt können wir eine Beispielfunktion definieren, um dies zu verwenden:
// Distribues a number of points between floor and ceil
// We assume a function PlotPoint(int) exists to aid in creating the planet, etc...
void DistributePoints(int floor, int ceil, int numPoints)
{
// Could easily output this in the function parameters, but language wasn't specified
int[numPoints] breaks;
int numBreaks = 0;
// Special case for first pair
breaks[0] = CenterRandom(floor, ceil);
numBreaks++;
for(int x = 0; x < numPoints - 1; x++)
{
// Generate a random number linearly, this will be used for picking
// This way we have a greater chance of choosing a random value between larger pairs
int picker = TrueRandom(floor, ceil);
// Now we first find the pair of points that our picker exists on
// For simplicity, we handle the first and last pair separately
if(picker >= floor && picker < breaks[0])
{
breaks[x] = CenterRandom(floor, breaks[0] - 1);
}
for(int i = 0; i < numBreaks; i++)
{
if(picker > breaks[i] && picker < breaks[i+1])
{
breaks[x] = CenterRandom(breaks[i] + 1, breaks[i+1] - 1);
}
}
if(picker > breaks[numBreaks] && picker <= ceil)
{
breaks[x] = CenterRandom(breaks[numBreaks] + 1, ceil);
}
PlotPoint(breaks[x]); // Plot the point
}
}
Als erstes ist zu beachten, dass dieser Code wirklich nicht prüft, ob die Auswahl bereits mit einem der Punkte übereinstimmt. Wenn dies der Fall ist, wird einfach kein Punkt generiert, möglicherweise etwas, das Sie möchten.
Um zu erklären, was hier vor sich geht, generiert CenterRandom eine Art Glockenkurve. Diese Funktion unterteilt die Ebene in mehrere Glockenkurven, eine pro vorhandenem Punktepaar. Der Picker teilt uns mit, aus welcher Glockenkurve generiert werden soll. Da wir linear auswählen, können wir sicherstellen, dass Paare mit größeren Lücken häufiger ausgewählt werden, aber wir lassen es trotzdem völlig zufällig.
Hoffe das weist dich in die richtige Richtung.