Pensa alla differenza tra 1 dado e 3 dadi . 1 dado ti dà una probabilità uniforme per tutti i valori, mentre 3 dadi tenderanno ad avere una probabilità più alta per i valori verso il centro.
Più "dadi" nella tua equazione, maggiore è la tua possibilità di ottenere qualcosa verso il centro. Quindi definiamo una funzione che può gestire qualsiasi numero in modo uniforme :
// 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;
}
Ora possiamo definire una funzione di esempio per usare questo:
// 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
}
}
Ora il primo da notare è che questo codice in realtà non controlla se il selettore corrisponde già a uno dei punti. In tal caso, non genererà un punto, forse qualcosa che ti piacerebbe.
Per spiegare cosa sta succedendo qui è che CenterRandom genera una sorta di curva a campana. Questa funzione suddivide il piano in più curve a campana, una per coppia di punti esistenti. Il selettore ci dice da quale curva a campana generare. Poiché scegliamo linearmente, possiamo garantire che le coppie con spazi più ampi tra loro vengano scelte più spesso, ma lo lasciamo ancora completamente casuale.
Spero che questo ti indichi nella giusta direzione.