Algorithmus für die Bestimmung von Tic Tac Toe Game Over
Ich geschrieben habe, ein Spiel von tic-tac-toe in Java, und meine aktuelle Methode der Bestimmung des Ende des Spiels Konten für die folgenden möglichen Szenarien für das Spiel über:
- Das Brett voll ist, und keine Gewinner hat doch schon erklärt: das Spiel ist ein Unentschieden.
- Kreuz gewonnen hat.
- Kreis gewonnen hat.
Leider, so zu tun, liest es durch eine vordefinierte Menge von diesen Szenarien aus einer Tabelle. Dies ist nicht unbedingt schlecht, wenn man bedenkt, dass es nur 9 Felder auf einem Brett, und so der Tisch ist etwas klein, aber gibt es eine bessere Algorithmische Weise zu bestimmen, wenn das Spiel vorbei ist? Die Feststellung, ob jemand gewonnen hat oder nicht, ist das Fleisch das problem, da die überprüfung, ob 9 Räume voll sind, ist trivial.
Den Tisch-Methode könnte die Lösung sein, aber wenn nicht, was ist? Auch, was ist, wenn die Bord waren nicht Größe n=9
? Was ist, wenn es ein viel größeres Brett, sagen n=16
n=25
und so weiter, wodurch sich die Anzahl der hintereinander Platzierten Elementen zu gewinnen, um sein x=4
x=5
usw? Einen Allgemeinen Algorithmus für alle n = { 9, 16, 25, 36 ... }
?
InformationsquelleAutor der Frage Ben Lakey | 2009-06-29
Du musst angemeldet sein, um einen Kommentar abzugeben.
Kennen Sie eine gewinnende Bewegung kann nur geschehen, nach X-oder O hat Ihren letzten Zug, so können Sie nur suchen, Zeile/Spalte mit optionaler diag, die darin enthalten sind, die sich bewegen, beschränken Sie Ihre Suche, wenn Sie versuchen, um zu bestimmen, eine gewinnen-board. Auch da gibt es eine Feste Anzahl von Zügen in ein Remis tic-tac-toe-Spiel, sobald der Letzte Schritt, wenn es nicht eine gewinnende Bewegung ist standardmäßig ein Unentschieden-Spiel.
edit: dieser code ist für ein n durch n Brett mit n in einer Reihe zu gewinnen (3x3-Brett requries 3 in einer Zeile, etc)
edit: code Hinzugefügt, um zu überprüfen, anti-diag, ich konnte nicht herausfinden, eine non-Schleife Weg, um festzustellen, ob der Punkt wurde auf die anti-diag-so thats, warum dieser Schritt fehlt
InformationsquelleAutor der Antwort Hardwareguy
können Sie ein Magisches Quadrat http://mathworld.wolfram.com/MagicSquare.htmlwenn jede Zeile, Spalte oder diag fügt bis zu 15, dann hat der Spieler gewonnen.
InformationsquelleAutor der Antwort adk
Dies ist ähnlich zu Osama ALASSIRY Antwortaber es handelt constant-Raum und linearer Zeit für linearer Raum und konstanter Zeit. Das heißt, es gibt keine Schleifen nach der Initialisierung.
Initialisieren ein paar
(0,0)
für jede Zeile, jeder Spalte und den beiden diagonalen (Diagonale & anti-Diagonale). Diese Paare repräsentieren die kumulierte(sum,sum)
der Stücke in der entsprechenden Zeile, Spalte oder Diagonale zu prüfen, wobeiWenn ein Spieler ein Stück, aktualisieren Sie die entsprechende Zeile pair-Mädchen Spalte-pair-Mädchen, und diagonal paarweise (wenn auf der diagonalen). Wenn irgendeine aktualisierte Zeile, Spalte oder Diagonale-pair-Mädchen gleich entweder
(n,0)
oder(0,n)
dann entweder A oder B gewonnen, beziehungsweise.Asymptotische Analyse:
Für den Speicher verwenden, verwenden Sie
4*(n+1)
zahlen.Übung: Können Sie sehen, wie testen für ein Unentschieden in O(1) Zeit pro Zug? Wenn dem so ist, können Sie am Ende das Spiel bereits früh auf ein Remis.
InformationsquelleAutor der Antwort CJ Gaconnet
Wie wäre es mit diesem pseudocode:
Nachdem ein Spieler legt ein Stück an der position (x,y):
Ich würde verwenden Sie ein array von char [n,n], mit O -, X-und Raum für leere.
InformationsquelleAutor der Antwort Osama Al-Maadeed
Hier ist meine Lösung, die ich geschrieben habe für ein Projekt an dem ich arbeite in javascript. Wenn Sie nichts dagegen haben, die Speicher Kosten von ein paar arrays es ist wahrscheinlich die Schnellste und einfachste Lösung, die Sie finden können. Es wird davon ausgegangen, Sie wissen, die position der letzten Bewegung.
InformationsquelleAutor der Antwort Jack Allan
Ich schrieb dies für meine C-Programmierung Klasse.
Ich bin Entsendung es, weil keines der anderen Beispiele, die hier gemacht werden, mit einer Größe rechteckigen Gitter, und eine beliebige Anzahl N-in-einer-Reihe aufeinanderfolgender Markierungen, um zu gewinnen.
Finden Sie mein Algorithmus, wie es ist, in der
checkWinner()
Funktion. Es spielt keine Magie benutzen, zahlen oder etwas Phantasie, um zu prüfen, ob ein Sieger, der es verwendet einfach vier for-Schleifen - Der code ist gut kommentiert, so dass ich ' ll lassen Sie es für sich selbst sprechen, denke ich.InformationsquelleAutor der Antwort mattR
Wenn das board n × n dann gibt es n Zeilen n Spalten und die 2 diagonalen. Überprüfen Sie jeden dieser für alle-X 's oder O' s, einen Sieger zu finden.
Wenn es dauert nur x < n aufeinander folgende Quadrate zu gewinnen, dann wird es ein wenig komplizierter. Die naheliegendste Lösung ist, um zu überprüfen jedes x × x Platz für einen Gewinner. Hier ist etwas code, der zeigt, dass.
(Ich wollte eigentlich nicht testen, dieser *hust*, aber es hat kompilieren auf dem ersten Versuch, yay me!)
InformationsquelleAutor der Antwort John Kugelman
Ich weiß nicht, Java auch, aber ich weiß, dass C, also versuchte ich adk ' s magic square Idee (zusammen mit Hardwareguy such-Einschränkung).
Kompiliert und die tests auch.
Das war lustig, danke!
Eigentlich, denken Sie daran, Sie brauchen nicht, ein Magisches Quadrat, nur eine Anzahl für jede Zeile/Spalte/Diagonale. Dies ist ein wenig leichter als die Verallgemeinerung eines magischen Quadrates zu
n
×n
Matrizen, da Sie gerade brauchen, um count zun
.InformationsquelleAutor der Antwort rampion
Ich wurde gebeten, die gleiche Frage in einem meiner interviews.
Meine Gedanken:
Initialisieren Sie die matrix mit 0.
Halten 3 arrays
1)sum_row (Größe n)
2) sum_column (Größe n)
3) Diagonale (Größe 2)
Für jede Bewegung von (X) dekrementiert das Feld Wert 1 und für jedes verschieben von (0) Inkrement um 1.
An jedem Punkt, wenn die Zeile/Spalte/Diagonale, die geändert wurde, in aktuelle Bewegung hat die Summe entweder -3 oder +3 bedeutet, dass jemand das Spiel gewonnen hat.
Für eine Attraktion, die wir verwenden können, obigen Ansatz zu halten, die moveCount variable.
Glaubst du, ich bin etwas fehlt ?
Edit: das Selbe kann verwendet werden, für die nxn-matrix. Summe sollte sogar noch +3 oder -3.
InformationsquelleAutor der Antwort Piyush Beli
nicht-Schleife Weg, um festzustellen, ob der Punkt wurde auf die anti-diag:
InformationsquelleAutor der Antwort Jeff
Machte ich einige Optimierungen in der Zeile, Spalte, Diagonale überprüft. Seine vor allem entschieden, in die erste verschachtelte Schleife, wenn wir überprüfen müssen, um eine bestimmte Spalte oder Diagonale. So vermeiden wir die überprüfung der Spalten oder diagonalen, Zeit zu sparen. Dies macht den großen Einfluss, wenn das board die Größe ist mehr und eine bedeutende Anzahl von Zellen, die nicht belegt sind.
Hier ist der java-code für, die.
InformationsquelleAutor der Antwort sanjiv
Ich bin spät dran, die party, aber ich wollte darauf hinweisen, ein Vorteil, den, die ich fand, um mit einem magic squarenämlich, dass es verwendet werden kann, um einen Verweis auf das Quadrat dazu führen würde, dass der Gewinn oder der Verlust auf den nächsten Zug, anstatt nur verwendet, um zu berechnen, Wann ein Spiel vorbei ist.
Nehmen Sie dieses Magische Quadrat:
Richten Sie zuerst ein
scores
array wird erhöht, jedes mal ein Umzug. Sehen diese Antwort für details. Nun, wenn wir illegal spielen Sie X zweimal in Folge bei [0,0] und [0,1], dann ist diescores
array sieht wie folgt aus:Und das board sieht wie folgt aus:
Dann müssen wir alle tun, um zu bekommen eine Referenz auf dem Platz um zu gewinnen/block auf:
In der Realität, die Umsetzung erfordert einige zusätzliche tricks, wie Umgang mit numerierten Tasten (in JavaScript), aber ich fand es ziemlich einfach und genossen die Freizeit-math.
InformationsquelleAutor der Antwort gwg
Ich mag diesen Algorithmus, da er verwendet eine 1x9 vs 3x3 Vertretung des Vorstandes.
InformationsquelleAutor der Antwort Scott Duchin
Andere Möglichkeit: erstellen Sie Ihre Tabelle mit code. Bis auf Symmetrie gibt es nur drei Möglichkeiten zu gewinnen: die edge-Reihe, mittlere Reihe, oder Diagonale. Nehmen Sie diese drei, und drehen Sie Sie um jede mögliche Weise:
Diese Symmetrien haben kann, mehr verwendet in der Spiele-spielen-code: wenn du ein board hast du schon gesehen, eine gedrehte version, können Sie einfach den zwischengespeicherten Wert oder den besten Zug aus, dass man (und unrotate es wieder). Dies ist in der Regel viel schneller als die Bewertung der Spiel-Teilbaum.
(Spiegeln Links und rechts können helfen, die gleiche Art und Weise; es war nicht nötig, weil hier die Menge der Rotationen der gewinnenden Muster ist Spiegel-symmetrisch.)
InformationsquelleAutor der Antwort Darius Bacon
Hier ist eine Lösung, die ich kam mit, dieser speichert die Symbole chars und nutzt die char-int-Wert, um herauszufinden, ob X oder O gewonnen hat (Blick auf die Schiedsrichter-code)
Auch hier sind meine unit-tests zu validieren, es funktioniert tatsächlich
Vollständige Lösung: https://github.com/nashjain/tictactoe/tree/master/java
InformationsquelleAutor der Antwort Naresh Jain
Wie wäre es mit einem folgenden Ansatz für die 9 slots? Erklären 9 integer-Variablen für eine 3x3 matrix (a1,a2,....a9), wo a1,a2,a3 darstellen, Zeile-1 und a1,a4,a7 würde column-1 (Sie erhalten die Idee). Verwenden Sie '1', um anzugeben, Spieler-1 und '2', um anzugeben, Spieler-2.
Gibt es 8 mögliche Gewinn Kombinationen:
Gewinnen-1: a1+a2+a3 (Antwort könnte sein, 3 oder 6, basierend auf dem Spieler gewonnen)
Win-2: a4+a5+a6
Gewinnen-3: a7+a8+a9
Gewinnen-4: a1+a4+a7
....
Win-7: a1+a5+a9
Win-8: a3+a5+a7
Nun wissen wir, dass wenn der Spieler durchquert man a1 dann müssen wir uns beleben, die Summe von 3 Variablen: Win-1, Win-4 und Win-7. Welche " Win-?' Variablen erreicht 3-oder 6-erste gewinnt das Spiel. Wenn die Win-1 variable 6 erreicht zuerst, dann Spieler 2 gewinnt.
Verstehe ich, dass diese Lösung nicht skalierbar leicht.
InformationsquelleAutor der Antwort user3071398
Konstanter Zeit O(8), im Durchschnitt 4 kurze UND. Spieler = die kurze Nummer. Benötigt zusätzliche Kontrollen, um sicher zu bewegen gilt.
InformationsquelleAutor der Antwort alexsalo
Dies ist eine wirklich einfache Möglichkeit zu überprüfen.
}
InformationsquelleAutor der Antwort lusion
Wenn du boarder Feld 5*5 für die unter anderem ich als Nächstes verwendet die Methode der überprüfung:
Ich denke, es ist mehr klar, aber ist wahrscheinlich nicht der optimale Weg.
InformationsquelleAutor der Antwort Aleksei Moshkov
Entwickelte ich einen Algorithmus für diese als Teil eines wissenschaftlichen Projekts einmal.
Dass Sie im Grunde rekursiv aufteilen der Platte in einer Reihe von überlappenden 2x2 rects, die Prüfung der verschiedenen möglichen Kombinationen für den Gewinn auf ein 2x2-Quadrat.
Es ist langsam, aber es hat den Vorteil der Arbeit auf jede Größe der Platte mit einem ziemlich linearen Speicherbedarf.
Ich wünschte, ich könnte meine Implementierung
InformationsquelleAutor der Antwort bgw