0

Ich programmiere eine Schach-KI mit einem Alpha-Beta-Bereinigungsalgorithmus, der bei fester Tiefe funktioniert. Ich war ziemlich überrascht zu sehen, dass es durch das Einstellen der KI auf eine höhere Tiefe noch schlimmer wurde. Aber ich denke, ich habe es so verstanden.Wie man Bewegungsreihenfolge in Schachbrettauswertung berücksichtigt

Es funktioniert derzeit so: Alle Positionen werden aufgelistet, und für jede von ihnen werden alle anderen Positionen aufgelistet und so weiter ... Bis die festgelegte Tiefe erreicht ist: Die Karte wird durch Überprüfen der Teile bewertet vorhanden sind und einen Wert für jeden Stücktyp festlegen. Dann sprudelt der Wert unter Verwendung des Minimax-Algorithmus mit Alpha-Beta bis zur Wurzel. Aber ich muss den Bewegungsauftrag berücksichtigen. Zum Beispiel gibt es zwei Möglichkeiten, eine Schachmatt in 2 Zügen und eine in 7 Zügen, dann muss die erste ausgewählt werden. Das gleiche gilt für eine Dame in 3 oder 6 Zügen. Da ich aber die Platine nur an den tiefsten Knoten auswerte und nur die Platine als Auswertungsergebnis überprüfe, weiß sie nicht, was die vorherigen Züge waren.

Ich bin mir sicher, dass es eine bessere Möglichkeit gibt, das Spiel zu bewerten, das für die Art verantwortlich ist, wie die Teile durch die Suche bewegt wurden.

EDIT: Ich habe herausgefunden, warum es seltsam spielte. Wenn ich nach Moves suchte (Tiefe 5), endete es mit einer AI-Bewegung (MAX-Knoten-Level). Auf diese Weise zählte es Bewegungen wie das Nehmen eines Ritters mit einem Turm, auch wenn es Letzteres angreifbar machte (der Algorithmus kann es nicht sehen, weil es nicht tiefer sucht). Also änderte ich das und ich setze die Tiefe auf 6, also endet es mit einer MIN-Knoten-Ebene. Seine Bewegungen machen jetzt mehr Sinn, da es sich tatsächlich revanchiert, wenn es angegriffen wird (was es manchmal nicht getan hat und stattdessen einen dummen Zug gespielt hat).

Allerdings ist es jetzt defensiver als je zuvor und spielt nicht: Es bewegt seinen Springer, dann bewegt er es zurück an die Stelle, an der es vorher war, und deshalb verliert es am Ende. Meine Bewertung ist sehr Standard, nur das Vorhandensein von Stücken ist wichtig für den Knotenwert, so dass es frei ist, die gewünschte Strategie auszuwählen, ohne sie dazu zu zwingen, Dinge zu tun, die sie nicht benötigt. Ist das ein normales Verhalten für meinen Algorithmus? Ist das ein Zeichen dafür, dass mein Alpha-Beta-Algorithmus schlecht implementiert ist oder bei einer solchen Auswertefunktion völlig normal ist?

+0

Alpha-Beta benötigt Informationen über zuvor ausgewerteten Zeilen. Nicht die Züge selbst, sondern die Werte _alpha_ und _beta_. Im Englischen bedeuten diese ungefähr: "Ich kann bereits eine Partitur von _alpha_ mit einer vorherigen Linie erzwingen. Wenn mein Gegner also eine Verteidigung hat, die zu einer niedrigeren Punktzahl als _alpha_ führt, kann ich aufhören, alle verbleibenden Züge in dieser Position zu bewerten." Wenn Sie also einen Partner in 2 gefunden haben, propagieren Sie diesen Wert für den Rest der Analyse und verwenden ihn, um den Partner in 7 zu löschen. –

+0

@ C.Frâncu Okay Ich stimme zu, dass es der Algorithmus sein sollte. Aber wenn ich mein Board nur in der höchsten Tiefe auswerte (und deshalb in dieser Tiefe nach Matches suche), kann es keinen Partner in 2 finden, da es nur das Ergebnis von zB 8 Moves sieht (wenn die Tiefe eingestellt ist) zu 8). Und das ist ein Problem für den Algorithmus ist nur die Paarung zu verzögern (da nach jedem Zug kann es tiefer in der Suche gehen). – Gradapin

+0

Das hängt von Ihrer Implementierung ab. Im Idealfall sollten Sie in der Tiefe 2 erkennen, dass das Spiel, da es keine legalen Züge gibt, irgendwie enden muss (entweder Kumpel oder Pattsituation). Was macht Ihr Algorithmus, wenn die Bewegungserzeugung keine Züge zurückgibt? –

Antwort

1

Wenn Sie den kürzesten Pfad zu einem Gewinn auswählen möchten, möchten Sie wahrscheinlich auch den längsten Pfad zu einem Verlust auswählen. Wenn Sie dies in der Auswertungsfunktion berücksichtigen würden, müssten Sie die Pfadlänge zusammen mit dem Score angeben und separate Auswertungsfunktionen für min und max haben. Es ist eine Menge komplexer und verwirrender Overhead.

Der Standard Weg zur Lösung dieses Problems ist mit einer iterativen Vertiefung Ansatz für die Bewertung. Zuerst suchst du tief genug für 1 Zug für alle Spieler, dann führst du die gesamte Suche erneut durch und suchst 2 Züge für jeden Spieler, usw., bis du keine Zeit mehr hast. Wenn du in 2 Zügen einen Gewinn findest, hörst du auf zu suchen und du wirst nie in die 7-Züge-Situation kommen. Dies löst auch das Problem, ungewöhnliche Tiefen zu suchen und seltsame Auswertungen zu erhalten. Es hat viele andere Vorteile, wie immer einen Umzug bereit zu gehen, wenn Sie keine Zeit mehr haben, und einige wichtige algorithmische Verbesserungen, weil Sie den Overhead der Verfolgung besuchter Zustände nicht benötigen.

Wie für das defensive Spiel, das ist ein bisschen der Horizont-Effekt und ein bisschen der Bewertungsfunktion. Wenn Sie eine perfekte Bewertungsfunktion haben, muss der Algorithmus nur eine Bewegung tief sehen. Wenn es nicht perfekt ist (und es nicht ist), dann müssen Sie viel tiefer in die Suche gehen. Zuletzt überprüfte ich, dass Algorithmen, die auf Ihrem Laptop laufen und etwa 8 Lagen tief sehen (eine Schicht ist 1 Zug pro Spieler), mit starken Menschen mithalten können.

0

Damit das Programm das kürzeste Schachmatt auswählen kann, besteht der Standardansatz darin, Partnern, die näher am Stamm auftreten, einen höheren Wert zuzuweisen. Natürlich müssen Sie Schachkameraden erkennen und ihnen Punkte geben.

Auch, von dem, was Sie beschreiben, benötigen Sie eine Ruhe-Suche.

All dies (und vieles mehr) wird im Schachprogramm Wiki erklärt. Sie sollten es auschecken: https://chessprogramming.wikispaces.com/Checkmate#MateScore https://chessprogramming.wikispaces.com/Quiescence+Search