Хватит ходить в стены!


16

Некоторые текстовые мошеннические лайки не позволяют вам войти в стену и дают вам возможность вернуться, если вы попытаетесь это сделать. Зачем это делать, когда вы можете заставить игрока двигаться в ближайшем правильном направлении?

Соревнование

Напишите программу функций, которая, учитывая направление и сетку символов 3 на 3, выводит ту же сетку после того, как игрок сделал шаг.

Например,

9
#..
.@#
#.#

становится

#.@
..#
#.#

вход

  • Направление задается одной цифрой от 1 до 9, каждое из которых соответствует 8 основным направлениям и стоит на месте. Это получено из относительных местоположений чисел на клавиатуре:

    NW N NE
    .. \ | /
    ... 7 8 9
    W- 4 5 6 -E
    ... 1 2 3
    ../ | \
    SW S SE
    
    Однако вы также можете использовать цифры 123, 456, 789 вместо 789, 456, 123. Другими словами, вы можете поменять местами верхние и нижние 2 строки или цифры, если вы того пожелаете. Это только две приемлемые комбинации индексов.

  • Сетка 3 на 3 будет состоять из 3 различных печатных символов ASCII, представляющих проходной пол, стены и игрока. (В тестовых примерах .используется для пола, #s - стены, и @является игроком)

  • Вы можете выбрать, какие символы использует ваша программа, но вы должны указать их в своем ответе, и они должны быть согласованы в нескольких испытаниях.
  • Символ, представляющий персонажа, всегда будет в середине сетки 3 на 3, а направление всегда будет между 1 и 9 (вкл.)
  • Вы можете принять участие в любом порядке
  • Сетка 3 на 3 может быть введена как массив символов, массив строк, строка длиной 9 или другая разумная альтернатива.

Выход

  • Возврат из функции или вывод в StdOut или ближайшую альтернативу
  • Пробелы и переводы строки разрешены
  • Вы должны использовать те же представления символов, что и для ввода
  • Те же форматы, разрешенные для входов, разрешены для выходов

Как игрок движется

Если указанное направление заблокировано стеной (например, если в приведенном выше примере было направление 6), то посмотрите на 2 ближайших направления:

  • Если одно (и только одно) направление свободно, переместите игрока в этом направлении.
  • Если нет свободных направлений, посмотрите на ближайшие 2 направления (исключая направление 5). Если вы завернули все вокруг и не нашли открытого направления (игрок окружен стенами), не двигайте игрока
  • Если оба направления открыты, выберите одно, чтобы перейти к нему случайным образом (хотя и не обязательно равномерно).

Если данное направление 5, не двигайте игрока

Контрольные примеры

( #= стена, .= пол, @= игрок)

Входные данные:

9
# ..
. @ #
#. #

Выход:

#. @
.. #
#. #


Входные данные:

3
# ..
. @ #
#. #

Выход:

# ..
.. #
# @ #


Входные данные:

7
##.
# @ #
.. #

Выход:

## @ ##.
#.# или #.#
.. # @. #


Входные данные:

5
...
. @.
...

Выход:

...
. @.
...


Входные данные:

2
###
# @ #
###

Выход:

###
# @ #
###

счет

Это , поэтому выигрывает самый короткий ответ в байтах.


Не используете yuhjklbn? ПОКОЙСЯ С МИРОМ.
Rɪᴋᴇʀ

Кроме того, мне не очень нравится часть "выбрать альтернативное направление". Это немного отличается от другой части задачи, которая заключается в «перемещении игрока в указанном направлении и выходе». Это просто личное предпочтение, хотя.
Rɪᴋᴇʀ

1
Эта часть сбивает с толку: «Если нет свободных направлений, посмотрите на следующие 2 ближайших направления».
Утренняя монахиня

1
Можем ли мы назначить число вместо символа ASCII для каждого элемента, а затем принять ввод как двумерный список? Или они должны быть строками?
Скотт Милнер

2
Могу ли я использовать указания 123;456;789вместо 789;456;123?
Утренняя монахиня

Ответы:


2

Pyth - 73 70 байт

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

Попытайся

Ввод состоит из двух строк:

1-я строка: направление движения

2-я строка: доска (позиции 123456789, 123 - верхний ряд)


3

JavaScript (ES6), 192 163 байта

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)

Примечания

Эта функция использует специальный формат ввода. Первый вход представляет собой массив целых чисел ( 0для floor, 1для wallи 2для player), представляющих карту. Вторым входом является (перевернутое) направление: 1это северо-запад, 2север, 3северо-восток, 4запад и т. Д. Входные данные должны быть представлены через синтаксис карри ( Z(a)(b)).

Контрольные примеры

Карты и направления были изменены в соответствии с моим форматом ввода.

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


1

Python 3, 120 104 153 176 175 байтов

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

Попробуйте онлайн!

Этот метод получает направление и список '.', '#' И '@'. Индексы начинаются с 1 до 9 (с 0 до 8 в списке). Так оно имеет вид

123 
456
789 

Метод возврата нового списка с новыми позициями.

Эта линия

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)

возвращает список этого типа:

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

Мы рассчитываем расстояния до свободных точек и добавляем случайность. Потому что ord('#') <= ord('.') - 8 and ord('.') + 8 <= ord('@')мы можем сказать, что ближайший "." для n = 7 (индекс в списке) имеет индекс 8.

введите описание изображения здесь

Пример:

>>> f(9, ['#','.','.','.','@','#','#','.','#'])
['#', '.', '.', '.', '.', '#', '#', '@', '#']
>>> f(3, ['#','.','.','.','@','#','#','.','#'])
['#', '.', '@', '.', '.', '#', '#', '.', '#']
>>> f(5, ['.','.','#','.','@','.','#','.','#'])
['.', '.', '#', '.', '@', '.', '#', '.', '#']
>>> f(7, ['#','#','#','#','@','#','#','#','#'])
['#', '#', '#', '#', '@', '#', '#', '#', '#']
>>> f(7, ['#','.','.','.','@','#','#','.','#'])
['#', '.', '.', '@', '.', '#', '#', '.', '#'] or ['#', '.', '.', '.', '.', '#', '#', '@', '#']

1) Это не работает для тестовых случаев, когда направление, в котором игрок хочет двигаться, занято и правильная позиция не первая ','(что имеет место в тестовых примерах 2, 3 и 5). 2) Ваш формат ввода / вывода не такой, как в вопросе. Пожалуйста, укажите ваш формат ввода / вывода.
Лука

Ваш пример f(9, ...не работает - он помещает символ в 2, но самые близкие позиции к 9 - это 6 и 8, поэтому один из них должен выбираться случайным образом (в вашем коде также нет случайности). Кроме того, он должен обойти периметр, находя ближайший ближайший, поэтому f(9,list("####@#.##"))следует поместить персонажа в единственно возможное место (7 здесь).
Джонатан Аллан

Спасибо за указание на ошибки. Для меня новость заключается в том, что код l [4], l [l.index ('.')] = '. @' И l [l.index ('.')], L [4 знак равно разные
Кирилл Малышев

@JonathanAllan, сначала я не совсем понял правила. Я надеюсь, что смог исправить код правильно.
Кирилл Малышев

Все еще не правильно, нет. 1. пример f(9, ...должен вернуться list("#....##@#")(потому что 8 свободен и рядом с 9). 2. Нечто подобное f(9,list("####@.#.#"))должно иметь некоторый шанс вернуться list("####..#@#")(не всегда list("####.@#.#")), как указано «Если оба направления открыты, выберите одно, чтобы перейти к случайному направлению».
Джонатан Аллан
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.