Verlieren Sie bei Tic-Tac-Toe

18

Schreiben Sie ein Programm, mit dem Sie Misère tic-tac-toe spielen können. Das heißt, das Ziel ist es, Ihren Gegner zu zwingen, drei in einer Reihe zu nehmen.

Akzeptieren Sie bei der Standardeingabe entweder ein 'X' oder ein 'O' (der Buchstabe, nicht Null), um zu bestimmen, auf welcher Seite das Programm abgespielt wird. Geben Sie dann eine einzelne Ziffer für Ihren Zug in Ihrem Zug aus und lesen Sie eine einzelne Ziffer in dem Zug Ihres Gegners, bis das Spiel beendet ist (X steht immer an erster Stelle). Sobald ein Gewinner ermittelt ist, geben Sie X oder O für den Gewinner oder D für ein Unentschieden aus. Zum Beispiel, wenn O 3 in einer Reihe bekommt, gewinnt X.

Angenommen, die Tafel ist folgendermaßen nummeriert:

0|1|2
-----
3|4|5
-----
6|7|8

Idealerweise ist eine Lösung optimal und verliert nie. Genau wie Tic-Tac-Toe sollte ein perfektes Spiel immer zu einem Unentschieden führen. Wenn das obige Protokoll eingehalten wird, kann ich die Einreichungen automatisch anhand verschiedener möglicher Strategien testen.

Gewinner ist der kürzeste Code. Bonuspunkte, wenn sie zufällig aus gleich guten Zügen ausgewählt werden, um das Spiel etwas unvorhersehbarer zu machen.

captncraig
quelle

Antworten:

10

Python, 383 Zeichen

M=[21,1344,86016,4161,16644,66576,65793,4368]
X=lambda B,k:any(m*k==B&m*3for m in M)
def S(B):
 if X(B,2):return 1,
 M=[i for i in range(0,18,2)if B>>i&3<2]
 return max((-S((B|3<<i)^87381)[0],i)for i in M)if M else(0,)
r='D'
c=ord(raw_input())&1
B=0
for i in range(9):
 if i&1==c:m=S(B^c*87381)[1];print m/2;B|=3-c<<m
 else:
  B|=2+c<<input()*2
  if X(B,2+c):r='XO'[c];break
print r

Die Platine Bist als eine ganze Zahl dargestellt zwei Bits pro Quadrat verwendet wird , mit 00und 01repräsentieren leere, 10darstellt und O 11darstellt , X Mist ein Satz von Bitmasken mit 01in den Spots eines verlieren Tripel ( 21= 0b010101= die obere Reihe etc.) Xberechnet , wenn jede verlierende Triple for kist auf einer Tafel vorhanden. SSucht Minimax nach einem optimalen Zug für X und gibt ein Paar der Punkte (1 = Sieg, -1 = Niederlage, 0 = Unentschieden) und einen quadratischen Index zurück. ^87381(= ^0b010101010101010101) kippt X und O, während leere Felder unverändert bleiben.

Der Computer verliert nie, deshalb musste ich diesen Scheck nicht mit einbeziehen :).

Es gibt wahrscheinlich einen einfacheren / kürzeren regelbasierten Algorithmus, aber das funktioniert.

Keith Randall
quelle
Sneaky sneaky bitwise witchcraft +1
Rohan Jhunjhunwala