Arrêtez de marcher dans les murs!

16

Certains voyous à base de texte ne vous laissent pas entrer dans les murs et vous permettent de revenir en arrière si vous essayez. Pourquoi faire cela quand vous pouvez faire bouger le joueur dans la direction valide la plus proche?

Le défi

Écrivez un programme de fonction qui, étant donné une direction et une grille de caractères 3 x 3, sort la même grille après que le joueur ait fait un pas.

Par exemple,

9
#..
.@#
#.#

devient

#.@
..#
#.#

Contribution

  • La direction est donnée par un seul chiffre de 1 à 9, chacun correspondant à 8 directions cardinales et immobile. Ceci est dérivé des emplacements relatifs des nombres sur un clavier:

    NW N NE
    .. \ | /
    ... 7 8 9
    W- 4 5 6 -E
    ... 1 2 3
    ../ | \
    SW S SE
    
    Cependant, vous pouvez également utiliser les nombres 123, 456, 789 au lieu de 789, 456, 123. En d'autres termes, vous pouvez permuter les 2 lignes ou numéros supérieurs et inférieurs si vous le souhaitez. Ce sont les 2 seules combinaisons d'indices acceptables.

  • La grille 3 x 3 sera composée de 3 caractères ASCII imprimables distincts représentant le sol, les murs et le lecteur. (Dans les cas de test, .est utilisé pour le sol, #s sont des murs et @est le joueur)

  • Vous pouvez choisir les caractères que votre programme utilise, mais vous devez les indiquer dans votre réponse et ils doivent être cohérents sur plusieurs essais.
  • Le personnage représentant le personnage sera toujours au milieu de la grille 3 par 3, et la direction sera toujours entre 1 et 9 (incl.)
  • Vous pouvez prendre des informations dans n'importe quel ordre
  • La grille 3 par 3 peut être entrée comme un tableau de caractères, un tableau de chaînes, une chaîne de 9 longueurs ou une autre alternative raisonnable.

Production

  • Retour d'une fonction ou sortie vers StdOut ou l'alternative la plus proche
  • Les espaces de fin et les nouvelles lignes sont autorisés
  • Vous devez utiliser les mêmes représentations de caractères que l'entrée
  • Les mêmes formats autorisés pour les entrées sont autorisés pour les sorties

Comment se déplace le joueur

Si la direction spécifiée est bloquée par un mur (par exemple si l'exemple ci-dessus avait la direction 6), regardez les 2 directions les plus proches:

  • Si une (et une seule) direction est libre, déplacez le joueur dans cette direction.
  • Si aucune direction n'est libre, regardez les 2 directions les plus proches (sauf la direction 5). Si vous vous êtes enroulé tout autour et n'avez trouvé aucune direction ouverte (joueur entouré de murs), ne déplacez pas le joueur
  • Si les deux directions sont ouvertes, choisissez-en une pour vous déplacer au hasard (mais pas nécessairement uniformément).

Si la direction donnée est un 5, ne déplacez pas le joueur

Cas de test

( #= mur, .= sol, @= joueur)

Contribution:

9
# ..
. @ #
#. #

Production:

#. @
.. #
#. #


Contribution:

3
# ..
. @ #
#. #

Production:

# ..
.. #
# @ #


Contribution:

sept
##.
# @ #
.. #

Production:

## @ ##.
#.# ou #.#
.. # @. #


Contribution:

5
...
. @.
...

Production:

...
. @.
...


Contribution:

2
###
# @ #
###

Production:

###
# @ #
###

Notation

Il s'agit de , donc la réponse la plus courte en octets l'emporte.

MildlyMilquetoast
la source
Vous n'utilisez pas yuhjklbn? DÉCHIRURE.
Rɪᴋᴇʀ
De plus, je n'aime pas vraiment la partie "choisir une autre direction". C'est un peu différent de l'autre partie du défi, qui est de "déplacer le joueur dans une direction et une sortie spécifiées". Mais ce n'est qu'une préférence personnelle.
Rɪᴋᴇʀ
1
Cette partie prête à confusion: "Si aucune direction n'est libre, regardez les 2 directions les plus proches."
Leaky Nun
1
Pouvons-nous attribuer un numéro au lieu d'un caractère ASCII pour chaque élément, puis prendre l'entrée comme une liste bidimensionnelle? Ou doivent-ils être des chaînes?
Scott Milner
2
Puis-je utiliser les instructions 123;456;789au lieu de789;456;123 ?
Leaky Nun

Réponses:

2

Pyth - 73 70 octets

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

Essayez-le

L'entrée se compose de deux lignes:

1ère ligne: sens de déplacement

2e ligne: le tableau (positions 123456789, 123 étant la rangée du haut)

Maria
la source
3

JavaScript (ES6), 192 163 octets

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)

Remarques

Cette fonction utilise un format d'entrée spécial. La première entrée est un tableau d'entiers ( 0pour floor, 1pour wallet 2pour player) représentant la carte. La deuxième entrée est la direction (inversée): 1est nord-ouest, 2est nord, 3est nord-est,4 est ouest, etc. Les entrées doivent être fournies via la syntaxe de curry ( Z(a)(b)).

Cas de test

Les cartes et les directions ont été modifiées pour convenir à mon format d'entrée.

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]))
}

Luc
la source
1

Python 3, 120 104 104 153 176 175 octets

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

Essayez-le en ligne!

Cette méthode obtient la direction et la liste des '.', '#' Et '@'. Les index commencent par 1 à 9 (avec vraiment 0 à 8 dans la liste). Il a donc la forme

123 
456
789 

La méthode retourne une nouvelle liste avec de nouvelles positions.

Cette ligne

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)

renvoie une liste de ce type:

>>>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, '#')]

Nous calculons les distances aux points libres et ajoutons de l'aléatoire. Parce que ord('#') <= ord('.') - 8 and ord('.') + 8 <= ord('@')nous pouvons dire que le «plus proche». pour n = 7 (index dans la liste) a un index de 8.

entrez la description de l'image ici

Exemple:

>>> f(9, ['#','.','.','.','@','#','#','.','#'])
['#', '.', '.', '.', '.', '#', '#', '@', '#']
>>> f(3, ['#','.','.','.','@','#','#','.','#'])
['#', '.', '@', '.', '.', '#', '#', '.', '#']
>>> f(5, ['.','.','#','.','@','.','#','.','#'])
['.', '.', '#', '.', '@', '.', '#', '.', '#']
>>> f(7, ['#','#','#','#','@','#','#','#','#'])
['#', '#', '#', '#', '@', '#', '#', '#', '#']
>>> f(7, ['#','.','.','.','@','#','#','.','#'])
['#', '.', '.', '@', '.', '#', '#', '.', '#'] or ['#', '.', '.', '.', '.', '#', '#', '@', '#']
Кирилл Малышев
la source
1) Cela ne fonctionne pas pour les cas de test où la direction dans laquelle le joueur veut se déplacer est occupée et la position correcte n'est pas la première ','(ce qui est le cas pour les cas de test 2, 3 et 5). 2) Votre format d'E / S ne semble pas être le même que dans la question. Veuillez mentionner votre format d'E / S.
Luke
Votre exemple f(9, ...ne fonctionne pas - il place le caractère à 2 mais les positions les plus proches de 9 sont 6 et 8, donc l'une d'entre elles doit être choisie au hasard (il n'y a pas non plus de caractère aléatoire dans votre code). De plus, il devrait ensuite faire le tour du périmètre pour trouver le prochain plus proche, donc f(9,list("####@#.##"))placer le personnage dans le seul endroit possible (7 ici).
Jonathan Allan
Merci d'avoir signalé des erreurs Pour moi, la nouvelle est que le code l [4], l [l.index ('.')] = '. @' Et l [l.index ('.')], L [4 ] = '@.' sont différents
Кирилл Малышев
@JonathanAllan, au début je n'ai pas bien compris les règles. J'espère que je pourrais corriger le code correctement.
Кирилл Малышев
Toujours pas correct, non. 1. l'exemple f(9, ...devrait revenir list("#....##@#")(car 8 est gratuit et à côté de 9). 2. Quelque chose comme f(9,list("####@.#.#"))devrait avoir une chance de revenir list("####..#@#")(pas toujours list("####.@#.#")) comme spécifié "Si les deux directions sont ouvertes, choisissez-en une vers laquelle se déplacer au hasard".
Jonathan Allan