Nombre alternativo: ChessMoveQ
Dada una lista de hasta 32 elementos, cada uno compuesto por 4 elementos, y una segunda lista con 4 elementos, determine si el movimiento detallado en la segunda entrada es un movimiento de ajedrez válido.
La primera lista indica la posición de las 32 piezas en el tablero. Cada elemento seguirá la estructura <colour>, <piece-name>, <x-coord>, <y-coord>
, como ["W", "K", 5, 1]
, que indica que el rey blanco está encendido 5, 1
( e1
en un tablero de ajedrez normal). Todos los elementos de la primera entrada serán únicos. <x-coord>
y <y-coord>
siempre estará entre 1 y 8. Un ejemplo sería:
[["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]]
que representaría el tablero:
La segunda entrada consistirá en las mismas estructuras que las sublistas de la primera, pero en lugar de las coordenadas x e y que indican dónde está la pieza, están indicando hacia dónde intenta moverse.
Para el ejemplo anterior, un movimiento válido podría ser ["W", "B", 4, 3]
(el alfil se mueve un cuadrado hacia adelante y hacia la izquierda), y un movimiento no válido podría ser ["B", "R", 4, 1]
que la torre tendría que moverse a través del caballero y el peón para llegar al cuadrado. Como el movimiento podría referirse a varias piezas a veces, debe probar si alguna de las piezas especificadas puede realizar el movimiento, no solo una de ellas. Por ejemplo, el primer ejemplo es válido para un solo obispo, pero sigue siendo un movimiento válido. Sin embargo, ninguna torre negra puede realizar el segundo movimiento, por lo que no es válida.
Su tarea es determinar si el movimiento detallado en la segunda entrada es un movimiento de ajedrez válido. La validez de una regla varía, dependiendo de la pieza que intenta moverse (haga clic en el nombre de la pieza para ver un diagrama de movimientos válidos):
- Cualquier pieza : ninguna pieza puede moverse a una casilla ya ocupada o fuera del tablero, a menos que esa casilla esté ocupada por una pieza del otro color. Por ejemplo, una pieza blanca puede moverse sobre un cuadrado ocupado por una pieza negra, pero no una pieza blanca. Además, ninguna pieza, a excepción de los Caballeros, puede moverse a cuadrados directamente obstruidos por otra pieza.
- Un movimiento por pieza B de la plaza C es "directamente obstruido" por pieza A , si A es directamente, en una línea recta (ortogonal o diagonal), entre B y C .
- Cualquier pieza : la posición del rey también puede afectar la validez del movimiento de una pieza. Si se cumple alguna de estas dos condiciones, el movimiento no es válido:
- Exponiendo al rey para que controle, moviendo una pieza del mismo lado que el rey en peligro. Esto solo se aplica si una pieza no opuesta realiza el movimiento, en lugar de que una pieza opuesta se mueva para poner al rey en jaque.
- Dejar al rey bajo control, en cuyo caso tiene que salir de control. Por lo tanto, si el rey está bajo control y el movimiento dicta que otra pieza se mueve, es un movimiento no válido, a menos que la otra pieza impida el control. Una pieza puede evitar el control de una de dos maneras: toma la pieza que realiza el control o obstruye el camino entre la pieza que realiza el control y el rey.
- Un "chequeo" es una situación en la que el oponente del rey podría (si fuera su turno de moverse) mover legalmente una pieza sobre ese rey. Esta regla no se aplica de forma recursiva, es decir, un rey está bajo control incluso si el movimiento del oponente sobre ese rey dejaría a su propio rey bajo control.
- Peones : un peón puede moverse hacia adelante (es decir, hacia arriba si es blanco, hacia abajo si es negro) un cuadrado a un cuadrado desocupado. También hay tres situaciones especiales:
- Si el peón aún no se ha movido (puede determinar esto usando la coordenada Y; los peones blancos no se han movido si su coordenada Y es 2, los peones negros no se han movido si su coordenada Y es 7), el peón se le permite mover dos casillas hacia adelante a una casilla desocupada.
- Si hay una pieza del oponente en diagonal frente al peón (es decir, en el cuadrado al noroeste o al noreste del peón si es blanco, o al sur-oeste o sureste si es negro), el peón puede moverse hacia la casilla ocupada en cuestión.
- Si un peón se mueve a la coordenada Y final (8 para blanco o 1 para negro) en las reglas normales de ajedrez, debe ser promovido a una reina, torre, caballero u obispo del mismo color. Para los propósitos de esta pregunta, la elección de la promoción es irrelevante para determinar si el movimiento es válido o no (y no puede expresarse en el formato de entrada), pero los movimientos de peón que darían lugar a la promoción deben ser permitidos.
- Obispos : los obispos pueden moverse entre 1 y 8 casillas a lo largo de cualquier camino intercardinal continuo (es decir, diagonal) no obstruido.
- Caballeros : los Caballeros pueden moverse en una
L
forma, que consiste en cualquiera de los siguientes movimientos (equivalentes):- Un solo cuadrado en cualquier dirección cardinal, seguido de un giro de 90/270 °, seguido de un movimiento final de 2 cuadrados hacia adelante.
- 2 casillas en cualquier dirección cardinal, seguidas de un giro de 90/270 °, seguido de un movimiento final de una única casilla hacia adelante.
- Grajos : Los grajos pueden moverse entre 1 y 8 casillas a lo largo de cualquier camino cardinal continuo no obstruido.
- Reinas : las reinas pueden moverse entre 1 y 8 casillas a lo largo de cualquier trayectoria continua sin obstrucción cardinal o intercardinal (es decir, diagonal).
- Reyes : los reyes se mueven como reinas, excepto que se limitan a mover solo un cuadro por movimiento (es decir, un rey solo puede moverse a cuadros adyacentes cardinal o diagonalmente). Como recordatorio, no puedes hacer un movimiento que deje a tu rey bajo control; por lo tanto, tampoco puedes mover a tu rey.
Las reglas del ajedrez también contienen movimientos especiales llamados "enroque" y "en passant". Sin embargo, debido a que la legalidad de estos movimientos depende de la historia del juego, no solo de la posición actual (y porque el enroque requiere mover dos piezas a la vez, lo que no encaja con el formato de entrada), no debes considerar ninguno de estos movimientos existir (es decir, un movimiento que sería enroque o pasajero debería considerarse ilegal).
Puede generar dos resultados distintos para indicar la validez de un movimiento, y puede tomar la entrada en el método que desee. También puede elegir la indexación 0 en lugar de la indexación 1 para las posiciones si lo prefiere. Este es un código de golf , por lo que gana el código más corto.
Casos de prueba
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)
Este desafío fue sandboxed . Recibió votos negativos, sin ninguna explicación, así que decidí publicarlo de todos modos
fuente
Respuestas:
Python 2 (con python-ajedrez ),
141 138 134 133132 bytesSin hacer ninguno de los códigos realmente interesantes, pero tal vez esto pueda competir con los idiomas de golf o (me atrevo a mencionarlo) ¿Mathematica?
Nota: python-ajedrez es un PyPI paquete de instalarlo en Python 2.7.9+ con:
python -m pip install python-chess
)Un programa completo que acepta la entrada de tres elementos:
PRNBQK
)a1
está0
,b1
es1
, ...a2
es8
, ...,h8
es63
,El programa sale a través de su código de salida con una entrada válida:
1
si el movimiento es válido (el programa generó un error debido a la división por cero);0
no lo es (el programa salió normalmente)(No) ¡ Pruébelo en línea! (porque el paquete python-chess no está instalado allí y TIO no permite la conectividad a Internet, por lo que el código de instalación pip en el encabezado no funcionará).
Tenga en cuenta que el operador de energía en Python hace
1**1 == 1**0 == 0**0 == 1
pero0**1 == 0
... por lo tanto,
1/0**1
plantea una división por error cero, mientras que1/1**1
,1/1**0
y1/0**0
todos tienen éxito(... y que en Python
False
yTrue
equiparar a0
y1
, respectivamente).fuente
str(S.piece_at(m.from_square))==p for
ap==str(S.piece_at(m.from_square))for
, eso debería ahorrar un byte.repr
uso de backticks para reemplazarstr
y salvar ...Regex (PCRE2),
931925837 bytesEsta solución parte de la declaración del problema en que dos estados de la placa se pasan a la expresión regular, en lugar de un estado de la placa y un movimiento. El movimiento se infiere de la diferencia entre los dos estados del tablero. Así que hice el trabajo del programa TIO tomar los casos de prueba en el formato provisto por esta pregunta, encontrar todas las instancias de la pieza descrita en el tablero y, con cada una, intentar moverla a la posición de destino y evaluar la expresión regular. con esa posibilidad, encontrar si alguna de las expresiones regulares es reportada como válida. Si esto no está bien, avíseme; es posible implementar una expresión regular como posición + movimiento, pero sería mucho menos elegante y requeriría una refactorización seria.
El tablero está representado en 8 × 8 ASCII donde las piezas blancas son mayúsculas y las negras minúsculas: P awn, k N ight, B ishop, R ook, Q ueen, K ing. El lado negro (el octavo rango) está en la parte superior y el lado blanco (el primer rango) está en la parte inferior. Cada rango está separado por una nueva línea, y los cuadrados vacíos se marcan como
-
. Las dos posiciones del tablero están separadas por una nueva línea adicional.El objetivo real de este proyecto es validar juegos completos, no solo movimientos individuales. Vea a continuación el estado actual de progreso.
Pruébalo en línea!
Bonito impreso y parcialmente sin gofres (los reflujos absolutos cambiaron a relativos, y los grupos de captura cambiaron a no capturar, o en algunos casos a la velocidad atómica):
-88 bytes utilizando llamadas de subrutina no atómicas, reorientando de PCRE1 a PCRE2
La versión anterior se ha modificado para que no permita el paso o el enroque, pero el proyecto completo se encuentra actualmente en un estado en el que valida cada tipo de movimiento, comenzando en el estado inicial del tablero (que debe ser la posición de inicio estándar del ajedrez: Chess960 no está compatible, pero al menos). Se aplican las reglas completas de en passant y enroque.
Aquí hay un juego de muestra validado por la expresión regular completa (PCRE1 - aún no reorientada) [regex101.com] .
Un movimiento no válido dará como resultado que cada posición posterior del tablero no coincida / destaque. La detección de jaque mate / estancamiento, y por lo tanto la detección de quién es el ganador (o si es un empate), aún no se ha implementado; Es por eso que el estado final del tablero en este ejemplo no está resaltado.
Aquí hay un programa C / C ++ que convierte la notación algebraica en el formato reconocido por esta expresión regular.La notación algebraica actualmente se debe poner en forma de matriz en línea en el código fuente, con cadenas separadas para cada movimiento, pero leyéndola como una sola cadena de stdin o un argumento de línea de comandos, con la secuencia completa de movimientos separados por espacios y los números de movimiento terminados en puntos, está planeado
También comencé con una expresión regular que valida un juego completo únicamente en notación algebraica de ajedrez, con la posición inicial estándar implícita. Todo lo que necesita es un "tablero de memoria virtual" vacío al final de la entrada (después de la lista de movimientos). Estoy bastante seguro de que es posible implementar esto por completo, y planeo terminarlo en algún momento.
fuente