Ist es ein gültiger Schachzug?

15

Anderer Name: ChessMoveQ

Bestimmen Sie anhand einer Liste mit bis zu 32 Elementen, die jeweils aus 4 Elementen bestehen, und einer zweiten Liste mit 4 Elementen, ob der in der zweiten Eingabe angegebene Zug ein gültiger Schachzug ist.

Die erste Liste zeigt die Position aller 32 Teile auf der Tafel an. Jedes Element folgt der Struktur <colour>, <piece-name>, <x-coord>, <y-coord>, zum Beispiel ["W", "K", 5, 1], die anzeigt, dass der weiße König eingeschaltet ist 5, 1( e1auf einem normalen Schachbrett). Alle Elemente der ersten Eingabe sind eindeutig. <x-coord>und <y-coord>wird immer zwischen 1 und 8 liegen. Ein Beispiel wäre:

[["B", "K", 3, 8], ["B", "Q", 1, 5], ["B", "N", 4, 7], ["B", "N", 7, 8],
 ["B", "B", 2, 4], ["B", "R", 4, 8], ["B", "R", 8, 8], ["B", "P", 1, 7],
 ["B", "P", 2, 7], ["B", "P", 3, 6], ["B", "P", 5, 6], ["B", "P", 6, 7],
 ["B", "P", 7, 7], ["B", "P", 8, 7], ["W", "K", 5, 1], ["W", "Q", 6, 3],
 ["W", "N", 3, 3], ["W", "B", 5, 2], ["W", "B", 6, 4], ["W", "R", 1, 1],
 ["W", "R", 8, 1], ["W", "P", 1, 3], ["W", "P", 2, 2], ["W", "P", 3, 2],
 ["W", "P", 4, 4], ["W", "P", 6, 2], ["W", "P", 7, 2], ["W", "P", 8, 3]]

welches würde den Vorstand vertreten:

ein beispiel schachbrett

Die zweite Eingabe besteht aus den gleichen Strukturen wie die Unterlisten der ersten, aber anstatt der x- und y-Koordinaten, die angeben, wo sich das Stück befindet, geben sie an, wohin es sich bewegen möchte.

Für das obige Beispiel könnte ein gültiger Zug sein ["W", "B", 4, 3](der Bischof bewegt sich ein Feld vorwärts und nach links), und ein ungültiger Zug könnte sein ["B", "R", 4, 1], dass der Turm durch den Ritter und den Bauern ziehen müsste, um zum Feld zu gelangen. Als der Umzug in mehrere Stücke zu Zeiten beziehen könnte, müssen Sie prüfen , ob jede der genannten Stücke machen den Umzug, nicht nur einer von ihnen. Zum Beispiel ist das erste Beispiel nur für einen Bischof gültig, aber es ist immer noch ein gültiger Zug. Da jedoch kein schwarzer Turm den zweiten Zug ausführen kann, ist er ungültig.

Ihre Aufgabe ist es festzustellen, ob der in der zweiten Eingabe angegebene Zug ein gültiger Schachzug ist. Die Gültigkeit einer Regel hängt von der Figur ab, die sich zu bewegen versucht (klicken Sie auf den Namen der Figur, um ein Diagramm der gültigen Züge anzuzeigen):

  • Jede Figur : Keine Figur kann auf ein bereits belegtes Feld oder von der Tafel gehen, es sei denn, auf diesem Feld befindet sich eine Figur der anderen Farbe. Beispielsweise kann sich eine weiße Figur auf ein Feld bewegen, das von einer schwarzen Figur besetzt ist, jedoch nicht von einer weißen Figur. Außerdem können keine Teile außer Ritter auf Felder verschoben werden, die direkt von einem anderen Teil blockiert werden.
    • Eine Bewegung von Teil B zu Quadrat C wird von Teil A "direkt behindert", wenn sich A direkt in einer geraden (orthogonalen oder diagonalen) Linie zwischen B und C befindet .
  • Jede Figur : Die Position des Königs kann auch die Gültigkeit des Zuges einer Figur beeinflussen. Wenn eine dieser beiden Bedingungen erfüllt ist, ist die Verschiebung ungültig:
    • Setzen Sie den König der Kontrolle aus, indem Sie ein Stück auf die gleiche Seite wie den gefährdeten König bewegen. Dies gilt nur, wenn eine nicht gegnerische Figur den Zug macht, anstatt eine gegnerische Figur, die sich bewegt, um den König in Schach zu setzen.
    • Lassen Sie den König in Schach. In diesem Fall muss er außer Kontrolle geraten. Wenn der König in Schach ist und der Zug vorschreibt, dass sich eine andere Figur bewegt, ist dies ein ungültiger Zug, es sei denn, die andere Figur verhindert den Schachzug . Ein Teil kann auf zwei Arten das Prüfen verhindern: Entweder nimmt es das Prüfteil oder es behindert den Weg zwischen dem Prüfteil und dem König.
    • Ein "Scheck" ist eine Situation, in der der Gegner des Königs (wenn er an der Reihe wäre) legal eine Figur auf diesen König ziehen könnte. Diese Regel gilt nicht rekursiv, dh ein König ist in Schach, auch wenn der Zug des Gegners auf diesen König seinen eigenen König in Schach lassen würde.
  • Bauern : Ein Bauer kann ein Feld vorwärts (dh aufwärts, wenn er weiß ist, abwärts, wenn er schwarz ist) zu einem freien Feld bewegen. Es gibt auch drei spezielle Situationen:
    • Wenn sich der Bauer noch nicht bewegt hat (Sie können dies anhand der Y-Koordinate bestimmen; weiße Bauern haben sich nicht bewegt, wenn ihre Y-Koordinate 2 ist, schwarze Bauern haben sich nicht bewegt, wenn ihre Y-Koordinate 7 ist), der Bauer darf zwei Felder vorwärts zu einem freien Feld bewegen.
    • Befindet sich eine gegnerische Figur diagonal vor dem Bauern (dh auf dem Feld nordwestlich oder nordöstlich des Bauern, wenn dieser weiß ist, oder südwestlich oder südöstlich, wenn er schwarz ist), der Bauer darf auf das besetzte Feld ziehen.
    • Wenn sich ein Bauer in normalen Schachregeln zur letzten Y-Koordinate bewegt (8 für Weiß oder 1 für Schwarz), muss er zu einer Dame, einem Turm, einem Ritter oder einem Bischof derselben Farbe befördert werden. Für die Zwecke dieser Frage spielt die Wahl der Beförderung keine Rolle, ob der Zug gültig ist oder nicht (und kann nicht im Eingabeformat ausgedrückt werden), aber Bauernzüge, die zur Beförderung führen würden, müssen erlaubt sein.
  • Bischöfe : Bischöfe können sich zwischen 1 und 8 Feldern entlang eines ununterbrochenen interkardinalen (dh diagonalen) Pfades bewegen.
  • Ritter : Ritter können sich in einerLFormbewegen, die aus folgenden (äquivalenten) Zügen besteht:
    • Ein einzelnes Feld in einer beliebigen Himmelsrichtung, gefolgt von einer 90/270 ° -Drehung, gefolgt von einer letzten Bewegung von 2 Feldern vorwärts.
    • 2 Felder in einer beliebigen Himmelsrichtung, gefolgt von einer 90/270 ° -Drehung, gefolgt von einer letzten Bewegung eines einzelnen Feldes vorwärts.
    (Denken Sie daran, dass der Weg eines Ritters nicht durch dazwischenliegende Teile blockiert werden kann, obwohl sein letztes Quadrat noch legal sein muss.)
  • Türme : Türme können sich zwischen 1 und 8 Feldern entlang eines ununterbrochenen Kardinalpfades bewegen.
  • Königinnen : Königinnen können sich zwischen 1 und 8 Feldern entlang eines durchgehenden kardinalen oder interkardinalen (dh diagonalen) ungehinderten Pfades bewegen.
  • Könige : Könige bewegen sich wie Königinnen, mit der Ausnahme, dass sie nur ein Feld pro Zug bewegen dürfen (dh ein König kann sich nur auf kardinal oder diagonal benachbarte Felder bewegen). Zur Erinnerung, Sie können keinen Zug machen, der Ihren König in Schach hält. Sie können also auch Ihren König nicht in Schach setzen.

Die Schachregeln enthalten auch spezielle Züge, die "Rochade" und "en passant" genannt werden. Da die Rechtmäßigkeit dieser Züge jedoch von der Geschichte des Spiels abhängt, nicht nur von der aktuellen Position (und da beim Rochieren zwei Stücke gleichzeitig verschoben werden müssen, was nicht zum Eingabeformat passt), sollten Sie keinen dieser Züge in Betracht ziehen zu existieren (dh ein Umzug, der Rochade oder en passant wäre, sollte als illegal angesehen werden).

Sie können zwei unterschiedliche Ergebnisse ausgeben, um die Gültigkeit eines Zuges anzuzeigen, und Sie können Eingaben in eine von Ihnen gewünschte Methode vornehmen. Sie können auch 0-Indizierung anstelle von 1-Indizierung für die Positionen wählen, wenn Sie dies vorziehen. Dies ist ein , also gewinnt der kürzeste Code!

Testfälle

Board
Move => Output (Reason)

[["B", "K", 3, 8], ["B", "Q", 1, 5], ["B", "N", 4, 7], ["B", "N", 7, 8], ["B", "B", 2, 4], ["B", "R", 4, 8], ["B", "R", 8, 8], ["B", "P", 1, 7], ["B", "P", 2, 7], ["B", "P", 3, 6], ["B", "P", 5, 6], ["B", "P", 6, 7], ["B", "P", 7, 7], ["B", "P", 8, 7], ["W", "K", 5, 1], ["W", "Q", 6, 3], ["W", "N", 3, 3], ["W", "B", 5, 2], ["W", "B", 6, 4], ["W", "R", 1, 1], ["W", "R", 8, 1], ["W", "P", 1, 3], ["W", "P", 2, 2], ["W", "P", 3, 2], ["W", "P", 4, 4], ["W", "P", 6, 2], ["W", "P", 7, 2], ["W", "P", 8, 3]]
["W", "R", 8, 2] => True (The rook on h1 can move forward one)

[['B', 'K', 6, 8], ['B', 'Q', 1, 7], ['B', 'N', 1, 3], ['B', 'N', 7, 1], ['B', 'B', 8, 8], ['B', 'B', 2, 5], ['B', 'R', 4, 3], ['B', 'R', 1, 5], ['B', 'P', 5, 5], ['B', 'P', 7, 2], ['B', 'P', 5, 7], ['B', 'P', 5, 6], ['B', 'P', 4, 4], ['W', 'K', 7, 3], ['W', 'Q', 3, 2], ['W', 'N', 4, 8], ['W', 'N', 7, 5], ['W', 'B', 1, 1], ['W', 'B', 8, 1], ['W', 'R', 1, 8], ['W', 'R', 3, 7], ['W', 'P', 8, 2], ['W', 'P', 6, 3], ['W', 'P', 4, 2], ['W', 'P', 1, 4], ['W', 'P', 8, 7]]
['W', 'N', 1, 5] => False (Neither knight to move to a5 from where they are)

[['B', 'K', 7, 3], ['B', 'Q', 2, 4], ['B', 'N', 5, 2], ['B', 'N', 1, 6], ['B', 'B', 7, 7], ['B', 'B', 1, 8], ['W', 'K', 7, 1], ['W', 'Q', 6, 1], ['W', 'N', 5, 6], ['W', 'N', 3, 3], ['W', 'B', 2, 2], ['W', 'B', 6, 5]]
['B', 'K', 8, 3] => False (The white bishop would put the king in check)

[['B', 'K', 7, 6], ['B', 'Q', 8, 3], ['B', 'N', 7, 7], ['B', 'N', 8, 7], ['B', 'B', 2, 2], ['B', 'B', 3, 8], ['B', 'R', 1, 1], ['B', 'R', 1, 6], ['B', 'P', 8, 5], ['B', 'P', 4, 3], ['B', 'P', 8, 6], ['W', 'K', 7, 8], ['W', 'Q', 7, 2], ['W', 'N', 5, 1], ['W', 'N', 4, 6], ['W', 'B', 1, 2], ['W', 'B', 2, 6], ['W', 'R', 4, 4], ['W', 'R', 3, 6], ['W', 'P', 5, 2], ['W', 'P', 6, 2]]
['B', 'N', 5, 8] => False (The white queen currently has the king in check, and this move doesn't prevent that)

[['B', 'K', 7, 6], ['B', 'Q', 8, 3], ['B', 'N', 7, 7], ['B', 'N', 8, 7], ['B', 'B', 2, 2], ['B', 'B', 3, 8], ['B', 'R', 1, 1], ['B', 'R', 1, 6], ['B', 'P', 8, 5], ['B', 'P', 4, 3], ['B', 'P', 8, 6], ['W', 'K', 7, 8], ['W', 'Q', 7, 2], ['W', 'N', 5, 1], ['W', 'N', 4, 6], ['W', 'B', 1, 2], ['W', 'B', 2, 6], ['W', 'R', 4, 4], ['W', 'R', 3, 6], ['W', 'P', 5, 2], ['W', 'P', 6, 2]]
['B', 'N', 7, 5] => True (The king is in check, and the knight blocks that)

[['B', 'K', 8, 3], ['B', 'Q', 6, 5], ['B', 'N', 7, 8], ['B', 'N', 3, 7], ['B', 'B', 4, 1], ['B', 'B', 1, 1], ['W', 'K', 7, 7], ['W', 'Q', 7, 1], ['W', 'N', 2, 2], ['W', 'N', 1, 3], ['W', 'B', 3, 5]]
['B', 'B', 2, 2] => True (takes the white knight)

[['B', 'K', 6, 1], ['B', 'Q', 6, 2], ['W', 'K', 8, 1]]
['B', 'Q', 7, 1] => True (Smallest checkmate possible, in terms of bounding box)

Diese Herausforderung war Sandkasten . Da es ohne jede Erklärung Abwertungen erhielt, beschloss ich, es trotzdem zu posten

Caird Coinheringaahing
quelle
"Ein Teil auf derselben Seite bewegt sich und setzt den König der Kontrolle aus." - Diese Formulierung scheint jetzt nicht zu passen, da Sie die Überschrift verschoben haben, unter der sie steht. Ich würde es in etwas ändern, wie "Wenn ich dieses Stück
bewege,
Diese Frage wurde in der Sandbox und jetzt hier ohne eine einzige Erklärung herabgestimmt. Es gibt nichts, was ich tun könnte, um Sie zu veranlassen, mir zu sagen, warum Sie abgelehnt haben, aber zumindest die Anständigkeit, Ihre Handlungen zu erklären, anstatt still im Schatten zu stehen. Wenn Sie der Meinung sind, dass dieser Beitrag verbessert werden kann, schlagen Sie bitte vor, wie, anstatt einen Pot Shot zu machen, ohne sich selbst zu erklären.
Caird Coinheringaahing
2
Niemand hat es abgelehnt ...?
FlipTack
1
Können wir eine 2D-Anordnung von Stücken als Eingabe erhalten?
Ovs
1
@ovs Ja, das scheint akzeptabel zu sein
Caird Coinheringaahing

Antworten:

3

Python 2 (mit Python-Schach ),  141 138 134 133  132 Bytes

Ohne irgendeinen der wirklich interessanten Codes zu machen - aber kann dies vielleicht mit Golfsprachen oder (wage ich es zu erwähnen) Mathematica konkurrieren?

Hinweis: python-Schach ist ein PyPI Paket auf Python installiert 2.7.9+ mit:
python -m pip install python-chess)

import chess
a,p,n=input()
S=chess.Board(a+' - - 0 1')
for m in S.legal_moves:1/(m.to_square!=n)**(`p`in`S.piece_at(m.from_square)`)

Ein vollständiges Programm, das die Eingabe von drei Elementen akzeptiert:

  1. der Anfang eines FEN-Datensatzes - der String, der die ersten beiden Felder enthält. Hiermit wird festgelegt, in welchem ​​Board-Status UND welche Farbe sich bewegt (da dies die Informationen in der Eingabe im OP sind, während die Felder drei bis sechs vom OP "festgelegt" sind und daher nicht Teil der Eingabe sein sollten).
  2. der Stückname, der versucht sich zu bewegen (wie im OP angegeben - einer von PRNBQK)
  3. der Platz , an dem das genannte Stück zu bewegen versucht , wo a1ist 0, b1ist 1, ... a2ist 8, ..., h8ist 63,

Das Programm gibt über seinen Exit-Code bei gültiger Eingabe aus:

  • 1 wenn der Zug gültig ist (das Programm hat einen Fehler ausgelöst - aufgrund der Division durch Null);
  • 0 es ist es nicht (das Programm wird normal beendet)

(Nicht) Online ausprobieren! (Da das Python-Chess-Paket dort nicht installiert ist und TIO keine Internetverbindung zulässt, funktioniert der PIP-Installationscode im Header nicht.)

Beachten Sie, dass das Netzbetreiber in Python macht 1**1 == 1**0 == 0**0 == 1aber 0**1 == 0
... also 1/0**1wirft eine Division durch Null - Fehler während 1/1**1, 1/1**0und 1/0**0alle Erfolg haben
(... und das in PythonFalse und TrueEquate zu 0und 1respectively).

Jonathan Allan
quelle
2
Es ist eine absolut gültige Antwort, aber es fühlt sich ein bisschen wie Schummeln an, ähnlich einer eingebauten Mathematica-Antwort.
Caird Coinheringaahing
Ja, daher auch der Kommentar , den ich an der Spitze setzen „Ohne dem wirklich interessant Code zu tun ...“ vielleicht , wenn ich etwas mehr Zeit habe ich ein Jelly man tun würde (die dieses Modul nicht importieren können :))
Jonathan Allan
1
... wohlgemerkt, es hat noch einige Mühe gekostet.
Jonathan Allan
Neu anordnen str(S.piece_at(m.from_square))==p forzu p==str(S.piece_at(m.from_square))for, dass ein Byte speichern sollte.
Zacharý
Ah, ja - danke @ Zacharý Ich wollte nur sehen, ob ich die reprBackticks, die ich ersetzen wollte str, auswerten kann, um zu sparen ...
Jonathan Allan
3

Regex (PCRE2), 931 925 837 Bytes

Diese Lösung weicht von der Problemstellung dahingehend ab, dass anstelle eines Board-Status und eines Move zwei Board-Status an den regulären Ausdruck übergeben werden. Die Bewegung wird aus der Differenz zwischen den beiden Board-Zuständen abgeleitet. Deshalb habe ich es mir zur Aufgabe gemacht, die Testfälle in dem von dieser Frage vorgegebenen Format zu erstellen, alle Instanzen des beschriebenen Stücks auf der Tafel zu finden und mit jedem einzelnen zu versuchen, es an die Zielposition zu bewegen und den regulären Ausdruck auszuwerten mit dieser Möglichkeit herauszufinden, ob irgendwelche vom regulären Ausdruck als gültig gemeldet werden. Wenn das nicht in Ordnung ist, lass es mich wissen. Es ist möglich, einen regulären Ausdruck als Position + Verschiebung zu implementieren, dies wäre jedoch weniger elegant und erfordert eine ernsthafte Umgestaltung.

Die Tafel wird in 8 × 8 ASCII dargestellt, wobei weiße Teile in Großbuchstaben und schwarze in Kleinbuchstaben geschrieben sind: P awn, k N ight, B ishop, R ook, Q ueen, K Ing. Die schwarze Seite (Rang 8) liegt oben und die weiße Seite (Rang 1) unten. Jeder Rang wird durch eine neue Linie getrennt und leere Felder werden als markiert- . Die beiden Boardpositionen sind durch einen zusätzlichen Zeilenumbruch getrennt.

Das eigentliche Ziel dieses Projekts ist die Validierung ganzer Spiele, nicht nur einzelner Züge. Weiter unten finden Sie Informationen zum aktuellen Status.

()?(?>|((.|
(?=.)){2})((?=(\X{72})-))((?=(?(1)[-a-z]|[-A-Z])))((?5)(?(?=(.*
)
)[qnrb]|p))((?5)(?(?=(?8){8}
)[QNRB]|P)))(?>((.)(?=(?5)\11)|(?(m)$)((?(1)(-(?=(?9))(?=(?3){8}((?3){9})?P(?4))(?(-1)(?=(?8){4}
))|[a-z](?=(?9))(?=(?3){7}(?2)?P(?4)))|(p(?4)((?=(?3){8}((?3){9})?-(?7))(?(-1)(?=(?8){7}
))|(?=(?3){7}(?2)?[A-Z](?7)))))|(?<e>(?6).)?(?=(?i:(?|(?(e)|(B|Q))(?27)(?(e)(B|Q))|(?(e)|(R|Q))(?31)(?(e)(R|Q))|(?(e)|(N))(?34)(?(e)(N))|(?(e)|(K))(?35)?(?(e)(K))))(?(e)(?<=(?!(?6)).)(?4)|(?6).(?5)\19))(?(e)(?=(?5)\20)|(?!(?6)).(?4)))(?<m>)|(?(+1)$)(.))+
)+\k<m>
(?!\X{0,70}((?(1)p|k)(?=(?3){7}(?2)?(?(1)K|P))|(?i:(?<E>(?!(?6))K)?((?(E)|((?6)[BQ]))(()?((?(-1)-)(?3){7}(?(-2)(?2)))+)(?(E)(?-4))|(?(E)|((?6)[RQ]))(-*|((?(-1)-)(?3){8})+)(?(E)(?-3))|(?(E)|((?6)N))((?<=..)(?2){3}|(?=.)(?2){5}|(?2){8}(?2)?)(?(E)(?-2)))(?(E)|(?&E))|K((?3){7,9})?K)))

Probieren Sie es online!

Hübsch gedruckt und teilweise ungolfed (die absoluten Rückreferenzen wurden in relative und die Erfassungsgruppen in nicht erfassende oder in einigen Fällen aus Gründen der Geschwindigkeit atomare Gruppen geändert):

# Chess move validation regex (PCRE)
()?                 # decide whether to evaluate this as white's or black's move; \1 set = white, \1 unset (NPCG) = black
(?>|                # subroutines:
  ((.|\n(?=.)){2})                  # (?3) = for moving within the board, without wrapping to the next board, (?2) = (?3){2}
  ((?=                              # (?4) = assert that position of just-consumed piece is vacated on the next turn
    (\X{72})                        # (?5) = skip to the position of the just-consumed piece on the next turn
  -))
  ((?=(?(1)[-a-z]|[-A-Z])))         # (?6) = assert that the piece at the current position belongs to the current player's opponent or is empty
  ((?5)(?(?=(.*\n)\n)[qnrb]|p))     # (?7) = black pawn that might be promoted, (?8) = .*\n
  ((?5)(?(?=(?8){8}\n)[QNRB]|P))    # (?9) = white pawn that might be promoted
)
(?>
  (?>
    # Handle squares that don't change (empty->empty or pieces that doesn't move)
    (.)(?=(?5)\g{-1}) |
    # Handle a piece that moves (and optionally captures an enemy piece)
    (?(m)$)  # allow only one move to be made per turn
    (?>
      (?(1)
        (?:                                                         # white pawn
            -  (?=(?9))(?=(?3){8}((?3){9})?P(?4))(?(-1)(?=(?8){4}\n)) |   # move 1 or 2 spaces forward
          [a-z](?=(?9))(?=(?3){7}(?2)?     P(?4))                     )   # capture diagonally
      |
        (?:p(?4)(?:                                                 # black pawn
          (?=(?3){8}((?3){9})?  -  (?7))(?(-1)(?=(?8){7}\n)) |            # move 1 or 2 spaces forward
          (?=(?3){7}(?2)?     [A-Z](?7)) )                   )            # capture diagonally
      ) |
      # bishops, rooks, queens, knights, or kings
      (?<e>(?6).)?   # decide between scanning forward (<e> is unset) or backwards (<e> is captured)
      (?=
        (?i:
          (?|
            (?(e)|(B|Q)) (?&B)  (?(e)(B|Q)) | # bishops or queens
            (?(e)|(R|Q)) (?&R)  (?(e)(R|Q)) | # rooks or queens
            (?(e)|(N  )) (?&N)  (?(e)(N  )) | # knights
            (?(e)|(K  )) (?&K)? (?(e)(K  ))   # kings
          )
        )
        (?(e)(?<=(?!(?6)).)(?4)|(?6).(?5)\g{-2})   # verify that the piece moved, and optionally captured piece, are of the correct color
      )
      (?(e)(?=(?5)\g{-1})|(?!(?6)).(?4))   # verify that the piece moved is the same type and color at its destination in the next turn's board position
    )(?<m>) |
    (?(+1)$)(.)  # handle the destination/source square that a piece moved to/from (only allow matching one of these per turn)
  )+\n
)+
\k<m>         # assert that a move has taken place
\n
# don't allow moving into check  
(?!
  \X{0,70}
  (?:
    # pawns (capture diagonally)
    (?(1)p|k)(?=(?3){7}(?2)?(?(1)K|P)) |
    # bishops, rooks, queens, knights, or kings
    (?i:
      (?<E>(?!(?6))K)?   # decide between scanning forward (<E> is unset) or backwards (<E> is captured)
      (?:
        (?(E)|((?6)[BQ])) (?<B>()?((?(-1)-)(?3){7}(?(-2)(?2)))+)         (?(E)(?-4)) | # bishops or queens
        (?(E)|((?6)[RQ])) (?<R>-*|((?(-1)-)(?3){8})+)                    (?(E)(?-3)) | # rooks or queens
        (?(E)|((?6) N  )) (?<N>(?<=..)(?2){3}|(?=.)(?2){5}|(?2){8}(?2)?) (?(E)(?-2))   # knights
      )
      (?(E)|(?&E)) |
      K(?<K>(?3){7,9})?K   # kings
    )
  )
)

-88 Bytes durch Verwendung von nichtatomaren Unterprogrammaufrufen, wodurch ein erneutes Targeting von PCRE1 nach PCRE2 erfolgt

Die obige Version wurde modifiziert, um weder En passant noch Castling zuzulassen, aber das gesamte Projekt befindet sich derzeit in einem Zustand, in dem alle Arten von Zügen validiert werden, beginnend mit dem anfänglichen Board-Status (der die Standard-Schach-Startposition sein muss - Chess960 nicht) unterstützt, aber zumindest). Die vollständigen Regeln von en passant und castling werden eingehalten.

Hier ist ein Beispielspiel, das von der vollständigen Regex validiert wurde (PCRE1 - noch nicht neu ausgerichtet) [regex101.com] .

Ein ungültiger Zug führt dazu, dass jede nachfolgende Brettposition nicht übereinstimmt / hervorgehoben wird. Die Schachmatt- / Patt-Erkennung und damit die Erkennung, wer der Gewinner ist (oder ob es sich um ein Unentschieden handelt), ist noch nicht implementiert. Aus diesem Grund wird der endgültige Board-Status in diesem Beispiel nicht hervorgehoben.

Hier ist ein C / C ++ - Programm, das die algebraische Notation in das von dieser Regex erkannte Format konvertiert.Die algebraische Notation muss derzeit in Form eines Arrays in den Quellcode eingefügt werden, mit separaten Zeichenfolgen für jede Verschiebung, aber als einzelne Zeichenfolge aus stdin oder einem Befehlszeilenargument, wobei die gesamte Sequenz von Verschiebungen durch Leerzeichen getrennt ist und Punkt-terminierte Zugnummern sind geplant.

Ich habe auch mit einem regulären Ausdruck begonnen, der eine vollständige Partie rein in algebraischer Schachnotation validiert, wobei die Standardausgangsposition impliziert ist. Alles, was es braucht, ist ein leeres "Rubbellos", das am Ende der Eingabe angehängt wird (nach der Liste der Züge). Ich bin mir ziemlich sicher, dass es möglich ist, dies vollständig umzusetzen und es irgendwann fertigzustellen.

Deadcode
quelle
Ich habe mich seit dem Zeitpunkt, als ich eine 3000-Byte-Regex-Monstrosität für eine Sudoku-Validierungsfrage herausgesucht habe, nicht mehr so ​​sehr gefürchtet. Wirklich beweist der Punkt, dass manchmal, wenn Sie Regex verwenden, um ein Problem zu lösen, Sie mit zwei Problemen enden
Value Ink
@ValueInk Heh, vielleicht hast du recht, aber ich genieße es ungeachtet (oder vielleicht wegen) seiner völligen Unpraktikabilität. Ihr Kommentar hat mich dazu inspiriert, diese Sudoku-Frage zu beantworten, aber ich habe nur 200 Bytes geschafft . Naja.
Deadcode