Ein Algorithmus für halb zufällige Sortierung (Java)

8

Ich mache ein rundenbasiertes RPG-Spiel, und meine Methode, die alle "Actor" -Objekte in der Reihenfolge sortiert, in der sie alle angreifen, sortiert sie völlig zufällig. Ich möchte diese Methode jedoch verbessern, so dass ein "Agility" -Stat, den jeder Akteur hat, seine Rolle verbessern kann. Ich habe mir verschiedene Methoden in der Collections-Klasse und Arrays angesehen, aber ich habe nichts gefunden, was mir gefällt.

Im Moment denke ich darüber nach, ein zufälliges int zwischen 1 und 100 zu bekommen, und mit dem Agility Score die Chancen zu verbessern. Ich habe versucht, separate ArrayLists für die Ganzzahlen und eine HashMap ... aber ein Nein gehen auf diese.

Meine Methode wie sie jetzt ist:

%Vor%

Ich schätze die Hilfe!

    
Justin McConnell 07.09.2011, 22:55
quelle

5 Antworten

1
%Vor%

Dann können Sie

anrufen %Vor%     
Anthony 07.09.2011, 23:08
quelle
6

Ihre Frage geht nicht sehr detailliert auf die Anforderungen ein, wie Agilität Ihre Angriffsreihenfolge beeinflusst, aber ich nehme an, dass Sie eine dieser beiden gemeint haben:

  1. Wenn eine Einheit eine höhere Agilität hat als eine andere, greift sie zuerst immer an.
  2. Wenn eine Einheit eine höhere Beweglichkeit hat als eine andere, greift sie normalerweise normalerweise an.

Wenn der erste der beiden richtig ist (Einheiten mit höherer Agilität greifen immer zuerst an), dann ist das, was du suchst, eine Art der Permutierung des Arrays mit der Einschränkung, dass Einheiten mit höherer Agilität immer vor Einheiten niedrigerer Einheiten enden Beweglichkeit, aber mit allem anderen zufällig gemacht. Eine Möglichkeit, dies zu tun, ist wie folgt:

  1. Wenn Sie N Einheiten haben, ordnen Sie die Einheiten 1 ... N zufällig zu. Weisen Sie nicht zweimal die gleiche Nummer zu.
  2. Sortieren Sie die Einheiten wie folgt in aufsteigender Reihenfolge:
    • Jede Einheit mit höherer Beweglichkeit als eine andere Einheit kommt zuerst.
    • Von zwei gebundenen Untis, je nachdem, welche die höhere Zufallszahl hat.

Sie können zeigen, dass dieser Ansatz die Einheiten so anordnet, dass alle Einheiten mit einer bestimmten Beweglichkeit relativ zueinander zufällig permutiert werden, aber immer Einheiten mit geringerer Beweglichkeit kommen. Dies benötigt Zeit O (n log n) und kann mit Collections.sort , Collections.shuffle und einem passenden Comparator erfolgen.

Wenn Sie andererseits möchten, dass die Reihenfolge zufällig ist, aber durch die Agilität beeinflusst wird, sollten Sie darüber nachdenken, eine zufällige Verteilung zu verwenden, die von einem Parameter gesteuert werden kann. Zum Beispiel können Sie jeder Einheit eine Priorität zuweisen, die aus einer Normalverteilung gezogen wird, deren Mittelwert die Agilität ist und deren Standardabweichung eine einigermaßen große Zahl ist (z. B. 20). Das würde bedeuten, dass Einheiten mit mehr Agilität sich eher vor Einheiten mit weniger Agilität bewegen, obwohl es eine große Menge an Zufälligkeit gibt. Der Vorteil dieses Ansatzes besteht darin, dass Sie durch Feinabstimmung der zugrunde liegenden Verteilung und ihrer Parameter (Mittelwert und Varianz bei einer Normalverteilung) genau festlegen können, in welchem ​​Maße das Agilitätsmaß eingerechnet wird.

Als Beispiel für einen sehr einfachen Ansatz können Sie die Einheitengeschwindigkeit als

modellieren
  

Priorität = e (Agilität / 100) + zufällig (1, 2)

Hier gilt, je mehr Agilität Sie haben, desto größer ist Ihre Priorität. Durch die Erhöhung der Zufälligkeit ändert sich das Ausmaß, in dem Agilität zählt. Natürlich könnte dies ein wenig verzerrt sein, da jeder marginale Anstieg der Agilität eine größere Bedeutung hat. Daher sollten Sie das Exponential durch etwas wie ein logistische Funktion .

Hoffe, das hilft!

    
templatetypedef 07.09.2011 23:04
quelle
6

Verwenden Sie Collections.sort () und stellen Sie einen Komparator bereit, der eine Kombination aus Zufallszahl und Flexibilität verwendet, um den Rang zu berechnen.

Hier ist eine Implementierung, die funktionieren würde. Beachten Sie, dass Player die einfachste mögliche Schnittstelle ist, die funktioniert:

%Vor%

Wichtig ist, dass der zufällige agile Score eines Spielers nach der Berechnung für alle späteren Vergleiche erneut verwendet werden muss. Diese Vergleichsklasse ist so konzipiert, dass sie nur einmal verwendet werden kann (die Karte muss zu Beginn ihrer Verwendung leer sein).

    
Bohemian 07.09.2011 22:58
quelle
2

Wenn Sie die Actor-Interna nicht berühren können, müssen Sie eine Art "Rolle" für jeden Akteur für eine vollständige Sortierung zuordnen (die wahrscheinlich viele zu vergleichende Aufrufe enthält), die aber bei der nächsten Sortierung vergessen wird.

In diesem Fall würde ich das tun:

%Vor%

Wenn Sie jetzt eine ArrayList von Actors sortieren möchten, erstellen Sie eine ArrayList von ActorComparaparates, sortieren Sie diese und erstellen Sie eine resultierende Liste der ActorComparaparates.

    
Cory Kendall 07.09.2011 23:39
quelle
1

Ein ganzes Beispiel mit einem TreeSet (ein SortedSet Implementierungen, die garantieren, dass die Elemente immer geordnet sind, mit einem Comparator in diesem Fall):

%Vor%     
Guido García 07.09.2011 23:10
quelle