Los juegos de aventura de texto tienen una fórmula bastante establecida; Hay un mundo compuesto por una serie de habitaciones / espacios, el jugador puede moverse por estas habitaciones, y hay algunos elementos en las habitaciones. El jugador puede recoger los elementos, dejarlos en el suelo, usarlos para acceder a otras habitaciones (p. Ej., Llaves) y combinarlos con otros elementos para crear nuevos elementos.
Desafío
Su desafío es escribir un tiempo de ejecución de aventura de texto en la menor cantidad de bytes (código de golf). Para simplificar las cosas, todo lo que necesita hacer es generar un valor verdadero o falso dependiendo de si una serie dada de comandos ganaría un juego determinado o no (sin interactividad, sin salida amigable para los humanos, etc.)
Reglas del juego
- El mundo siempre está compuesto por un corredor con 10 habitaciones conectadas. Cada habitación requiere una llave para entrar, pero se puede salir en cualquier momento sin una llave (por lo que supongo que es una especie de cerradura);
- El jugador comienza en la sala 0 y gana si alguna vez ingresa a la sala 9 (una vez que llegue a la sala 9 pueden hacer lo que quieran, incluso ir a otra sala, y todavía habrán ganado);
- Cada habitación puede contener cualquier cantidad de artículos;
- Hay hasta 26 elementos, llamados AZ, y ningún elemento aparecerá más de una vez en el mundo;
- El jugador puede recoger elementos de la sala actual y colocarlos en su inventario (también puede colocar elementos de su inventario en la sala actual);
- El tamaño máximo de inventario del jugador es finito y se le proporcionarán los detalles del nivel;
- Al comienzo del juego, el inventario del jugador siempre está vacío;
- No hay límite para el número máximo de elementos en una habitación (aunque el límite implícito sería 26, ya que ese es el número total de elementos);
- Los productos que AJ son llaves que se pueden utilizar para entrar en habitaciones 0-9 (es decir, el jugador puede mover a la habitación 0 si tienen punto A, a la habitación 1 si tienen B, etc. nota que las claves son no obligados a salir de una habitación, y el jugador comienza en la sala 0, por lo que la clave "A" solo se requiere si el jugador quiere regresar a la sala 0);
- Los elementos en el inventario del jugador se pueden combinar para crear nuevos elementos (que se crearán en el inventario del jugador): las combinaciones permitidas se proporcionarán con los detalles del nivel;
- La combinación de elementos consume los elementos originales (es decir, si uno de los elementos era una clave, ya no será posible usar esa clave);
- Si el jugador intenta hacer algo imposible (p. Ej., Recoger un elemento que no está en la habitación actual / soltar un elemento que no tiene / combinar elementos que no tiene / ir a una habitación que no tiene la llave) para), no pasa nada y pueden continuar;
- El jugador nunca dará una orden sin sentido (por ejemplo, vaya a la sala 11).
Entonces, un juego simple podría verse así:
v
+---+---+---+---+---+---+---+---+---+---+
| C | | J | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+
| CORRIDOR |
+---------------------------------------+
Inventory capacity: 99
La sala 0 contiene el elemento "C" (que es la clave de la sala 2). La sala 2 contiene el elemento "J" (que es la clave de la sala 9). El jugador puede ganar el juego recogiendo C, moviéndose a la sala 2, recogiendo J y luego moviéndose a la sala 9.
Un juego más complejo podría ser:
v
+---+---+---+---+---+---+---+---+---+---+
| C | | X |YZ | | | | | | |
+---+---+---+---+---+---+---+---+---+---+
| CORRIDOR |
+---------------------------------------+
Inventory capacity: 10
C+X => D
Y+Z => J
Ahora el jugador puede ganar recogiendo C, moviéndose a la sala 2, recogiendo X, combinando C con X para crear D, luego moviéndose a la sala 3. Ahora pueden recoger y combinar Y y Z para obtener J, lo que les permite ve a la habitación 9.
Formato de entrada
Hay un poco de entrada para manejar, y esa es una tarea bastante aburrida, por lo que el formato de entrada es muy flexible. Obtendrá los siguientes datos, y cómo debe enviarlos a su programa depende en gran medida de usted:
- El contenido inicial de cada habitación (lista de 0 o más elementos para cada habitación);
- Una colección de combinaciones de elementos permitidos (cada uno contiene 2 elementos de entrada y su elemento de salida; tenga en cuenta que los elementos de entrada no están ordenados);
- El tamaño máximo de inventario (entero, 0 <= tamaño <= 26);
- La lista de comandos que el jugador intentó.
Los comandos del jugador pueden ser:
[P]ick up <item>
- recoge un objeto de la sala y lo coloca en el inventario del jugador (si hay espacio)[D]rop <item>
- deja caer un elemento del inventario del jugador en la sala actual[C]ombine <item1> <item2>
- combina 2 artículos en el inventario del jugador para producir un nuevo artículo[G]o to <room>
- viaja a la habitación elegida si el jugador tiene la llave requerida
Por ejemplo, el formato de entrada que utilicé para probar era simples argumentos de programa:
./adventure YZ '' '' '' '' '' '' '' '' '' 1 YZJ 2 PY PZ CYZ G9
# r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 combinations inv. size commands...
# means:
# room 0 starts with items Y & Z, all other rooms start empty
# 1 combination is possible: Y+Z => J
# max inventory size is 2
# player commands are [P]ick up Y, [P]ick up Z, [C]ombine Y and Z, [G]o to room 9
# (in this example, the player wins)
Pero si algún otro formato lo hace más fácil, está bien (por ejemplo, caracteres delimitadores especiales / líneas múltiples / ordenamiento diferente / serializado a JSON / etc.)
Formato de salida
Su programa debería devolver un resultado verdadero si los comandos del jugador hacen que gane el juego, y algún resultado falso de lo contrario. Este podría ser un mensaje reconocible para stdout, un código de retorno del programa, o el idioma que elija. Todos los demás resultados serán ignorados.
Casos de prueba
El siguiente script bash proporciona un arnés de prueba que verificará la mayoría de las situaciones. Se ha escrito para usar el formato descrito anteriormente, pero modificarlo para usar un formato diferente es solo un caso de agregar una conversión en la invoke
función.
#!/bin/sh
PROG="$1";
if [[ -z "$PROG" ]]; then
echo "Usage: $0 <program-to-test>";
exit 1;
fi;
function invoke {
"$PROG" "$@"
}
RED="\033[1;31m";
GREEN="\033[1;32m";
RESET="\033[m";
FAILURES="0";
function pass {
if ! invoke "$@" >/dev/null 2>&1; then
echo "${RED}Expected pass, got fail:${RESET} $*" >&2;
(( FAILURES = "$FAILURES" + 1 ));
invoke "$@" 2>&1;
fi;
}
function fail {
if invoke "$@" >/dev/null 2>&1; then
echo "${RED}Expected fail, got pass:${RESET} $*" >&2;
(( FAILURES = "$FAILURES" + 1 ));
invoke "$@" 2>&1;
fi;
}
echo "Running tests...";
# R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 C I Cmd...
pass J '' '' '' '' '' '' '' '' '' 0 9 PJ G9;
fail '' J '' '' '' '' '' '' '' '' 0 9 PJ G9;
pass J '' '' '' '' '' '' '' '' '' 0 9 PJ PJ G9;
fail J '' '' '' '' '' '' '' '' '' 0 9 PJ;
fail J '' '' '' '' '' '' '' '' '' 0 9 G9;
pass J '' '' '' '' '' '' '' '' '' 0 9 G9 PJ G9;
pass J '' '' '' '' '' '' '' '' '' 0 1 PJ G9;
fail J '' '' '' '' '' '' '' '' '' 0 0 PJ G9;
fail J '' '' '' '' '' '' '' '' '' 0 9 PJ DJ G9;
fail J '' '' '' '' '' '' '' '' '' 0 9 PJ PJ DJ G9;
pass J '' '' '' '' '' '' '' '' '' 0 9 PJ DJ PJ G9;
pass J '' '' '' '' '' '' '' '' '' 0 9 PJ DJ PJ G9;
pass B CJ '' '' '' '' '' '' '' '' 0 2 PB G1 DB PC PJ G9;
fail B CJ '' '' '' '' '' '' '' '' 0 2 PB G1 DB PB PC PJ G9;
pass AJ '' '' '' '' '' '' '' '' '' 0 2 PA PJ G9;
pass B D '' J '' '' '' '' '' '' 0 2 PB G1 PD G3 DB PJ G9;
fail B D '' J '' '' '' '' '' '' 0 2 PB G1 PD G2 DB PJ G9;
fail B D '' J '' '' '' '' '' '' 0 2 PB G1 PD G3 PJ G9;
fail B D J C '' '' '' '' '' '' 0 2 PB G1 PD G3 PJ G9;
pass AJ '' '' '' '' '' '' '' '' '' 0 2 PA PJ G9 G0;
fail ADJ '' '' '' '' '' '' '' '' '' 0 3 PA PD PJ G3 DJ G0 PJ G9;
pass ADJ '' '' '' '' '' '' '' '' '' 0 3 PA PD PJ G3 DJ G0 G3 PJ G9;
fail ADJ '' '' '' '' '' '' '' '' '' 0 3 PA PD PJ G3 DJ G0 DD G3 PJ G9;
pass ADJ '' '' '' '' '' '' '' '' '' 0 3 PA PD PJ DD G3 DJ G0 DD G3 PJ G9;
fail ADJ '' '' '' '' '' '' '' '' '' 0 1 PA DA DA PD PJ G9;
pass ADJ '' '' '' '' '' '' '' '' '' 0 1 PA DA DA PJ G9;
fail ABCDEFGHIKLMNOPQRSTUVWXYZ J '' '' '' '' '' '' '' '' 0 26 PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PT PU PV PW PX PY PZ G9;
pass ABCDEFGHIJKLMNOPQRSTUVWXYZ '' '' '' '' '' '' '' '' '' 0 26 PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PT PU PV PW PX PY PZ G9;
fail YZJ '' '' '' '' '' '' '' '' '' 0 2 PY PZ CYZ PJ G9;
pass YZJ '' '' '' '' '' '' '' '' '' 1 YZW 2 PY PZ CYZ PJ G9;
pass YZJ '' '' '' '' '' '' '' '' '' 1 YZW 2 PY PZ CYZ PJ CWJ G9;
fail XYZJ '' '' '' '' '' '' '' '' '' 1 YZW 2 PY PZ CYZ PX PJ G9;
fail XYZJ '' '' '' '' '' '' '' '' '' 1 YZW 2 PY PZ CYZ PX DY DZ PJ G9;
pass XYZJ '' '' '' '' '' '' '' '' '' 1 YZW 2 PY PZ CYZ PX DW PJ G9;
pass YZ '' '' '' '' '' '' '' '' '' 1 YZJ 2 PY PZ CYZ G9;
fail YZ '' '' '' '' '' '' '' '' '' 1 YZJ 2 CYZ G9;
pass YZ '' '' '' '' '' '' '' '' '' 1 YZJ 2 PY PZ CYZ CYZ G9;
fail YZ '' '' '' '' '' '' '' '' '' 1 YZJ 2 PY PZ CYZ DJ CYZ G9;
fail YZ '' '' '' '' '' '' '' '' '' 1 YZJ 2 PY PZ CYZ DJ PY PZ CYZ G9;
fail WZ '' '' '' '' '' '' '' '' '' 1 YZJ 2 PW PZ CYZ G9;
fail WZ '' '' '' '' '' '' '' '' '' 1 YZJ 2 PY PZ CYZ G9;
pass YZ '' '' '' '' '' '' '' '' '' 1 YZJ 2 PY PZ CZY G9;
pass YZ '' '' '' '' '' '' '' '' '' 1 ZYJ 2 PY PZ CYZ G9;
fail YZ '' '' '' '' '' '' '' '' '' 1 YZJ 1 PY PZ CYZ G9;
fail YZ '' '' '' '' '' '' '' '' '' 1 YZJ 1 PY PZ CYZ PY PZ CYZ G9;
fail YZ '' '' '' '' '' '' '' '' '' 1 YZJ 1 PY PZ CYZ PJ G9;
fail YZ '' '' '' '' '' '' '' '' '' 1 YZJ 1 PJ G9;
pass BW UV '' '' '' '' '' '' '' '' 3 BUR WVS RSJ 2 PB PW G1 DW PU CBU DR PW PV CVW PR CRS G9;
fail BW AUV '' '' '' '' '' '' '' '' 3 BUR WVS RSJ 2 PB G1 PU CBU DR PA PB G0 DA PW G1 PV CVW PR CRS G9;
pass BCW AUV '' '' '' '' '' '' '' '' 3 CUR WVS RSJ 2 PB PC G1 DB PU CCU DR PC PA PB G0 DA PW G1 DB PV CVW PR CRS G9;
fail BCW UV '' '' '' '' '' '' '' '' 3 CUR WVS RSJ 2 PB PC G1 DB PU CCU DR PC PA PB G0 DA PW G1 DB PV CVW PR CRS G9;
fail BCW AUV '' '' '' '' '' '' '' '' 3 CUR WVS RSJ 2 PB PC G1 DB PU CCU PA PB G0 DA PW G1 DB PV CVW PR CRS G9;
fail BCW AUV '' '' '' '' '' '' '' '' 3 CUR WVS RSJ 2 PB PC G1 DB PU CCU DR PA G0 DA PW G1 DB PV CVW PR CRS G9;
fail BCW AUV '' '' '' '' '' '' '' '' 3 CUR WVS RSJ 2 PB PC G1 DB PU CCU DR PB G0 DA PW G1 DB PV CVW PR CRS G9;
fail BCW AUV '' '' '' '' '' '' '' '' 3 CUR WVS RSJ 2 PB PC G1 DB PU CCU DR PA PB G0 DA G1 DB PV CVW PR CRS G9;
fail BCW AUV '' '' '' '' '' '' '' '' 3 CUR WVS RSJ 2 PB PC G1 DB PU CCU DR PA PB G0 DA PW G1 DB CVW PR CRS G9;
pass BFK LG M N O CDE PQR U W '' 10 BPT CQS TSH HUI IWV VFA GRX MXZ ANY YZJ 5 \
PB PF PK G1 PL PG G6 DB DK DL G5 PC PD PE G6 DF G2 PM G6 DM DC G3 PN G4 PO G6 DN DO DD DE \
PB PP CBP PC PQ CCQ CTS G7 PU CUH G8 PW CWI G6 PF CVF PR PM PN CGR CMX CAN CYZ G9
fail BFK LG M N O CDE PQR U W '' 10 BPT CQS TSH HUI IWV VFA GRX MXZ ANY YZJ 5 \
PB PF PK G1 PL PG G6 DB DK DL G5 PC PD PE G6 DF G6 DM DC G3 PN G4 PO PM G6 DN DO DD DE \
PB PP CBP PC PQ CCQ CTS G7 PU CUH G8 PW CWI G6 PF CVF PR PM PN CGR CMX CAN CYZ G9
if (( "$FAILURES" == "0" )); then
echo "${GREEN}All tests passed${RESET}";
else
echo "${RED}Total failures: $FAILURES${RESET}";
fi;
Victorioso
Código de golf estándar: gana el código más corto (en bytes). Las entradas deben seguir las reglas del juego, lo que en la práctica significa que deben pasar todos los casos de prueba (se pueden agregar más pruebas si es necesario).