¡Deja de caminar hacia las paredes!

16

Algunos `` me gusta '' basados ​​en texto no te permiten caminar hacia las paredes y te permiten retroceder si lo intentas. ¿Por qué hacer eso cuando puedes hacer que el jugador se mueva en la dirección válida más cercana?

El reto

Escriba un programa de función que, dada una dirección y una cuadrícula de caracteres de 3 por 3, genere la misma cuadrícula después de que el jugador haya dado un paso.

Por ejemplo,

9
#..
.@#
#.#

se convierte

#.@
..#
#.#

Entrada

  • La dirección viene dada por un solo dígito del 1 al 9, cada uno correspondiente a 8 direcciones cardinales y detenido. Esto se deriva de las ubicaciones relativas de los números en un teclado:

    NW N NE
    .. \ | / /
    ... 7 8 9
    W- 4 5 6 -E
    ... 1 2 3
    ../ | \
    SW S SE
    
    Sin embargo, también puede usar los números 123, 456, 789 en lugar de 789, 456, 123. En otras palabras, puede intercambiar las 2 filas o números superiores e inferiores si así lo desea. Estas son las únicas 2 combinaciones de índice aceptables.

  • La cuadrícula de 3 por 3 constará de 3 caracteres ASCII distintos e imprimibles que representan el piso, las paredes y el jugador que se pueden caminar. (En los casos de prueba, .se usa para piso, #s son paredes y @es el jugador)

  • Puede elegir qué caracteres usa su programa, pero debe indicarlos en su respuesta y deben ser consistentes en varias pruebas.
  • El personaje que representa al personaje siempre estará en el medio de la cuadrícula de 3 por 3, y la dirección siempre estará entre 1 y 9 (incl.)
  • Puede tomar entrada en cualquier orden
  • La cuadrícula de 3 por 3 se puede ingresar como una matriz de caracteres, una matriz de cadenas, una cadena de 9 longitudes u otra alternativa razonable.

Salida

  • Regresar de una función o salida a StdOut o la alternativa más cercana
  • Se permiten espacios finales y líneas nuevas
  • Debe usar las mismas representaciones de caracteres que la entrada
  • Los mismos formatos permitidos para entradas están permitidos para salidas

Cómo se mueve el jugador

Si la dirección especificada está bloqueada por un muro (por ejemplo, si el ejemplo anterior tenía la dirección 6), mire las 2 direcciones más cercanas:

  • Si una (y solo una) dirección es libre, mueva al jugador en esa dirección.
  • Si no hay direcciones libres, mira las siguientes 2 direcciones más cercanas (excluyendo la dirección 5). Si has dado la vuelta y no has encontrado una dirección abierta (jugador rodeado de paredes), no muevas al jugador
  • Si ambas direcciones están abiertas, elija una para moverse al azar (aunque no necesariamente de manera uniforme).

Si la dirección dada es un 5, no muevas al jugador

Casos de prueba

( #= pared, .= piso, @= jugador)

Entrada:

9 9
# ..
. @ #
#. #

Salida:

#. @
.. #
#. #


Entrada:

3
# ..
. @ #
#. #

Salida:

# ..
.. #
# @ #


Entrada:

7 7
##.
# @ #
.. #

Salida:

## @ ##.
#. # o #. #
.. # @. #


Entrada:

5 5
...
. @.
...

Salida:

...
. @.
...


Entrada:

2
###
# @ #
###

Salida:

###
# @ #
###

Puntuación

Este es el , por lo que gana la respuesta más corta en bytes.

Levemente Milquetoast
fuente
¿No estás usando yuhjklbn? Q.E.P.D.
Rɪᴋᴇʀ
Además, no me gusta tanto la parte de "elegir una dirección alternativa". Es un poco diferente de la otra parte del desafío, que es "mover al jugador en una dirección y salida específicas". Sin embargo, eso es solo preferencia personal.
Rɪᴋᴇʀ
1
Esta parte es confusa: "Si no hay direcciones libres, mira las siguientes 2 direcciones más cercanas".
Leaky Nun
1
¿Podemos asignar un número en lugar de un carácter ASCII para cada elemento, luego tomar la entrada como una lista bidimensional? ¿O tienen que ser cuerdas?
Scott Milner
2
¿Puedo usar las instrucciones en 123;456;789lugar de 789;456;123?
Leaky Nun

Respuestas:

2

Pyth - 73 70 bytes

Kmsd"78963214"DPGJXXYt@K+xKQG\@4\.R?q/J\#/Y\#Jk=YwV5=GflTmPd(N_N)IGOGB

Intentalo

La entrada consta de dos líneas:

1a línea: dirección del movimiento

Segunda línea: el tablero (posiciones 123456789, siendo 123 la fila superior)

Maria
fuente
3

JavaScript (ES6), 192 163 bytes

a=>b=>a[(a[4]=0)+--b]?(A=(c,d)=>c==b|(e=a[c])-(f=a[d])|!e?(a[c-b?(e?e<f:new Date&1)?c:d:4]=2,a):A(+g[c],+h[d]))(+(g="3016X2785")[b],+(h="1250X8367")[b]):(a[b]=2,a)

Notas

Esta función utiliza un formato de entrada especial. La primera entrada es una matriz de enteros ( 0para floor, 1para wally 2para player) que representan el mapa. La segunda entrada es la dirección (invertida): 1es noroeste, 2es norte, 3es noreste, 4es oeste, etc. Las entradas deben darse a través de la sintaxis de curry ( Z(a)(b)).

Casos de prueba

Los mapas y las direcciones se han modificado para adaptarse a mi formato de entrada.

Z=
a=>b=>a[(a[4]=0)+--b]?(A=(c,d)=>c==b|(e=a[c])-(f=a[d])|!e?(a[c-b?(e?e<f:new Date&1)?c:d:4]=2,a):A(+g[c],+h[d]))(+(g="3016X2785")[b],+(h="1250X8367")[b]):(a[b]=2,a)

testcases = [
    [[1,0,0,0,2,1,1,0,1], 3],
    [[1,0,0,0,2,1,1,0,1], 9],
    [[1,1,0,1,2,1,0,0,1], 1],
    [[0,0,0,0,2,0,0,0,0], 5],
    [[1,1,1,1,2,1,1,1,1], 2]
]
for (test of testcases) {
    console.log(Z(test[0])(test[1]))
}

Luke
fuente
1

Python 3, 120 104 153 176 175 bytes

def f(n,l):
 n-=1
 if n!=4and'.'in l:l[sorted(enumerate(l),key=lambda x:abs(x[0]%3-n%3+(x[0]//3-n//3)*1j)-ord(x[1])-__import__('random').random()/9)[1][0]],l[4]='@.'
 return l

Pruébalo en línea!

Este método obtiene la dirección y la lista de '.', '#' Y '@'. Los índices comienzan con 1 a 9 (con 0 a 8 en la lista realmente). Entonces tiene la forma

123 
456
789 

Método devolver nueva lista con nuevas posiciones.

Esta línea

sorted(enumerate(l),key=lambda x:abs(x[0]%3-n%3+(x[0]//3-n//3)*1j)-ord(x[1])-__import__('random').random()/9)

devuelve una lista de este tipo:

>>>n=7
>>> l=['#','#','#','.','@','#','.','#','.']
>>> sorted(enumerate(l),key=lambda x:abs(x[0]%3-n%3+(x[0]//3-n//3)*1j)-ord(x[1])-__import__('random').random()/9)
[(4, '@'), (8, '.'), (6, '.'), (3, '.'), (7, '#'), (5, '#'), (1, '#'), (0, '#'), (2, '#')]

Calculamos distancias a puntos libres y agregamos aleatoriedad. Porque ord('#') <= ord('.') - 8 and ord('.') + 8 <= ord('@')podemos decir que el '.' Más cercano para n = 7 (índice en la lista) tiene un índice de 8.

ingrese la descripción de la imagen aquí

Ejemplo:

>>> f(9, ['#','.','.','.','@','#','#','.','#'])
['#', '.', '.', '.', '.', '#', '#', '@', '#']
>>> f(3, ['#','.','.','.','@','#','#','.','#'])
['#', '.', '@', '.', '.', '#', '#', '.', '#']
>>> f(5, ['.','.','#','.','@','.','#','.','#'])
['.', '.', '#', '.', '@', '.', '#', '.', '#']
>>> f(7, ['#','#','#','#','@','#','#','#','#'])
['#', '#', '#', '#', '@', '#', '#', '#', '#']
>>> f(7, ['#','.','.','.','@','#','#','.','#'])
['#', '.', '.', '@', '.', '#', '#', '.', '#'] or ['#', '.', '.', '.', '.', '#', '#', '@', '#']
Кирилл Малышев
fuente
1) Esto no funciona para los casos de prueba donde la dirección en la que el jugador quiere moverse está ocupada y la posición correcta no es la primera ','(que es el caso para los casos de prueba 2, 3 y 5). 2) Su formato de E / S no parece ser el mismo que en la pregunta. Por favor mencione su formato de E / S.
Lucas
Su ejemplo f(9, ...no funciona: coloca el personaje en 2, pero las posiciones más cercanas a 9 son 6 y 8, por lo que una de ellas debe seleccionarse al azar (tampoco hay aleatoriedad en su código). Además, debe rodear el perímetro para encontrar el siguiente más cercano, por lo que f(9,list("####@#.##"))debe colocar al personaje en el único lugar posible (7 aquí).
Jonathan Allan
Gracias por señalar errores. Para mí, la noticia es que el código l [4], l [l.index ('.')] = '. @' Y l [l.index ('.')], L [4 ] = '@.' son diferentes
Кирилл Малышев
@JonathanAllan, al principio no entendía las reglas. Espero poder corregir el código correctamente.
Кирилл Малышев
Todavía no es correcto, no. 1. el ejemplo f(9, ...debería volverlist("#....##@#") (porque 8 es gratis y junto a 9). 2. Algo así f(9,list("####@.#.#"))debería tener alguna posibilidad de regresar list("####..#@#")(no siempre list("####.@#.#")) como se especifica "Si ambas direcciones están abiertas, elija una para moverse al azar".
Jonathan Allan