Minimax erklärt für ein idiot
Ich habe verschwendet meine gesamten Tag versuchen, verwenden Sie das minimax-Algorithmus, um eine unschlagbare tictactoe KI. Habe ich etwas verpasst auf dem Weg (Gehirn frittiert).
Ich bin nicht auf der Suche für den code hier, nur besser zu erklären, wo ich schief ging.
Hier ist meine aktuelle code (der minimax-Methode immer 0 zurück, aus irgendeinem Grund):
from copy import deepcopy
class Square(object):
def __init__(self, player=None):
self.player = player
@property
def empty(self):
return self.player is None
class Board(object):
winning_combos = (
[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8],
[0, 4, 8], [2, 4, 6],
)
def __init__(self, squares={}):
self.squares = squares
for i in range(9):
if self.squares.get(i) is None:
self.squares[i] = Square()
@property
def available_moves(self):
return [k for k, v in self.squares.iteritems() if v.empty]
@property
def complete(self):
for combo in self.winning_combos:
combo_available = True
for pos in combo:
if not pos in self.available_moves:
combo_available = False
if combo_available:
return self.winner is not None
return True
@property
def player_won(self):
return self.winner == 'X'
@property
def computer_won(self):
return self.winner == 'O'
@property
def tied(self):
return self.complete == True and self.winner is None
@property
def winner(self):
for player in ('X', 'O'):
positions = self.get_squares(player)
for combo in self.winning_combos:
win = True
for pos in combo:
if pos not in positions:
win = False
if win:
return player
return None
@property
def heuristic(self):
if self.player_won:
return -1
elif self.tied:
return 0
elif self.computer_won:
return 1
def get_squares(self, player):
return [k for k,v in self.squares.iteritems() if v.player == player]
def make_move(self, position, player):
self.squares[position] = Square(player)
def minimax(self, node, player):
if node.complete:
return node.heuristic
a = -1e10000
for move in node.available_moves:
child = deepcopy(node)
child.make_move(move, player)
a = max([a, -self.minimax(child, get_enemy(player))])
return a
def get_enemy(player):
if player == 'X':
return 'O'
return 'X'
InformationsquelleAutor der Frage orokusaki | 2010-10-18
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihre komplette Funktion nicht wie erwartet funktioniert, wodurch Spiele deklariert werden gebunden, bevor etwas passieren kann. Zum Beispiel, betrachten Sie dieses setup:
Sollte dies ein Gewinn für den computer auf den nächsten zu bewegen. Stattdessen sagt er, das Spiel gebunden ist.
Das problem ist, dass Sie Ihre Logik in völliger, jetzt, überprüft, um zu sehen, wenn alle Quadrate in einer combo sind kostenlos. Wenn einer von Ihnen nicht, es wird davon ausgegangen, dass diese combo kann nicht gewonnen werden. Was es braucht, zu tun ist, überprüfen Sie, ob alle Positionen in diesem Kombinationsfeld sind belegt, und so lange, wie alle diese combos sind entweder Keine oder die gleichen Spieler, die combo sollte berücksichtigt werden, weiterhin zur Verfügung.
z.B.
Nun, dass ich richtig getestet, die mit dem aktualisierten code, ich bin immer das erwartete Resultat auf dieser test-Fall:
InformationsquelleAutor der Antwort Conspicuous Compiler
Schritt 1: Bauen Sie Ihr Spiel Baum
Ausgehend von dem aktuellen board erzeugen alle möglichen Züge der Gegner machen.
Dann für jeden von diesen erzeugen Sie alle möglichen Züge, die Sie machen können.
Für Tic-Tac-Toe einfach weiter, bis niemand spielen kann. In anderen spielen werden Sie in der Regel zu stoppen, nachdem eine bestimmte Zeit oder Tiefe.
Dieser sieht aus wie ein Baum, zeichne es dir auf ein Stück Papier, aktuellen board an der Oberseite, alle Gegner bewegt sich eine Schicht unterhalb, alle Ihre mögliche Schritte der Reaktion einer Schicht unten usw.
Schritt 2: Markiert alle Bretter an der Unterseite des Baumes
Für ein einfaches Spiel wie Tic-Tac-Toe stellen Sie die Punktzahl 0, wenn Sie verlieren, Band 50, 100 zu gewinnen.
Schritt 3: übertragen Sie die Kerbe oben auf dem Baum
Dies ist, wo die min-max ins Spiel kommen. Die Punktzahl eines zuvor unscored board hängt davon ab, seine Kinder und wer bekommt zu spielen. Angenommen du und dein Gegner wählen immer das beste möglich zu verschieben, in dem gegebenen Zustand. Der beste Zug für den Gegner ist der Zug, der gibt Sie die schlechteste Bewertung. Ebenso können Sie Ihre besten bewegen, ist die Bewegung, die Ihnen die höchste Punktzahl. Im Falle der Gegner an der Reihe ist, wählen Sie das Kind mit der Mindestpunktzahl (maximiert seinen nutzen). Wenn es an der Reihe ist, vorausgesetzt, dass Sie machen das beste möglich zu bewegen, so dass Sie wählen die maximale.
Schritt 4: Wählen Sie Ihre besten bewegen
Spielen Sie jetzt das verschieben, dass die Ergebnisse in die beste propagiert wird-score unter all deinen möglichen spielt ab der aktuellen position.
Versuchen Sie es auf ein Stück Papier, wenn ausgehend von einem leeren Brett ist zu viel für Sie beginnen mit einigen advanced Tic-Tac-Toe position.
Mit Rekursion:
Sehr Häufig kann dies vereinfacht werden durch die Verwendung von Rekursion. Das "scoring" - Funktion rekursiv aufgerufen wird bei jeder Tiefe und je nachdem, ob oder nicht die Tiefe gerade oder ungerade ist, es wählen Sie max oder min bzw. für alle möglichen Züge. Wenn keine Spielzüge mehr möglich sind, es wertet die statische Partitur des Vorstandes. Rekursive Lösungen (z.B. das Beispiel-code) kann ein bisschen schwieriger zu fassen.
InformationsquelleAutor der Antwort Guy Sirton
Wie Sie bereits wissen, die Idee von Minimax ist die Tiefe Suche nach dem besten Wert, vorausgesetzt, der Gegner spielt immer der Umzug mit dem schlechtesten Wert (schlechteste für uns, also für Sie am besten ist).
Die Idee ist, Sie versuchen, geben Sie einen Wert für jede position. Die position, wo Sie verlieren, ist negativ (wir wollen das nicht) und die position, wo Sie gewinnen, ist positiv. Sie nehme an, Sie wird immer versuchen, für die höchste Wert-position, sondern Sie übernehmen auch die Gegner werden immer darauf abzielen, den niedrigsten Wert position, die hat das schlechteste Ergebnis für uns, und das beste für Sie ist (Sie gewinnen, wir verlieren). So setzte Sie sich in Ihre Schuhe, versuchen zu spielen, so gut wie Sie können, wie Sie sind, und annehmen, Sie wird das tun.
Also, wenn Sie herausfinden, Sie haben möglich zwei Züge, indem Sie Ihnen die Wahl, zu gewinnen oder zu verlieren, was in einem draw wie auch immer, Sie nehme an, Sie gehen für die Bewegung, der Sie gewinnen, wenn Sie lassen Sie Sie tun. So ist es besser zu gehen für die Auslosung.
Nun für eine "Algorithmische" anzeigen.
Stellen Sie sich Ihr grid ist fast voll, außer für die zwei möglichen Positionen.
Überlegen Sie, was passiert, wenn Sie spielen die erste :
Die Gegner spielen die anderen. Es ist Ihr nur möglich bewegen, so haben wir nicht zu berücksichtigen, andere Züge aus. Betrachten Sie das Ergebnis, verknüpfen Sie einen resultierenden Wert ( + ∞ , wenn gewonnen, 0, wenn das draw -∞, wenn Sie verloren gehen : für tic tac toe können Sie vertreten, diejenigen, die als +1 0 und -1).
Betrachten wir nun, was passiert, wenn Sie spielen die zweite :
(hier dasselbe, der Gegner hat nur einen Zug, Blick auf die daraus resultierende position, der Wert der position).
Müssen Sie wählen Sie zwischen zwei Zügen. Es ist unsere Bewegung, so wollen wir das beste Ergebnis (dies ist das "max" im minimax). Wählen Sie die mit dem höheren Ergebnis als unsere "beste" zu bewegen. Dass es für das "2 bewegt sich vom Ende" - Beispiel.
Nun stellen Sie sich vor, Sie haben nicht 2, sondern 3 nach Links verschoben.
Das Prinzip ist das gleiche, Sie wollen einen Wert zuweisen, der auf jedes der 3 möglichen Züge, so dass Sie das beste zu wählen.
So dass Sie beginnen mit der Betrachtung eines der drei bewegt sich.
Sie sind jetzt in der situation vor, mit nur 2 möglichen Züge, aber es ist der Gegner an der Reihe. Dann starten Sie über eine der möglichen Züge für den Gegner, wie wir es oben. Sie haben ebenfalls Blick auf jede der möglichen Züge, und finden Sie ein Ergebnis-Wert für beide von Ihnen. Es ist der Gegner bewegen, so nehmen wir an, Sie spielen das "beste" zu bewegen für Sie, derjenige mit der schlechtesten Wahlbeteiligung für uns, so ist derjenige mit dem geringeren Wert (dies ist der "min" im minimax). Ignorieren Sie die andere ; nehme an, Sie spielen, was Sie fand, war am besten für Sie trotzdem. Dies ist, was Ihr Umzug wird der Ertrag, so ist es der Wert, den Sie zuweisen, um die erste der drei bewegt sich.
Nun Sie betrachten jeder der anderen möglichen 2 bewegt. Geben Sie Ihnen einen Wert in der gleichen Weise. Und von Ihren drei Zügen, die Sie wählen, die mit dem max-Wert.
Betrachten wir nun, was passiert mit 4 bewegt. Für jedes Ihrer 4 bewegt, schauen Sie, was passiert, für die 3 Bewegungen Ihrer Gegner, und für jeden von Ihnen werden Sie annehmen, Sie wählen die, die Ihnen das Schlimmste mögliche Ergebnis zu den besten von den 2 verbleibenden Züge für Sie.
Sehen Sie, wo dieser Weg ist. Zu bewerten, fahre n Schritte vom Ende, schaut Euch an was passieren kann, für jeden der n möglichen Züge, die versuchen, einen Wert zu geben, so dass Sie können wählen Sie die beste. In den Prozess, werden Sie haben, um zu versuchen finden Sie den besten Zug für den Spieler, der spielt bei n-1 : der Gegner, und wählen Sie den Schritt mit dem geringeren Wert. In den Prozess der Bewertung der n-1 bewegen, Sie haben die Wahl zwischen den möglichen n-2 bewegt, der wird unser sein, und wir nehmen an, wir spielen so gut wir können zu diesem Schritt. Etc.
Dies ist der Grund, warum dieser Algorithmus ist inhärent rekursiv. Was n bei Schritt n bewerten Sie alle möglichen Schritte, die bei n-1. Spülen und wiederholen.
Für tic-tac-toe heutigen Maschinen sind weit mächtig genug, um zu berechnen, alle möglichen Ergebnisse Recht aus dem start des Spiels, weil es nur ein paar hundert von Ihnen. Wenn Sie schauen, um es zu implementieren, für ein komplexeres Spiel, haben Sie zu stoppen computing an einem gewissen Punkt, denn es wird zu lange dauern. Also für ein Komplexes Spiel, müssen Sie auch code schreiben, der entscheidet, ob weiterhin auf der Suche nach allen möglichen nächsten bewegt oder um zu versuchen, geben Sie einen Wert für die position und die Rückkehr zu früh. Es heißt, Sie haben auch zu berechnen, einen Wert für position ein, ist nicht endgültig - zum Beispiel für Schach würde man berücksichtigen, wie viel material jeder Gegner hat auf dem board, die unmittelbaren Möglichkeiten zu überprüfen, ohne sich fortzupflanzen, wie viele Kacheln die du kontrollierst, und alle, die es nicht trivial.
InformationsquelleAutor der Antwort Jean