Печать части 2D списка

#python #list #maze

#python #Список #Лабиринт

Вопрос:

Мне нужно создать игру-лабиринт, которая получает в качестве входных данных команду от пользователя, чтобы играть в игру. Я написал код для игры в лабиринт. Что я хочу изменить, так это показывать только часть лабиринта, когда он печатается пользователю (после выполнения перемещения). Вот лабиринт, который у меня есть:

 level = [
    ["1"," ","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1"],
    ["1"," "," ","1","1","1","1","1","1","1"," "," "," "," "," "," "," "," "," "," ","1","1","1","1","1"],
    ["1"," "," ","1","1","1","1","1","1","1"," "," ","1","1","1","1","1","1"," "," ","1","1","1","1","1"],
    ["1"," "," "," "," "," "," "," ","1","1"," "," ","1","1","1","1","1","1"," "," ","1","1","1","1","1"],
    ["1"," "," "," "," "," "," "," ","1","1"," "," ","1","1","1"," "," "," "," "," "," "," "," ","1","1"],
    ["1"," ","1","1","1","1"," "," ","1","1"," "," ","1","1","1"," "," "," "," "," "," "," "," ","1","1"],
    ["1"," ","1","1","1","1"," "," ","1","1"," "," ","1","1","1","1","1","1"," "," ","1","1","1","1","1"],
    ["1"," ","1","1","1","1"," "," ","1","1"," "," "," "," ","1","1","1","1"," "," ","1","1","1","1","1"],
    ["1"," "," ","1","1","1"," "," "," "," "," "," "," "," ","1","1","1","1"," "," "," "," "," "," ","1"],
    ["1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1"," ","1"]
]

start_maze = level[0][1]      #start of maze
end_maze = level[9][23]       #end of maze
  

С выводом как таковым:

 The initial configuration of the maze is:
1 X 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1     1 1 1 1 1 1 1                     1 1 1 1 1
1     1 1 1 1 1 1 1     1 1 1 1 1 1     1 1 1 1 1
1               1 1     1 1 1 1 1 1     1 1 1 1 1
1               1 1     1 1 1                 1 1
1   1 1 1 1     1 1     1 1 1                 1 1
1   1 1 1 1     1 1     1 1 1 1 1 1     1 1 1 1 1
1   1 1 1 1     1 1         1 1 1 1     1 1 1 1 1
1     1 1 1                 1 1 1 1             1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1   1
  

Как мне сделать так, чтобы игрок мог видеть только часть лабиринта при перемещении, вместо того, чтобы видеть конец (что упрощает задачу)?

Так, например, чтобы иметь такой вид, как этот:

     1   1 1 1
    1     1 1 
    1   X 1 1 
    1          
    1               
  

т. е. так, чтобы он мог видеть только 2 другие ячейки в каждом направлении.

Надеюсь, я прояснил вопрос. Ниже приведена часть кода, которая является основной игрой, если это необходимо:

 player = {'y': 0, 'x': 1}
level[player['y']][player['x']] = 'X'

# Translate keywords into coordinate changes
move_modifications = {'UP': {'y': -1, 'x': 0},
                      'DOWN': {'y': 1, 'x': 0},
                      'LEFT': {'y':0, 'x': -1},
                      'RIGHT': {'y': 0, 'x': 1}} 

def player_move(maze):

    # Main game loop
    play = True
    while play:
        move = input("Please enter a command (LEFT/RIGHT/UP/DOWN): ")
        move = move.upper()

        coords = move_modifications[move]

        new_y = player['y']   coords['y']
        new_x = player['x']   coords['x']

        #Catch them if they try to leave the map
        try:
            maze_position = maze[new_y][new_x]
        except IndexError:
            print("Not on map")
            continue

        if maze_position != '1':
            # Move on the map
            maze[player['y']][player['x']] = ' '
            maze[new_y][new_x] = 'X'

            # Update player coords
            player['y'] = new_y
            player['x'] = new_x

            # Print result
            print_level(maze)
  

Остальной код просто перемещается, он не включает в себя печать лабиринта.

Комментарии:

1. Можете ли вы поделиться своей игрой? Хочешь поиграть в это 🙂

2. Я добавил код сюда: ссылка . Я использую Jupyter Notebook, поэтому вы можете скопировать код в новый ноутбук для воспроизведения.

Ответ №1:

Массивы NumPy облегчают нарезку двумерных списков. Рассмотрим приведенный ниже код и фрагмент.

 # load numpy from its module
import numpy as np

# create a numpy array
np_level = np.array(level)

# slice the map
slice = np_level[max(new_y-2,0) : new_y 3,     # y slice
                 max(new_x-2,0) : new_x 3]      # x slice

# print the slice
print(slice)
# or print_level(slice), whichever one suits your case
  

Это берет ваш 2D массив level , создает массив NumPy np_level , затем печатает его фрагмент из диапазона [y-2, y 3) и [x-2, x 3) (используя интервальную нотацию). Это означает, что он разрезает массив от y-2 до y 2 и от x-2 до x 2 включительно.

max(y-2, 0) Присутствует на случай, если y-2 значение упадет ниже 0 (т. Е. отрицательное). Нарезка с отрицательным индексом начала и положительным индексом конца вернет пустой список (например, some_array[-1:1] ==> [] ). То же самое касается max(x-2, 0) . Мы могли бы также добавить min(y 3, <height-of-level>) и min(x 3, <width-of-level>) для конечных индексов, но нарезка массива уже обрабатывает эти граничные случаи — так что все хорошо.

Примечание. Для этого требуется установить модуль NumPy. Если это еще не сделано, установите его, введя python -m pip install numpy в командной строке / терминале.

Комментарии:

1. Спасибо — это очень полезно. Однако, когда я пытаюсь реализовать это, это выдает мне только [ ] в качестве выходных данных… Я заменил print_level(level) в своем коде то, что вы написали выше.

2. Я также немного отредактировал код, поскольку понял, что level это мой специфический уровень, тогда как в основном игровом цикле нам нужно maze . Когда я вызываю функцию, я вставляю level .

3. @MOA » Однако, когда я пытаюсь реализовать это, это выдает мне только [ ] в качестве выходных данных » — Хм … возможно, потому, что позиция находится в начальной позиции (1, 0)? Я только что добавил абзац о проверке границ. Попробуйте реализовать это, если вы еще этого не сделали.

4. Я думаю, что у массивов numpy меньше накладных расходов, чем у вложенных списков в Python, поскольку у них меньше промежуточных слоев между вашим скриптом и памятью

5. О, я нашел это, это print_level вместо print