Tic-Tac-Toe - X oder O?


14

Hintergrund

Springe zu "Aufgabe", wenn du mit Tic-Tac-Toe vertraut bist (ich denke, die meisten sind es!)

Tic-Tac-Toe ist ein berühmtes Spiel für zwei Spieler. Es besteht aus einem 3x3- Brett, das nach und nach von zwei Spielern besetzt wird (Erläuterungen unten). Der erste Spieler benutzt den Charakter Xund der andere den O. Der Gewinner ist der erste, der 3 aufeinanderfolgende und identische Zeichen ( Xoder O) erhält , entweder horizontal, vertikal oder diagonal. Wenn das Spielfeld voll ist und keiner der Spieler drei aufeinanderfolgende Charaktere hat, wie oben beschrieben, endet das Spiel unentschieden. Beachten Sie, dass am Ende des Spiels möglicherweise leere Stellen vorhanden sind, falls einer der Spieler in weniger als 9 Zügen insgesamt gewinnt (dies ist bei einem Unentschieden nicht möglich).

Aufgabe

Mit einem Tic-Tac-Toe-Brett am Ende eines Spiels (in Form einer Zeichenfolge, einer Matrix, einer flachen Liste mit 9 geordneten Werten, einem beliebigen anderen anständigen Format) bestimmen Sie, wer das Spiel gewinnt.

  • Die Eingabe besteht aus unterschiedlichen und konsistenten Werten, einem für X, einem für Ound einem anderen, die eine leere Stelle darstellen.

  • Ihr Programm sollte in der Lage sein, 3 verschiedene, konsistente und nicht leere Werte auszugeben: einen für den Fall eines XSieges, einen für den Fall eines OSieges oder einen anderen, wenn die Spieler unentschieden sind.

    Bitte geben Sie diese Werte in Ihrer Antwort an. Sie können davon ausgehen, dass der Eingang eine gültige Tic-Tac-Toe-Karte ist.

Testfälle

X, O, _Sind die Eingangswerte hier; X wins, O winsUnd Tiesind für die Ausgabe.

X O X
O X _
O _ X

Ausgang: X wins.

X _ O
X O _
X O X

Ausgang: X wins.

X O X
_ O X
_ O _

Ausgang: O wins.

X O X
O O X
X X O

Ausgang: Tie.


Es gelten wie immer alle unsere Standardregeln. Das ist , der kürzeste Code in Bytes in jeder Sprache gewinnt!


2
Raus aus meinem Gehirn! Ich hatte buchstäblich gerade eine Idee für eine Noughts & Crosses-Herausforderung, die ich am Montag in Sanbox durchführen wollte. Dann öffne ich die Seite und sehe das!
Shaggy

1
@Shaggy Um jemanden aus der "Fast and Furious" -Serie zu zitieren: Zu langsam! ; p
Mr. Xcoder

Es ist in Ordnung, meine Idee war eine spielbare Version, vorausgesetzt das wurde noch nicht gemacht.
Shaggy

4
@Laikoni Ich glaube nicht, dass es ein Trottel ist, da dies viel flexibler Ein- und Ausgang hat und auch leere Kästchen, und dies lässt auch vermuten, dass der Eingang eine gültige Karte ist.
Erik der Outgolfer

1
@Joshua Hier geht es darum, ein Tic-Tac-Toe-Spiel zu machen. Hier geht es darum, einen einzustufen.
DonielF

Antworten:


6

Jelly ,  16 15  14 Bytes

U,Z;ŒD$€ẎḄỊÐḟḢ

Ein monadischer Link, der eine Liste von Listen (die Zeilen - oder Spalten) mit den folgenden Werten akzeptiert:

X = 0.155; O = -0.155; _ = 0

Rückgabe der Ergebnisse:

X wins = 1.085; O wins = -1.085; Tie = 0

Hinweis: Ein Wert von Null für die Verwendung _, und gleiche aber entgegengesetzte Werte Xund Odieser Wert (hier 0.155) kann in dem Bereich sein (1/6, 1/7)(an beiden Enden exklusiv) - I nur einen Wert in diesem Bereich gewählt, der eine präzise darstellbare Gleitkomma - Ergebnis ergab für die Win Cases.

Probieren Sie es online!

Wie?

U,Z;ŒD$€ẎḄỊÐḟḢ - Link: list of lists (as described above)
U              - upend (reverse each row)
  Z            - transpose (get the columns)
 ,             - pair the two
      $€       - last two links as a monad for each of them:
    ŒD         -   diagonals (leading diagonals - notes: 1. only one is of length 3;
               -              2. the upend means we get the anti-diagonals too)
        Ẏ      - tighten (make a single list of all the rows, columns and diagonals)
         Ḅ     - from binary (vectorises) (note that [0.155, 0.155, 0.155]
               -                           converts to 4*0.155+2*0.155+1*0.155 = 1.085
               -                           and [-0.155, -0.155, -0.155]
               -                           converts to 4*-0.155+2*-0.155+1*-0.155 = -1.085
               -                           while shorter lists or those of length three
               -                           with any other mixtures of 0.155, -0.155 and 0
               -                           yield results between -1 and 1
               -                           e.g. [.155,.155,0] -> 0.93)
           Ðḟ  - filter discard if:
          Ị    -   insignificant (if abs(z) <= 1) (discards all non-winning results)
             Ḣ - head (yields the first value from the list or zero if it's empty)

Ja, ich denke, alle esoterischen Sprachantworten sollten eine Erklärung haben (und ich würde gerne auch Erklärungen für normale Sprachen sehen!)
Jonathan Allan

Danke fürs Hinzufügen! Sehr guter Ansatz, viel
klüger

6

Javascript (ES6), 103 87 Bytes

a=>"012+345+678+036+147+258+048+246T".replace(/\d/g,n=>a[n]||!1).match(/(\d)\1\1|T/)[0]

Eingang

  • X wird dargestellt als 1
  • O ist dargestellt als 2
  • _ wird dargestellt als 0

Ausgabe

  • X wins wird dargestellt als "111"
  • O wins wird dargestellt als "000"
  • Krawatte wird dargestellt als "T"

Erläuterung

a=>
    "012+345+678+036+147+258+048+246" // List of indexes for each row
    .replace(/\d/g,n=>a[n]||!1)       // Replace all digits with the value of the cell
    .match(/(\d)\1\1|$/)[0]           // Find the first row filled with the same value

Testfälle

f=
a=>"012+345+678+036+147+258+048+246T".replace(/\d/g,n=>a[n]||!1).match(/(\d)\1\1|T/)[0]
console.log(f([1,2,1,2,1,0,2,0,1]))
console.log(f([1,0,2,1,2,0,1,2,1]))
console.log(f([1,2,1,0,2,1,0,2,0]))
console.log(f([1,2,1,2,2,1,1,1,2]))


"Ihr Programm sollte in der Lage sein, 3 verschiedene, konsistente und nicht leere Werte auszugeben", damit Sie keine leere Zeichenfolge für tie ausgeben können.
RedClover

1
@ Soaku Meine Güte, ich habe diesen Teil der Regeln verpasst.
Herman L

4

Jelly , 18 Bytes

UŒD;;Z;ŒDµSA⁼3µÐfḢ

Probieren Sie es online!

X= 1, O= -1, _= 0
X gewinnt = [1, 1, 1], O gewinnt = [-1, -1, -1], Unentschieden = 0
Eingabe als Liste von 3 Listen mit jeweils 3 Elementen (1, -1, 0).


Wow Nice ... Wenn Sie mit dem Golfen fertig sind, fügen Sie bitte die E / A-Werte und eine Erklärung hinzu :-)
Mr. Xcoder

Hier ist ein ähnlicher Ansatz mit einem etwas kürzeren Test. Nimmt X= 1, O= 2, _= 3, gibt zurück 1(X gewinnt),2 (O gewinnt) oder 3(Unentschieden) zurück.
Arnauld

@ Arnauld danke für die Verkürzung
Erik der Outgolfer

3

Python 3 , 73 Bytes

lambda b:{'XXX','OOO'}&{*b.split(),b[::4],b[1::4],b[2::4],b[::5],b[2::3]}

Probieren Sie es online!


Python 2 , 100 95 92 87 82 77 Bytes

lambda b:{'XXX','OOO'}&set(b.split()+[b[::4],b[1::4],b[2::4],b[::5],b[2::3]])

Probieren Sie es online!


Übernimmt die Eingabe als durch Zeilenumbrüche getrennte Zeichenfolge von XO_

Ausgänge:

  • {'XXX'}für X,
  • {'OOO'} zum O
  • {} für ein Unentschieden

Zerschneidet die Zeichenfolge in Zeilen, Spalten und Diagonalen:

The board:
    1 2 3
    4 5 6
    7 8 9
which is '123\n456\n789' is sliced into:

['123', '456', '789', '147', '258', '369', '159', '357']
rows: b.split() -> ['123', '456', '789']
cols: [b[::4],b[1::4],b[2::4]] -> ['147', '258', '369']
diag: [b[::5],b[2::3]] -> ['159', '357']

dann 'XXX'und 'OOO'werden gegen die Scheiben geprüft.

Übernimmt die Eingabe als durch Zeilenumbrüche getrennte Zeichenfolge von XO_

Ausgänge:

  • {'XXX'} zum X,
  • {'OOO'} zum O
  • {} für ein Unentschieden

Zerschneidet die Zeichenfolge in Zeilen, Spalten und Diagonalen:

The board:
    1 2 3
    4 5 6
    7 8 9
which is '123\n456\n789' is sliced into:

['123', '456', '789', '147', '258', '369', '159', '357']
rows: b.split() -> ['123', '456', '789']
cols: [b[::4],b[1::4],b[2::4]] -> ['147', '258', '369']
diag: [b[::5],b[2::3]] -> ['159', '357']

dann 'XXX'und 'OOO'werden gegen die Scheiben geprüft.


Python-Slicing FTW Wie auch immer, 81 Bytes sollten funktionieren, denke ich.
Totalhuman

@icrieverytim [2::2]Scheiben 3579, während [2:8:2]gibt357
TFeld

Python 3, 73 Bytes .
Jonathan Frech

3

R, 118 116 115 Bytes

Vielen Dank an @ user2390246 für zwei zusätzliche Bytes.

function(M,b=table,u=unlist(c(apply(M,1,b),apply(M,2,b),b(diag(M)),b(M[2*1:3+1]))))`if`(any(u>2),names(u[u>2]),"T")

Leicht ungolfed:

function(M){
    u=unlist(c(apply(M,1,table), #Contingency table of the rows
             apply(M,2,table), #of the columns
             table(diag(M)), #of the diagonal
             table(M[2*1:3+1]))) #of the opposite diagonal
    `if`(any(u>2),names(u[u>2]),"T") #Give name of element that occurs more than twice in any setting
 }

Gibt zurück, Xwenn X gewinnt, Owenn O gewinnt und Tim Falle eines Gleichstands.

Probieren Sie es online!


1
M[c(3,5,7)]ist kürzer für die gegenüberliegende Diagonale
user2390246

3

Perl 5 , 58 Bytes

56-Byte-Code + 2 fpr -p0.

$_=eval sprintf'/(.)(.{%s}\1){2}/s||'x4 .'0?$1:T',0,2..4

Probieren Sie es online!

Ausgänge Xund Ofür Siege oderT für ein Unentschieden. Beinhaltet eine Reihe von Kopf- / Fußzeilen-Code zum gleichzeitigen Testen.


Alternativ 58 Byte

$}.="/(.)(.{$_}\\1){2}/s||"for 0,2..4;$_=eval$}.'0?$1:T'

Probieren Sie es online!


2

Python 2 , 124 118 117 115 Bytes

  • 6 Bytes gespart dank Erik the Outgolfer gespart ; Verwenden einer Zeichenfolge, um Kommata zu vermeiden.
  • Dank Herrn Xcoder ein Byte gespart ; Golfen[j*3:j*3+3] zu[j*3:][:3] .
  • Speichert zwei Bytes, indem eine magische Zahl zum Komprimieren der Zeichenfolge verwendet wird.
def T(B):
 for j in range(8):
	a,b,c=map(int,`0x197bf3c88b2586f4bef6`[j*3:][:3])
	if B[a]==B[b]==B[c]>0:return B[a]

Probieren Sie es online!

Eingabe- / Ausgabewerte

  • X wird dargestellt als 1
  • O wird dargestellt als 2
  • _ wird dargestellt als None

[8,0,3,6,1,4,7,2,5,8,0,4,8,2,4,6]->map(int,'8036147258048246')
Erik der Outgolfer

@EriktheOutgolfer Danke. Ich habe versucht, die Ganzzahl-Liste mithilfe von Golf zu spielen map(ord,"..."), obwohl ein nulByte in der Mitte einer Zeichenfolge nicht funktioniert hat ...
Jonathan Frech

117 Bytes . [j*3:j*3+3]ist [j*3:][:3]. Als Randnotiz j*3+3ist dasselbe wie -~j*3, aber das sind auch 118 Bytes.
Mr. Xcoder

@ JonathanFrech Sie scheinen ein Extra zu haben 01234567...
Erik the Outgolfer

1
@ Mr.Xcoder Danke. Habe heute ein neues Golfspiel gelernt.
Jonathan Frech

2

Python 3 , 173 Bytes

lambda x:h(x,1)*2or+h(x,0)
h=lambda x,y:g(x,y)or g(zip(*x),y)or x[0][0]==x[1][1]==x[2][2]==y or x[0][2]==x[1][1]==x[2][0]==y
g=lambda x,y:any(all(e==y for e in r)for r in x)

Probieren Sie es online!

  • Eingabe als Matrix von 1 == X, 0 == O, -1 == _

  • Ausgabe als Einzelwert: 2 == X, 1 == O, 0 == TIE

-8 Bytes dank Erik dem Outgolfer


Sie können die erste Zeile lambda x:h(x,1)*2or+h(x,0)durch -8 Bytes und 0 == TIE(was imo schöner ist) ersetzen .
Erik der Outgolfer

@EriktheOutgolfer cool, danke
HyperNeutrino

2

PHP, 70 Bytes

for($c=95024101938;${${$i++&7}.=$argn[$c%9]}=1<$c/=3;);echo$XXX-$OOO;

Annahmen -n( Standardeinstellungen des Interpreters). Benötigt zusätzlich -R(execute<code> für jede Eingabezeile ), als eins gezählt.

Die Eingabe erfolgt in einer einzelnen Zeile (genau wie in der Problembeschreibung, außer dass alle Leerzeichen entfernt wurden).

Die Ausgabe ist wie folgt: 1→ X Siege, -1→ O Siege, 0→ Gleichstand.

Probieren Sie es online!


Sie müssen nicht die gesamten Zeichenfolgen haben, sondern können Ihre Ausgabewerte auswählen. 'X Wins'kann geändert werden in 'X'(oder sogar eine ganze Zahl sagen 1). Gleiches gilt für 'O wins'und Tie. Davon abgesehen 109 Bytes .
Mr. Xcoder

@ Mr.Xcoder danke für die Klarstellung.
Primo

1

Retina , 49 Bytes

;
;;
.*(\w)(.)*\1(?<-2>.)*(?(2)(?!))\1.*
$1
..+
T

Probieren Sie es online! Nimmt die Eingabe als 11-stellige Zeichenfolge von 9 Xs, Os oder -s in drei durch ;s getrennten Dreiergruppen vor , obwohl der Link einen Header enthält, der die angegebenen Testfälle in dieses Format übersetzt. Entspricht einer Gewinnlinie direkt mithilfe einer Bilanzgruppe, um sicherzustellen, dass die drei übereinstimmenden Zeichen gleich weit voneinander entfernt sind. (Geeignete Abstände sind 0 (horizontale Linie), 4 (umgekehrte Diagonale), 5 (vertikale Linie) oder 6 (diagonale); andere Abstände würden eine ;Saite treffen oder sich außerhalb der Saite erstrecken.)


1

Java 8, 112 108 106 104 90 102 93 Bytes

b->b.replaceAll(".*(X|O)(\\1|...\\1...|.{4}\\1.{4}|..\\1..)\\1.*","$1").replaceAll("..+","T")

+12 Bytes (90 → 102) durch Fehlerbehebung, indem nur eine Diagonale anstelle von beiden überprüft wurde.
-9 Bytes (102 → 93) durch Verwendung von replaceAllanstelle vonmatches .

Eingabe im Format XOX OX_ O_X, AusgabeX ,O oder T.

Erläuterung:

Probieren Sie es hier aus.

b->{                   // Method with String as both parameter and return-type
  b.replaceAll(".*(X|O)(\\1|...\\1...|.{4}\\1.{4}|..\\1..)\\1.*",
                       //  If we found a line of X or O:
     "$1")             //   Replace it with either X or O
   .replaceAll("..+",  //  If there are now more than 2 characters left:
     "T")              //   Replace it with T
                       // End of method (implicit / single-line return-statement)

Erklärung Regex:

.*(X|O)(\1|...\1...|.{4}\1.{4}|..\1..)\1.*
.*                                      .*# 0 or more trailing & leading chars
  (X|O)                               \1  # X or O next to those leading/trailing chars
       (\1                                # A single X or O in between (row found)
          |...\1...                       # 3 chars, X or O, 3 chars (column found)
                   |.{4}\1.{4}            # 4 chars, X or O, 4 chars (diagonal TLBR found)
                              |..\1..)    # 2 chars, X or O, 2 chars (diagonal TRBL found)

0

Retina , 127 Bytes

.*(X|O)\1\1.*
$1
(X|O).. \1.. \1..
$1
.(X|O). .\1. .\1.
$1
..(X|O) ..\1 ..\1
$1
(X|O).. .\1. ..\1
$1
..(X|O) .\1. \1..
$1
..+
_

Probieren Sie es online!

... Ich denke, Sie könnten diese brutale Kraft nennen ... Dachte, es könnte etwas Verdienst sein ...


0

Netzhaut , 51 Bytes

.*(X|O)(\1|...\1...|.{4}\1.{4}|..\1..)\1.*
$1
..+
T

Port meiner Java 8 Antwort . Eingang in dem Format XOX OX_ O_X, Ausgabe X, Ooder T.

Erläuterung:

Probieren Sie es hier aus.

.*(X|O)(\1|...\1...|.{4}\1.{4}|..\1..)\1.*
.*                                      .*# 0 or more trailing & leading chars
  (X|O)                               \1  # X or O next to those leading/trailing chars
       (\1                                # A single X or O in between (row found)
          |...\1...                       # 3 chars, X or O, 3 chars (column found)
                   |.{4}\1.{4}            # 4 chars, X or O, 4 chars (diagonal TL→BR found)
                              |..\1..)    # 2 chars, X or O, 2 chars (diagonal TR→BL found)

$1                                        #  Replace match of above with either X or O

..+                                       # If there are now 2 or more characters left:
T                                         #  Replace everything with T

0

J, 34 Bytes

[:>./[:+./"1(2 1 0},:0 1 2}),(,|:)

Ungolfed:

[: >./ [: +./"1 (2 1 0} ,: 0 1 2}) , (, |:)

Erläuterung

Codierung:

X = 2
O = 3
_ = 1

Unsere übergeordnete Strategie besteht zunächst darin, eine Matrix zu erstellen, bei der jede Zeile ein möglicher Gewinn ist. Zeile eins ist diagonal /, Zeile 2 ist diagonal \, die nächsten drei Zeilen sind die Zeilen und die letzten drei Zeilen sind die Spalten. Dieser Teil wird durch den Satz (mit Item Amend }) erreicht:

(2 1 0},:0 1 2}),(,|:)

Schließlich nehmen wir die GCD jeder Reihe:

+./"1

Dank unserer Kodierung hat jede Zeile mit einem Leerzeichen eine GCD von 1, ebenso wie jede Zeile, die eine Mischung aus Xs und Os enthält, da 2 und 3 Coprime sind. Als nächstes müssen wir nur das maximale Element finden:>./

Wenn das Spiel unentschieden ist, ist es 1. Wenn ein Spieler gewinnt, ist es die Nummer dieses Spielers.

Probieren Sie es online!


0

JavaScript, 66 Bytes

([a,b,c,d,e,f,g,h,i])=>e&(a&i|c&g|b&h|d&f)|a&(b&c|d&g)|i&(c&f|g&h)

Halte es einfach.

  • Eingabe: Eine Zeichenfolge oder ein Array von Zahlen oder Zeichenfolgen, 0die einem Leerzeichen, 1einem X und 2einem O entsprechen.
  • Ausgang: 0für ein Unentschieden, 1für X Sieg, 2für O Sieg.

Erweitert, leicht kommentiert:

( [a,b,c,d,e,f,g,h,i] ) => // Break apart the input into nine variables w/ destructuring
  // Run through all possible win conditions. 1&1&1 -> 1, 2&2&2 -> 2
  e & (             // All victories involving the middle square
    a & i | c & g | // Diagonal lines
    b & h | d & f   // Vertical/horizontal through the middle
  ) | 
  a & ( b & c | d & g ) | // Victories with the top-left square
  i & ( c & f | g & h )   // Victories with the bottom-right square
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.