Connect Four Validator

20

Einführung

Connect Four ist ein Spiel, in dem Sie versuchen, vier in einer Reihe zu erhalten: horizontal, vertikal oder diagonal. In diesem Codegolf versuchen wir herauszufinden, wer mit einem Spielbrett gewonnen hat. Es wird immer einen Gewinner geben und nur einen.


Aufgabe

Finden Sie mit einem Connect Four-Board heraus, wer der Gewinner ist: Xoder Y. Es wird immer einen Gewinner geben und nur einen. Die Brettgröße wird immer 6 mal 7 sein, so wie das Spielbrett im Bild ist.

Bei einem Brett ist das folgende Brett in diesem Fall Xrot und Yblau:

Bildbeschreibung hier eingeben

Ihre Eingabe wäre:

OOOOOOO
OOOOOOO
OOOOOOO
OOOOXOO
OOOXXOO
OOXYYYY

Sie können die Spielreihen nach Zeilenvorschubzeichen (wie oben) und ohne Trennzeichen trennen, die Reihen in ein Array oder eine Liste unterteilen oder eine Zeichenmatrix eingeben.

Richtige Ausgabe für dieses Beispiel:

Y

Y hat vier in einer Reihe; Y ist also der Gewinner. Also geben wir Y aus.


Testfälle

Eingang:

OOOOOOO
OOOOOOO
OOOOOOO
OOOOOOO
OOYYOOO
OYXXXXO

Ausgabe:

X

Eingang:

OOOOOOO
OOOOOOO
OOOOOOO
XXXXOOO
YXYYOOO
YXYYXYX

Ausgabe:

X

Eingang:

YXYYXOO
XYXXYOO
XXXYYOO
YYYXXOO
XXYYYYO
XXYYXXO

Ausgabe:

Y

Eingang:

OOOOOOO
OOOOOOO
OYOOOOO
OOYOOOO
OOOYOOO
OOOOYOO

Ausgabe:

Y

Eingang:

OOOOOOO
OOOOOOO
OYOOOOX
OOYOOOX
OOOXOOX
OXOXYOX

Ausgabe:

X

Wertung

Wenigste Anzahl von Bytes gewinnt!

Neil
quelle
Dies ist die perfekte Herausforderung für PMA / Snails codegolf.stackexchange.com/questions/47311/...
Jerry Jeremiah
2
Können wir davon ausgehen, dass der Gewinner immer einen Spielstein mehr hat als der Verlierer?
Math Junkie
1
@mathjunkie Ich habe mich geirrt, das kannst du nicht annehmen.
Neil
3
@nfnneil Muss die Ausgabe X oder Y sein oder können wir zwei andere konsistente Ausgaben auswählen, um den Gewinner anzugeben?
Martin Ender
1
Können wir uns dafür entscheiden, andere Zeichen als Eingabe zu verwenden? Oder eine numerische Matrix eingeben?
Luis Mendo

Antworten:

2

Jelly , 19 Bytes

UŒD;ŒD;Z;ṡ€4;/ṢEÞṪṪ

Probieren Sie es online!

Der Kern dieser Antwort ist von meiner Antwort auf diese sehr ähnliche Frage kopiert .

Erläuterung

UŒD;ŒD;Z;ṡ€4;/ṢEÞṪṪ
   ;  ; ;             Append {the input} and the following three values:
UŒD                     the antidiagonals of {the input};
    ŒD                  the diagonals of {the input};
       Z                the transposed {input}.
         ṡ 4          Find all length-4 substrings
          €             of each subarray within that.
            ;/        Flatten one level.
                Þ     Sort, with the following sort order:
               E        If all elements are the same, sort later.
              Ṣ         Tiebreak via lexicographical order.
                 ṪṪ   Take the last element of the last element.

Ziemlich einfach: Wir nehmen alle Zeilen, Spalten, Diagonalen und Antidiagonalen (wie im n-queens-Validator), nehmen dann alle Teilzeichenfolgen der Länge 4 und sortieren sie so, dass die Gewinnlinie von 4 nach sortiert wird das Ende. (Wir brauchen den Tiebreak für den Fall, dass es OOOOzusätzlich zum XXXXoder ein gibt YYYY.) Nehmen Sie das letzte Element des letzten Elements, und das wird Xoder Ywie erforderlich sein.


quelle
6

Netzhaut, 51 48 Bytes

Vielen Dank an Martin Ender für das Speichern von 3 Bytes

M`X((.{6}X){3}|(.{8}X){3}|(.{7}X){3}|XXX)
T`d`YX

Probieren Sie es online!

Übernimmt die Eingabe als durch Kommas getrennte Liste von Zeilen

Mathe-Junkie
quelle
Sie können mit einem Spiel Stufe ein paar Bytes speichern und verkürzt (.{7}X){3}|XXXauf (.{7}X|X)\4\4: tio.run/nexus/retina#fc4xCsMwDAXQPfcI2GC6NDS5QaeipcP/...
Martin Ender
1
@MartinEnder Ich verstehe nicht, wie Sie es verwenden können \4- Sie möchten den Effekt der .{7}Zeichenfolge wiederholen , nicht des übereinstimmenden. (Und Bilanzkreise wären wahrscheinlich viel zu lang.)
Neil
1
@Neil oh yeah, egal, irgendwie habe ich nicht gedacht, dass es andere OXY-Zellen als das Match im Gitter gibt. Bei Verwendung der Übereinstimmungsstufe werden dann immer noch 3 Bytes gespart.
Martin Ender
5

Javascript (ES6), 54 55

Edit 1 Byte gespeichert dank @Arnauld

Ich überprüfe nur, ob X der Gewinner ist, da es immer einen Gewinner und nur einen Gewinner geben wird

Die Eingabe ist eine Zeichenfolge mit einem beliebigen Trennzeichen, wie in der Antwort von @ Arnauld

F=    
b=>'YX'[+[0,6,7,8].some(x=>b.match(`X(.{${x}}X){3}`))]

;['OOOOOOO OOOOOOO OOXOOOO OOXOOOO OOXOOOO OOXOYYY'
 ,'OOOOOOO OOOOOOO OOXOOOO OOYXOOO OOYOXOO OOYYOXY'
 ,'OOOOOOO,OOOOOOO,OOOOOOO,OOOOOOO,OOYYOOO,OYXXXXO'
 ,'OOOOOOO,OOOOOOO,OOOOOOO,XXXXOOO,YXYYOOO,YXYYXYX'
 ,'YXYYXOO,XYXXYOO,XXXYYOO,YYYXXOO,XXYYYYO,XXYYXXO']
.forEach(s => console.log(s,F(s)))

edc65
quelle
@ Arnauld richtig, danke
edc65
4

Jelly , 25 22 Bytes

ŒgL⁼¥Ðf
;UŒD€;Z;$ç€4FṀ

Nimmt eine Liste von Zeichenfolgen (oder eine Liste von Zeichen) auf X, Yund O(würde auch mit Ersetzungen funktionieren, bei denen das Leerzeichen eine niedrigere Ordnungszahl hat als beide Zähler).

Probieren Sie es online! oder führen Sie eine erweiterte Version aus , die eine mehrzeilige Zeichenfolge akzeptiert.

Wie?

ŒgL⁼¥Ðf - Link 1, runs of given length: list A, length B  e.g. "XYYYXXO", 4
Œg      - group runs of equal elements of A                     ["X","YYY","XX","O"]
     Ðf - filter keep:
    ¥   -     last two links as a dyad:
  L     -         length                                         1   3     2    1
   ⁼    -         equal to B?         (none kept in this case->) 0   0     0    0

;UŒD€;Z;$ç€4FṀ - Main link: list of list of chars (or list of stings) I
 U             - reverse each row of I
;              - I concatenated with that
  ŒD€          - positive diagonals of €ach (positive and negative diagonals)
        $      - last two links as a monad:
      Z        -     transpose of I (i.e. the columns)
       ;       -     concatenated with I (columns + rows)
     ;         - concatenate (all the required directional slices)
         ç€4   - call the last link (1) as a dyad for €ach with right argument = 4
            F  - flatten the result
             Ṁ - take the maximum ('Y'>'X'>'O') - this has the bonus effect of returning:
                               'Y' or 'X' for a winning board; and
                               'O' or '' for a (valid) game in progress.
Jonathan Allan
quelle
4

JavaScript (ES6), 77 76 69 Bytes

7 Bytes gespart dank Neil

Nimmt Eingaben als eine etwas getrennte Zeichenfolge, wobei etwas im Grunde genommen ein beliebiges Zeichen ist.

b=>[...'XXXXYYYY'].find((c,i)=>b.match(`(${c}.{${(i%4+6)%9}}){3}`+c))

Testfälle

Arnauld
quelle
Warum nicht benutzen b.match()? Sollte beim RegExpAnruf sparen .
Neil
@Neil Ich habe total vergessen, dass match()eine implizite Konvertierung nach RegExp. Vielen Dank!
Arnauld
3

Python 2 , 143 Bytes

m=input()
u=[r[::-1]for r in m]
print"YX"[any(any('X'*4in''.join(t[i][j-i]for i in range(j+1))for j in range(6))for t in(m[::-1],m,u,u[::-1]))]

Nimmt eine Liste von Zeichenfolgen oder eine Liste von Zeichen. Hardcodiert für 6 Zeilen mal 7 Spalten, wie die Spezifikation garantiert.

Probieren Sie es online!

Jonathan Allan
quelle
2

PHP, 71 Bytes

echo preg_match('#X(XXX|(.{8}X){3}|(.{7}X){3}|(.{9}X){3})#',$argn)?X:Y;

Online Version

Jörg Hülsermann
quelle
2

Python 2 , 201 143 129 128 107 Bytes

Ich habe mich entschieden, horizontal, vertikal und diagonal zu einer Liste zusammenzufügen und dann Inkremente hinzuzufügen und dann nach X zu suchen, um die Zeiten darin zu bestimmen. Und da es immer einen Gewinner geben wird, kann ich davon ausgehen, dass Y gewonnen hat, wenn X dies nicht tut. Dieser Code nimmt eine Matrix aller verschiedenen Teile und leeren Stellen auf.

lambda m:"YX"[any("X"*4in"".join(a)for a in zip(*m)+m+zip(*["0"*(7-i)+m[i]+"00"*i+m[i]for i in range(6)]))]

Probieren Sie es online!

Credits

Neil
quelle
Es ist vollkommen akzeptabel, sich selbst zu antworten.
Jonathan Allan
Ohne einen Blick zu viel auf mich, scheint es nutzlos Whitespaces an zu sein: i:] for, i, r, r] forund 1 for.
Yytsi
@ TuukkaX Danke für die Eingabe, aktualisiert.
Neil
Könnte *(len(m)-1)auch sein*~-len(m) . Wie es funktioniert.
Yytsi
Die ] forund 1 forsind immer noch da.
Yytsi
1

K (NGN / k) , 58 55 Bytes

{"XY"@|/&/'88<x ./:/:,/{x+/:/:+3+[4#1-+!3 3]\&4}'+!6 7}

Probieren Sie es online!

{ } Funktion mit Argument x

+!6 7 alle möglichen Paare von 0..5 und 0..6

{ }' für jeden von ihnen

4#1-+!3 3 sind 4 der 8 ortho-diagonalen Richtungen: (1 1;1 0;1 -1;0 1)

3+[ ]\&4Beginnen Sie mit einer Liste von vier Nullen ( &4) und führen Sie drei Schritte in jede der Richtungen aus

x+/:/: Beginnen Sie an jeder möglichen Position und führen Sie die Schritte in jede mögliche Richtung aus

,/verketten. An dieser Stelle haben wir eine Matrix mit 4 Listen von Koordinatenpaaren, von denen einige über die Tafel hinausreichen

x ./:/: suchen Sie die entsprechenden Zellen aus x

88<welche von ihnen sind "Y"-s? (88 ist der ASCII-Code von "X")

&/'Welche 4-Listen bestehen nur aus "Y"-s? (und-reduzieren-jeden)

|/Gibt es mindestens eine solche? (oder-reduzieren)

"XY"@wenn falsch zurück "X", wenn wahr zurück"Y"

ngn
quelle
1

Zsh , 207 ... 159 Bytes

Versionsgeschichte: 4 Iterationen für ~ 25 Bytes in der ersten Woche; dann 3 weitere Iterationen für ~ 25 Bytes 6 Monate später.

t(){a=($^a-$^@_);for s l (${w:^^argv})s+=$l&&for ((i=0;i++<$#s;))a[i]+=$s[i];}
w=(+)
t $@
for s;w[++j]=${(l:j:)}_
t $@
t ${(Oa)@}
[[ $a = *XXXX* ]]&&<<<X||<<<Y

( erster ) ( zweiter ) ( dritter ) ( vierter ) ( fünfter ) ( sechster ) Probieren Sie es online!

In der Fußzeile drucke ich sowohl die Eingabekarte als auch das Array, das wir daraus erstellen, nach stderr. Scrollen Sie zum Debuggen nach unten, um sie anzuzeigen. Das Array, das wir bauen, ist jetzt viel länger, da tes bei jedem Aufruf ein kartesisches Produkt mit Eingangskarte gibt . (Hey, es hat den Code um ein paar Bytes verkürzt.)

Es gibt hier eine Menge zu besprechen , deshalb habe ich die (sechste Ausgabe) Kommentare zu einer kommentierten Zusammenfassung verschoben .

(tl; dr: Transpositionen des ursprünglichen Arrays verketten, aber getrennt aufbewahren)

GammaFunktion
quelle