Spiel des Lebens: Wie können sich "Entitäten" parallel entwickeln?

7

Ok der Titel ist nicht klar, hier ist was ich meine.

Ich programmiere eine Art Spiel (wie das Spiel des Lebens). Zum Beispiel gibt es Tiere (jedes Tier ist eine Java-Instanz einer Klasse).

All diese Tiere sind auf einer Karte und all diese " Welt " entwickelt sich bei jedem "Zug".

Diese Tiere können bei jeder Drehung Aktionen ausführen. Beispiel: ein Wolf tötet ein Schaf .

Aber ich habe Schwierigkeiten beim "Weg", diese Evolution zwischen den Zuständen zu machen, weil das Ergebnis von der Reihenfolge abhängt, die ich durch die Tiere durchlaufe.

Beispiel:

  • Wolf zuerst : Der Wolf tötet die Schafe (dann ist das Schaf tot, also keine Aktion)
  • Schaf zuerst : das Schaf frisst etwas Gras und DANN (macht den Wolf) der Wolf tötet das Schaf

Wie kann ich dieses Problem lösen?

Multithreading? (Aber ich werde viele Tiere haben, wie 1000 und noch mehr ...). Gibt es einen Algorithmus, einen "Weg", um das zu tun?

Danke

    
Matthieu Napoli 14.09.2010, 22:44
quelle

9 Antworten

1

Ich denke, es ist nur möglich, dass sich Entitäten in sehr einfachen Szenarien parallel entwickeln (Conways Leben als Beispiel) - für deine "Wolf-Schaf-Gras" -Welt wird es immer komplexer, je mehr du darüber nachdenkst:

  • Betrachten Sie eine Situation mit zwei Wölfen und einem Schaf. Wolf Eins beschließt, die Schafe zu essen; Wolf Zwei beschließt, das Schaf zu essen - wie würdest du entscheiden, welches Schaf du bekommst (lass uns annehmen, dass Essen eine atomare Operation ist - Wölfe können ihre Mahlzeiten nicht teilen). Also musst du dich noch für eine Bestellung entscheiden, also Wolf Eins bekommt ein Schaf und Wolf Zwei bekommt nichts (was für die Wolf Zwei völlig unerwartet ist - es gab vor einer Sekunde ein Schaf, es öffnet seinen Mund und - BAM! - da ist nichts)

  • Es gibt zwei Wölfe und zwei Schafe; Beide "Attraktivitäten" von Schafen sind für beide Wölfe gleich, daher wählen sie ihre Beute nach dem Zufallsprinzip aus. Leider wählen sie das gleiche Schaf, Wolf Eins isst Schaf Eins, Wolf Zwei versucht auch Schaf Eins zu essen aber es verschwindet magisch direkt unter seiner Nase. Ende der Runde. In der nächsten Runde läuft Sheep Two weg, Wolf Two verhungert - was völlig unlogisch ist.

Ich denke also, dass ich einfach über die Liste der Tiere iteriere und eine Methode für jedes Tier aufrufe, das eine atomare Aktion ausführt, was zu einem logischeren Universum führt. Wenn du befürchtest, dass Tiere, die früher hervorgebracht wurden, einen unfairen Vorteil gegenüber denen haben, die später hervorgebracht wurden, kannst du die Liste der Tiere vor jedem Zug zufügen - so isst dein Schaf in deinem Beispiel Gras und wird dann vom Wolf gefressen. oder der Wolf frisst es, bevor es Gras fressen kann. C'est la vie.

    
Sergey 15.09.2010, 01:27
quelle
10

Du solltest die Drehungen richtig modellieren, dh jedes Tier muss basierend auf dem aktuellen Zustand der Welt an der Reihe sein, damit die Ergebnisse der Aktion aktualisiert werden der nächste Zustand der Welt, nicht der aktuelle. Ie.

  1. Im aktuellen Schritt frisst das Schaf etwas Gras, und der Wolf tötet es.
  2. Im nächsten Zustand der Welt gibt es einen zufriedenen Wolf und kein Schaf (oder einen Schafskadaver - abhängig von Ihrem Modell).

Auf diese Weise beeinflusst die Reihenfolge der Auswertung das Ergebnis nicht, was die Möglichkeit eröffnet, z.B. parallelisieren Sie die Ausführung, vorzugsweise mit FutureTask s und a ThreadPoolExecutor .

    
Péter Török 14.09.2010 22:50
quelle
4

Thread-Nebenläufigkeit ist hier nicht das Hauptproblem. Ich glaube, dass das richtige Modell jedem Unternehmen erlauben sollte, sich in der aktuellen Runde für eine Aktion zu entscheiden. Um den Spielstatus bei der nächsten Runde zu bestimmen, sollten Sie die Aktionen ausführen und Konflikte bei Bedarf lösen. Sie sollten Regeln für die Lösung aller Arten von "widersprüchlichen" Aktionskombinationen von zwei verschiedenen Spielern festlegen.

    
Eyal Schneider 14.09.2010 23:05
quelle
3

Oh, Sie wollen nicht in Multi-Threading, die Dinge werden noch verwirrender.

In diesem Fall iteriere alle Tiere und lass sie ihre Aktion wählen. DANN aktualisieren Sie die Karte.

    
Rodney Gitzel 14.09.2010 22:52
quelle
1

Wenn Sie einen zentralen Manager hätten, der Benachrichtigungen empfangen und ausgeben könnte, könnten Sie ein Beobachtermuster verwenden. Jedes Mal, wenn sich eine Kurve entwickelt, melden die Tiere, wo sie sind. Der Manager benachrichtigt, wer anwesend ist und führt die Methode eat() entsprechend dem Kontext aus. Wenn sie mit dem Essen fertig sind, geben sie den Manager an, der ihnen wiederum sagt, was zu tun ist (z. B. notify() )

    
Escualo 14.09.2010 22:58
quelle
1

Es klingt, als wolltest du, dass sich die Welt jedes Mal genauso entwickelt wie Conways Leben. Im Leben betrachten Sie jede Zelle und berechnen, was das Ergebnis für sie sein würde, basierend auf dem vorherigen -Zustand. Wenn die Zelle zwei Nachbarn hat, wird sie für die nächste Generation leben, egal ob diese Nachbarn in der nächsten Generation da sind. Der ursprüngliche Zustand sollte schreibgeschützt sein und die Regeln sollten funktionieren, egal was passiert.

Zum Beispiel, was ist, wenn du zwei Wölfe in der Nähe eines Schafes hast, würden sie beide es essen, oder nur eines? Wenn nur einer, dann brauchst du eine Regel, für die man die Schafe essen soll und die andere muss das wissen. Du könntest den umgekehrten Weg gehen, d. H. Schau dir die Schafe an und finde ein Tier, das es essen würde. Nehmen wir an, Sie wollen nur einen Wolf, der die Schafe isst, und Sie sagen, dass der Wolf mit der niedrigsten 'Y' Koordinate die Schafe bekommt, oder die niedrigste 'X' Koordinate, wenn es zwei Wölfe mit dem gleichen 'Y' gibt. Wenn Sie einen Wolf bearbeiten, müssen Sie sicherstellen, dass kein anderer Wolf die Schafe zuerst frisst. Das könnte verwirrender werden, weil das vielleicht ein anderes Schaf in der Nähe hätte, das es essen würde, also würde es das erste nicht essen ...

Der einfachste Weg wäre zu sagen, dass alle Tiere ihre Aktionen ausführen können, egal was mit ihnen in der Evolution zur nächsten Runde passiert oder was ein anderes Tier tut. Wenn ein Schaf von drei Wölfen umgeben ist, wird es in der nächsten Runde tot sein und alle Wölfe werden an der Mahlzeit teilnehmen. Wenn Gras neben einem Schaf ist, werden die Schafe es auch essen, wenn das Schaf von Wölfen umgeben ist. Für die Wölfe werden sie alle in dieser Runde gefüttert, weil sie neben einem Schaf waren.

%Vor%     
Jason Goemaat 15.09.2010 00:25
quelle
0

Von meinem Kopf weg könnten Sie so etwas tun:

Haben Sie ein einzelnes World-Objekt, das eine Liste von Player-Objekten verwaltet. Der Spieler hat die folgenden Methoden:

Spieler

  • public void takeTurn (Weltwelt)
  • public boolean isDead ()
  • public void kill ()

Wenn die World-Instanz zu jedem Spieler gelangt, fragt sie, ob sie tot ist. Wenn nicht, wird die takeTurn-Methode aufgerufen. Oder, takeTurn kann isDead () intern aufrufen und nur zurückgeben, wenn dies der Fall ist. Wenn Sie einen anderen Spieler (oder sich selbst) töten, rufen Sie einfach die Kill-Methode des Spielers auf.

Wenn Sie die Welt an takeTurn weitergeben, müssen Sie nur einen Rückruf durchführen, um den Status der Welt zu aktualisieren.

    
Javid Jamae 14.09.2010 23:07
quelle
0

Eine Möglichkeit, dies zu tun ist:

  1. Lassen Sie die Schafe ihre Handlungen ausführen und notieren Sie sie im nächsten Schritt.
  2. Aktualisieren Sie das Board für die Sheeps-Aktionen
  3. Führe jede Wolfsaktion aus und notiere sie im nächsten Schritt.
  4. Aktualisiere die Tafel für die Wolfsaktionen.

Zwei Wege zwei Multithread sind das:

  • Teilen Sie das Board in verschiedene Regionen und weisen Sie jedem Thread eine Region zu. Sie werden Probleme haben herauszufinden, wie Sie es von einer Region in eine andere verschieben können.

  • Der andere Weg könnte sein, die Schleife durch Kreaturen zu verschiedenen Threads zu unterbrechen. zB

    for(w=THREAD_NUM; w<NUM_OF_WOLVES; w+=NUM_OF_THREADS) { w.doAction(); }

mikek3332002 14.09.2010 23:10
quelle
0

Vielleicht könntest du das völlig zufällig machen.

Erstes zufälliges Beispiel: Schaf frisst das Gras und dann frisst der Wolf das Schaf (Schaf - & gt; Wolf)

Zweites zufälliges Beispiel: Wolf frisst die Schafe, weil das arme Ding zu langsam war, um ins Gras zu kommen (Wolf - & gt; /)

Ist die reale Welt deterministisch? :)

    
sventevit 15.09.2010 15:32
quelle