Ich schreibe einen Minimax-Algorithmus für ein Spiel in Java und verändere den Spielzustand aus Geschwindigkeitsgründen, während ich rekursiv durch den Entscheidungsbaum gehe. Dies beinhaltet jedoch die Änderung der Liste der Züge, die ich überspringe.
%Vor% Die Methode board.move()
mutiert die ArrayList legalMoves
, aber takeBack(1)
bringt sie in ihren ursprünglichen Zustand zurück. Könnte das irgendwelche Probleme verursachen?
Mit einem Wort, ja.
Sie geben nicht den Typ von board.legalMoves
an. Du sagst, dass es Array ist, aber es kann nicht sein, da du isEmpty()
darauf anrufst. Ich vermute deshalb, dass du ArrayList
meinst. Wenn das der Fall ist, ist die Dokumentation ziemlich klar:
Die Iteratoren, die von den Methoden
iterator
undlistIterator
dieser Klasse zurückgegeben werden, sind fail-fast: wenn die Liste zu irgendeinem Zeitpunkt nach der Erstellung des Iterators strukturell verändert wird, außer durch die eigeneremove
oder% des Iterators. co_de% Methoden, der Iterator wird einadd
werfen. Angesichts der gleichzeitigen Modifikation versagt der Iterator daher schnell und sauber, anstatt willkürliches, nicht-deterministisches Verhalten zu einem unbestimmten Zeitpunkt in der Zukunft zu riskieren.
Ich sehe zwei Möglichkeiten dafür:
1) Strukturelle Änderungen vermeiden. Mit anderen Worten, es ist in Ordnung, die Werte der Elemente zu ändern, aber es ist nicht in Ordnung, Elemente hinzuzufügen / zu entfernen.
2) Iteriere über den ConcurrentModificationException
mithilfe von Indizes:
Ja, das kannst du, aber es ist gefährlich. Ich schlage vor, den Minmax-Algorithmus in eine neue Klasse zu verschieben und die Daten zur Analyse in den Konstruktor zu übergeben.
Nun können Sie die Daten einmal im Konstruktor kopieren und die Methoden können auf der Kopie ausgeführt werden. Der Algorithmus kann nun die Daten beliebig verändern, andere Teile des Spiels oder andere Threads nicht beeinflussen. Wenn Sie Probleme haben, müssen sie aus dem Code einer Klasse stammen.
Das allgemeine Ziel besteht darin, jedem modifizierenden Teil des Codes eine Kopie der Daten zu geben, die er benötigt, um Abhängigkeiten zu trennen, die Probleme verursachen können.