Jump to content
Unity Insider Forum

Prozeduale Chance in Listenreihenfolge


MustafGames

Recommended Posts

Gruß,

habe da mal wieder etwas gefunden wo ich nicht weiter komme (Mathe halt):

Angenommen wird haben eine Liste mit 8 Objekten, dann soll eine Methode per Zufall entscheiden welches Objekt genommen wird, dieser Zufall soll noch beeinflusst werden von der Position des Objektes in der Liste (Objekt 1 hat eine höhere Wahrscheinlichkeit als Objekt 2 usw..).

 

    public static int GetPercentageByList (int listSize) {
        if (listSize > 0) {
            for (int i = 0; i < listSize; i++) {
                float chance = (100.0f / (float)i) * 0.01f;
                if (Random.value <= chance) {
                    return i;
                }
            }
        }
        return 0;
    }

Liege ich mit meiner Variante richtig?

 

MfG Mustaf.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wenn du genau ein Objekt aus einer Menge auswählen willst, dann ist es auf jeden Fall ein Warnzeichen, wenn du mehrere Male würfelst. Sagen wir, du hast nur zwei Ergebnisse: Eins mit einer 60%-Chance und eins mit 40%. Damit ist die Chance, dass du bei beiden "daneben würfelst", 0.4 * 0.6 = 0.24. Du hast also eine 24%-Chance, keines von beiden auszuwählen.

Besser ist es, ein einzelnes Mal zu würfeln und dann zu schauen, was das Ergebnis des Wurfes bedeutet.

Dazu braucht man die Summe aller Gewichtungen (im Beispiel 0.4 + 0.6 = 1, aber muss ja nicht immer auf 1 summieren) und skaliert das Ergebnis um diesen Wert.

Es wäre eine Elegante Methode, ein Struct zu haben, das das mögliche Objekt und dessen Gewichtung hat:

public struct RandomResult
{
  public int result;
  public float weight;
}

Dann kriegt man eine Menge Instanzen dieses Structs und bildet die Summe:

public int PickRandomly(RandomResult[] results)
{
  var sumOfAllWeights = results.Select(result => result.weight).Sum();

Anschließend kannst du würfeln über deine Ergebnisse iterieren und schauen, "wie weit" dein Zufallsergebnis kommt:

var roll = Random.value * sumOfAllWeights;

for (var result in results)
{
  if (roll < result.weight)
  {
    return result.result;
  }
  else
  {
    roll -= result.weight;
  }
}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...