Jeder erkennt, dass Tic Tac Toe ein gelöstes Spiel ist. Die Misère-Version von only-Xs bietet jedoch eine interessante Alternative.
In dieser Version des Spiels spielen beide Spieler Xs auf dem Brett und versuchen zu vermeiden, drei in einer Reihe zu machen. Wenn Sie mehr darüber erfahren möchten, hat Numberphile ein schönes Video zu diesem Konzept.
Spielen Sie mit einem Brett aus Misère Crosses einen optimalen Zug.
Eine Tafel besteht aus drei Zeilen mit jeweils drei Zeichen, die X
oder sind . Somit:
X X
X
XX
ist eine gültige Tafel. Sie können dies in jedem geeigneten Format verwenden, solange Ihre Eingabe und Ausgabe dasselbe Format verwenden. Zu den Formaten gehören (ohne darauf beschränkt zu sein): Eine mehrzeilige Zeichenfolge (mit optionalem nachgestellten Zeilenumbruch); Ein 2D-Array von Zeichen, die X
oder sind ; Ein 1D-abgeflachtes Array von Booleschen Werten, das angibt, ob jede Position gespielt wurde.
Ein optimaler Zug garantiert Ihnen, dass Sie gewinnen, indem Sie weiter optimal spielen, oder verlängert Ihren Verlust so lange wie möglich und wird durch die folgenden Regeln definiert:
- Vermeiden Sie es, drei in einer Reihe zu machen.
- Wenn Sie zuerst gehen, spielen Sie in der Mitte.
- Wenn das einzige belegte Feld das mittlere ist, spielen Sie in einem der verbleibenden Felder.
- Wenn das mittlere Feld nicht besetzt ist und ein äußeres Feld besetzt ist, spielen Sie gegenüber dem letzten Spiel Ihres Gegners.
- Wenn das mittlere Feld besetzt ist und ein äußeres Quadrat besetzt ist, spielen Sie einen "Ritterzug" (gegenüber, einen darüber) weg von einem vorherigen Zug, bei dem Sie nicht verlieren.
- Wenn keine verbleibenden Felder mehr vorhanden sind, auf denen Sie nicht verlieren, spielen Sie auf einem der verbleibenden Felder.
[HINWEIS: Dies hat sich in einem Fall als nicht optimal erwiesen, aber Sie sollten diesen Algorithmus trotzdem verwenden.]
Sie können davon ausgehen, dass alle Ihre vorherigen Züge optimal waren. Somit ist die erste Beispielkarte keine gültige Eingabe. Die Bewegungen Ihres Gegners können optimal sein oder auch nicht.
Wenn das Spiel beendet ist (dh eine Drei in einer Reihe gemacht wurde), ist das Verhalten undefiniert.
Da dies Code-Golf ist , gewinnt die kürzeste Antwort in Bytes!
Ein möglicher Weg, bei dem nur optimale Bewegungen verwendet werden, ist folgender:
[ ] [ ] [X ] [X ] [X ] [X ] [XX ]
[ ]->[ X ]->[ X ]->[ XX]->[ XX]->[ XX]->[ XX]
[ ] [ ] [ ] [ ] [ X ] [XX ] [XX ]
Hier sind mögliche Eingaben, die vom Gegner mit nicht optimalen Zügen stammen:
(Beachten Sie, dass nur die linken Bretter in dieser Liste gültige Eingaben sind.)
[X ] [X ]
[ ]->[ ]
[ ] [ X]
[XX ] [XX ]
[ ]->[ ]
[ X] [ XX]
[XX ] [XX ]
[X ]->[X X]
[ XX] [ XX]
.XX\nX..\nX..
zum Beispiel. Müssen wir in Betracht ziehen, solche Boards zu erben?Antworten:
Ruby, Rev B 121 Bytes
Die Übermittlung ist die anonyme Funktion abzüglich der
f=
. Wird im Testprogramm angezeigt, um die Verwendung zu veranschaulichen.2 Bytes werden eingespart, indem das mittlere Quadrat zum niedrigstwertigen Bit anstelle des höchstwertigen Bits gemacht wird (Entfernen durch
/2
statt%256
.). Verbleibende Einsparungen durch eine Neuorganisation der Tabelle akzeptabler Züge. Das Organisieren als freies / besetztes zentrales Quadrat anstelle der Gesamtzahl der X ermöglicht einen einfacheren Test. Außerdem enthält das Array jetzt nur noch 2 Zeichenfolgen, sodass die%w{string1 string2}
Syntax zugunsten der["string1","string2"]
Syntax aufgegeben wird . Dies ermöglicht das Einfügen eines nicht druckbaren Zeichens\7
, wodurch wiederum eine einfachere Codierung verwendet werden kann:126-t
anstelle von(36-t)%120
.Ruby, Rev. A 143 Bytes
Dies ist eine anonyme Funktion. Das Eingabe- / Ausgabeformat wurde offen gelassen, daher habe ich mich für eine 9-Bit-Binärzahl entschieden. Das Bit des 512 stellt die Mitte dar, wobei die verbleibenden Bits sich spiralförmig darum drehen (das Bit der 1 wird als Ecke betrachtet.)
Es gibt weit mehr mögliche Eingaben als akzeptable Ausgaben. Der Algorithmus besteht also darin, alle Bewegungen auszuprobieren und eine zu finden, die zu einem akzeptablen Ausgabemuster passt. Die akzeptablen Ausgabemuster für jede Anzahl von X sind fest codiert.
Die Informationen über das mittlere Quadrat werden entfernt und die verbleibenden 8 Bits werden mit 257 multipliziert, um sie zu duplizieren. Dieses Muster wird dann durch Rechtsverschiebung über die akzeptablen Muster hinaus gedreht.
Die Schleife wird nicht verlassen, wenn ein Muster gefunden wird, sodass das zurückgegebene Muster das LETZTE akzeptable gefundene Muster ist. Aus diesem Grund werden bevorzugte Muster (wo es eine Präferenz gibt) später in der Liste aufgeführt.
Angesichts der Strategie „Ritter bewegen“ ist es von geringer Bedeutung, ob ein Muster um 45 Grad gedreht wird oder nicht. Die ungolfed Version folgt der Ritterbewegungsstrategie und muss daher nicht zwischen Eck- und Randquadraten unterscheiden: Drei in einer Reihe sind sowieso zu vermeiden.
Ich fand jedoch, dass dies nicht immer die beste Strategie ist, da es den folgenden Trick gibt. Wenn Ihr Gegner zuerst geht und die Mitte einnimmt, sollte er gewinnen. Aber bei seinem zweiten Zug macht er den Fehler, dass Sie ein 2x2-Quadrat machen dürfen, das Sie nehmen sollten, da Sie ihn so zwingen können, drei in einer Reihe zu machen. Dies ist in der Golfversion implementiert. In diesem Fall wird ein kleiner zusätzlicher Code benötigt, um zwischen drei X in einer Ecke (Gegner zum Verlieren zwingen) und drei X entlang einer Kante (sofortiger Selbstmord) zu unterscheiden.
Ungolfed im Testprogramm
Die ungolfed Version folgt der in der Frage ausgedrückten Logik.
In der Golfversion wird der Tisch leicht modifiziert
[[0],[1,17],[9],[37,7,51,85],[45],[47,119]]
, um das etwas andere Verhalten für den Fall zu implementierenr=3
. Es wird dann auf druckbares ASCII komprimiert (Dekodierung erforderlich(t-36)%120
). Ein zusätzliches Stück Logik ist erforderlich, um im Fall des Tabelleneintrags 7 zwischen drei X in einer Ecke und drei X entlang einer Kante zu unterscheiden:&&t+j%2!=43
Ausgabe des Testprogramms
Dies passiert, wenn der Computer selbst spielt.
SPIELANALYSE, DIE ZUERST SPIELT
Dies ist eigentlich sehr einfach und linear.
Wenn Sie zuerst spielen, ist das mittlere Feld immer das erste belegte Feld.
r = 0
r = 2
r = 4
Es gibt nur einen Weg (bis zur Symmetrie), fünf X einschließlich des mittleren Quadrats auf dem Brett zu haben, ohne dass das Spiel beendet ist. Im mittleren Quadrat befindet sich ein X, eines auf jeder Diagonale (in einem Winkel von 90 Grad zueinander) und eines auf jeder horizontalen / vertikalen Mittellinie (in einem Winkel von 90 Grad zueinander). Da eine ganze Kante nicht belegt werden kann, ist das Obige das einzige Anordnung möglich. Ein anderer Spieler muss beim nächsten Zug verlieren.
SPIELANALYSE ZWEITES SPIELEN
Das Spiel ist ganz anders, je nachdem, ob der andere Spieler das mittlere Feld wählt.
r = 1
mittlerer Platz besetzt
mittleres Quadrat frei
r = 3
Mittleres Feld besetzt, wenn ein anderer Spieler neben Ihrem letzten X spielt. In der ungolfed-Version wird es unterstützt, wenn ein Ritter wie unten entfernt ist
Das Obige ist jedoch NICHT der beste Zug und wird in der Golfversion nicht unterstützt. Der beste Zug ist wie folgt und erzwingt einen Sieg in der nächsten Runde:
Mittleres Feld besetzt, wenn ein anderer Spieler bei 90 oder 135 Grad bis zu Ihrem letzten X spielt (spielen Sie den Ritterzug weg.)
Mittleres Quadrat frei
r = 5
mittlerer Platz besetzt. Aus den oben in r = 4 genannten Gründen gibt es vier mögliche Züge, die alle verlieren. Es wird nur eine unterstützt: 101111 = 47.
mittleres Quadrat frei. Es gibt nur eine mögliche Platine bis zur Symmetrie, wie folgt. Ein anderer Spieler muss beim nächsten Zug verlieren, sodass r> 5 nicht unterstützt werden muss.
quelle