Nom alternatif: ChessMoveQ
Étant donné une liste de 32 éléments au maximum, chacun composé de 4 éléments et une deuxième liste de 4 éléments, déterminez si le coup détaillé dans la deuxième entrée est un coup d'échecs valide.
La première liste indique la position des 32 pièces sur le plateau. Chaque élément suivra la structure <colour>, <piece-name>, <x-coord>, <y-coord>
, telle que ["W", "K", 5, 1]
, qui indique que le roi blanc est activé 5, 1
( e1
sur un échiquier normal). Tous les éléments de la première entrée seront uniques. <x-coord>
et <y-coord>
sera toujours compris entre 1 et 8. Un exemple serait:
[["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]]
qui représenterait le conseil:
La deuxième entrée sera constituée des mêmes structures que les sous-listes de la première, mais plutôt que les coordonnées x et y indiquant où se trouve la pièce, elles indiquent où elle essaie de se déplacer.
Pour l'exemple ci-dessus, un mouvement valide pourrait être ["W", "B", 4, 3]
(l'évêque se déplace d'un carré vers l'avant et vers la gauche), et un mouvement invalide pourrait être ["B", "R", 4, 1]
comme la tour devrait passer par le chevalier et le pion pour arriver au carré. Comme le mouvement peut parfois faire référence à plusieurs pièces, vous devez tester si l' une des pièces spécifiées peut effectuer le mouvement, pas seulement l'une d'entre elles. Par exemple, le premier exemple n'est valable que pour un seul évêque, mais c'est toujours un mouvement valable. Cependant, aucune tour noire ne peut effectuer le deuxième coup, elle n'est donc pas valide.
Votre tâche consiste à déterminer si le coup détaillé dans la deuxième entrée est un coup d'échecs valide. La validité d'une règle varie en fonction de la pièce essayant de se déplacer (cliquez sur le nom de la pièce pour un diagramme des mouvements valides):
- N'importe quelle pièce : aucune pièce ne peut se déplacer sur une case déjà occupée ou hors du plateau, à moins que cette case ne soit occupée par une pièce de l'autre couleur. Par exemple, une pièce blanche peut se déplacer sur un carré occupé par une pièce noire, mais pas une pièce blanche. De plus, aucune pièce, à l'exception des chevaliers, ne peut se déplacer vers des cases qui sont directement obstruées par une autre pièce.
- Un mouvement par pièce B à la case C est « bloqué directement » par pièce A si A est directement en ligne droite (perpendiculaire ou diagonale), entre B et C .
- N'importe quelle pièce : la position du roi peut également affecter la validité du mouvement d'une pièce. Si l'une de ces deux conditions est remplie, le déplacement n'est pas valide:
- Exposer le roi pour vérifier, en déplaçant une pièce du même côté que le roi en voie de disparition. Cela ne s'applique que si une pièce non opposée effectue le mouvement, plutôt qu'une pièce adverse se déplaçant pour mettre le roi en échec.
- Laisser le roi en échec, auquel cas il doit se retirer du contrôle. Par conséquent, si le roi est en échec et que le mouvement dicte qu'une autre pièce se déplace, c'est un mouvement invalide, à moins que l'autre pièce n'empêche le contrôle. Une pièce peut empêcher le contrôle de deux manières: soit elle prend la pièce effectuant le contrôle, soit elle obstrue le chemin entre la pièce effectuant le contrôle et le roi.
- Un «check» est une situation dans laquelle l'adversaire du roi peut (si c'était son tour de se déplacer) déplacer légalement une pièce sur ce roi. Cette règle ne s'applique pas récursivement, c'est-à-dire qu'un roi est en échec même si le mouvement de l'adversaire sur ce roi laisserait son propre roi en échec.
- Pions : Un pion peut se déplacer vers l'avant (c'est-à-dire vers le haut s'il est blanc, vers le bas s'il est noir) d'une case vers une case inoccupée. Il existe également trois situations particulières:
- Si le pion n'a pas encore bougé (vous pouvez le déterminer en utilisant la coordonnée Y; les pions blancs n'ont pas bougé si leur coordonnée Y est 2, les pions noirs n'ont pas bougé si leur coordonnée Y est 7), le pion est autorisé à avancer de deux cases vers une case inoccupée.
- S'il y a une pièce de l'adversaire en diagonale devant le pion (c'est-à-dire sur la case au nord-ouest ou au nord-est du pion si elle est blanche, ou au sud-ouest ou sud-est si elle est noire), le pion est autorisé à se déplacer sur la case occupée en question.
- Si un pion se déplace vers la coordonnée Y finale (8 pour le blanc ou 1 pour le noir) dans les règles d'échecs normales, il doit être promu reine, tour, chevalier ou évêque de la même couleur. Aux fins de cette question, le choix de la promotion n'a pas d'importance si le mouvement est valide ou non (et ne peut pas être exprimé dans le format d'entrée), mais les mouvements de pion qui entraîneraient une promotion doivent être autorisés.
- Évêques : les évêques peuvent se déplacer entre 1 et 8 carrés le long de n'importe quel chemin intercardinal (c'est-à-dire diagonal) continu non obstrué.
- Chevaliers : Les chevaliers peuvent se déplacer dans une
L
forme, consistant en l'un des mouvements (équivalents) suivants:- Un seul carré dans n'importe quelle direction cardinale, suivi d'un virage à 90/270 °, suivi d'un dernier déplacement de 2 carrés vers l'avant.
- 2 carrés dans n'importe quelle direction cardinale, suivis d'un virage à 90/270 °, suivi d'un mouvement final d'un seul carré vers l'avant.
- Tourelles : les tours peuvent se déplacer entre 1 et 8 carrés le long de tout chemin cardinal continu non obstrué.
- Reines : les reines peuvent se déplacer entre 1 et 8 carrés le long de tout chemin continu non obstrué cardinal ou intercardinal (c'est-à-dire diagonal).
- Rois : les rois se déplacent comme des reines, sauf qu'ils sont limités à ne déplacer qu'une case par mouvement (c'est-à-dire qu'un roi ne peut se déplacer que vers des cases adjacentes cardinalement ou diagonalement). Pour rappel, vous ne pouvez pas faire un mouvement qui laisse votre roi en échec; vous ne pouvez donc pas non plus mettre votre roi en échec.
Les règles d'échecs contiennent également des mouvements spéciaux appelés "roque" et "en passant". Cependant, parce que la légalité de ces mouvements dépend de l'histoire du jeu, pas seulement de la position actuelle (et parce que le roque nécessite de déplacer deux pièces à la fois, ce qui ne correspond pas au format d'entrée), vous ne devriez considérer aucun de ces mouvements exister (c'est-à-dire qu'un mouvement qui serait un roque ou en passant devrait être considéré comme illégal).
Vous pouvez générer deux résultats distincts pour indiquer la validité d'un déplacement, et vous pouvez saisir des données dans la méthode que vous souhaitez. Vous pouvez également choisir l'indexation 0 plutôt que l'indexation 1 pour les positions si vous préférez. C'est un code-golf , donc le code le plus court gagne!
Cas de test
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)
Ce défi a été mis en bac à sable . Il a reçu des downvotes, sans aucune explication, j'ai donc décidé de le poster quand même
la source
Réponses:
Python 2 (avec python-chess ),
141 138 134 133132 octetsSans faire le code vraiment intéressant - mais peut-être que cela peut rivaliser avec les langues de golf ou (oserais-je le mentionner) Mathematica?
Note: python-échecs est un Pypi package d' installation sur Python 2.7.9+ avec:
python -m pip install python-chess
)Un programme complet acceptant l'entrée de trois éléments:
PRNBQK
)a1
est0
,b1
est1
, ...a2
est8
, ...,h8
est63
,Le programme génère via son code de sortie une entrée valide:
1
si le mouvement est valide (le programme a généré une erreur - en raison de la division par zéro);0
ce n'est pas le cas (le programme s'est terminé normalement)(Ne fais pas) Essayez-le en ligne! (car le paquet python-chess n'y est pas installé et TIO n'autorise pas la connectivité Internet, donc le code pip-install dans l'en-tête ne fonctionnera pas).
Notez que l'opérateur de puissance en Python fait ,
1**1 == 1**0 == 0**0 == 1
mais0**1 == 0
... donc
1/0**1
soulève une division par zéro erreur tout1/1**1
,1/1**0
et1/0**0
tout réussit(... et qu'en Python
False
etTrue
équivaloir à0
et1
respectivement).la source
str(S.piece_at(m.from_square))==p for
enp==str(S.piece_at(m.from_square))for
, cela devrait économiser un octet.repr
backticks à utiliser pour remplacerstr
pour sauver ...Regex (PCRE2),
931925837 octetsCette solution s'écarte de l'énoncé du problème en ce que deux états de la carte sont passés à l'expression régulière, au lieu d'un état de la carte et d'un déplacement. Le mouvement est déduit de la différence entre les deux états du conseil d'administration. J'ai donc fait le travail du programme TIO pour prendre les cas de test dans le format fourni par cette question, trouver toutes les instances de la pièce décrite sur le tableau, et avec chacun, essayez de le déplacer vers la position de destination et d'évaluer le regex avec cette possibilité, en trouvant s'il y en a sont signalés par l'expression régulière comme valides. Si ce n'est pas correct, faites-le moi savoir; il est possible d'implémenter une regex comme position + mouvement, mais serait beaucoup moins élégant et nécessiterait une refactorisation sérieuse.
Le tableau est représenté en 8 × 8 ASCII où les morceaux blancs sont en majuscules et les noirs en minuscules: P awn, k N ight, B ishop, R ook, Q ueen, K ing. Le côté noir (le 8e rang) est en haut et le côté blanc (le 1er rang) est en bas. Chaque rang est séparé par une nouvelle ligne et les cases vides sont marquées comme
-
. Les deux positions du tableau sont séparées par une nouvelle ligne supplémentaire.Le but réel de ce projet est de valider des jeux entiers, pas seulement des mouvements simples. Voir ci-dessous l'état d'avancement actuel.
Essayez-le en ligne!
Assez imprimé et partiellement non golfé (les références absolues sont devenues relatives et les groupes de capture sont passés à non-capture, ou dans certains cas atomiques pour la vitesse):
-88 octets en utilisant des appels de sous-programme non atomiques, reciblant ainsi de PCRE1 à PCRE2
La version ci-dessus a été modifiée pour ne pas permettre le passage ou le roque, mais le projet complet est actuellement dans un état où il valide chaque type de mouvement, en commençant à l'état initial du plateau (qui doit être la position de départ standard des échecs - Chess960 n'est pas pris en charge, au moins). Les règles complètes en passant et en roque sont appliquées.
Voici un exemple de jeu validé par la regex complète (PCRE1 - pas encore reciblé) [regex101.com] .
Un mouvement invalide entraînera la non-correspondance / surbrillance de chaque position de plateau suivante. La détection d'échec / échec, et donc la détection de qui est le gagnant (ou s'il s'agit d'un match nul), n'est pas encore implémentée; c'est pourquoi l'état final de la carte dans cet exemple n'est pas mis en évidence.
Voici un programme C / C ++ qui convertit la notation algébrique dans le format reconnu par cette expression régulière. La notation algébrique doit actuellement être mise sous la forme d'un tableau en ligne dans le code source, avec des chaînes distinctes pour chaque mouvement, mais en la lisant comme une chaîne unique à partir de stdin ou un argument de ligne de commande, avec la séquence entière de mouvements séparés par des espaces et les numéros de mouvement terminés par des points, est prévu.
J'ai également commencé sur une expression régulière qui valide un jeu complet purement en notation d'échecs algébrique, avec la position initiale standard implicite. Tout ce dont il a besoin est un "scratch board" vide ajouté à la fin de l'entrée (après la liste des coups). Je suis à peu près sûr qu'il est possible de l'implémenter dans son intégralité et que je prévois de le terminer un jour.
la source