Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Print part of a 2D list

Tags:

python

list

maze

I have to create a maze game, which receives as an input a command from the user in order to play the game. I have written the code for the maze game. What I want to modify is to only show part of the maze when it is printed to the user (after a move has been made). Here is the maze I have:

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

With an output as such:

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

How do I make it so that the player can only see part of the maze as he moves around, rather than being able to see the end (which makes it easy)?

So for example to have a view like this:

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

i.e. so that he can only see 2 other cells in each direction.

I hope I made the question clear. Below is the part of the code that is the main game, if that is needed:

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)

The rest of the code is just moving around, it doesn't include any printing of the maze.

like image 249
MOA Avatar asked Mar 14 '19 12:03

MOA


People also ask

How do you access the elements of a 2D list in python?

Use list indexing to access elements in a 2D list. Use the list indexing syntax a_2d_list[x][y] to access an element at index y in the nested list at index x .

How do you print a 2D list on one line in python?

print(str([[1, 2, 3], [3, 4, 5]]). replace(',', '')) outputs [[1 2 3] [3 4 5]] which may or may not be what you are looking for. Is your expected output 8098, 24390, 15876, 8352, 12876, 12644 ? Note the comma between 15876 and 8352.


1 Answers

NumPy arrays make convenient the slicing of 2-dimensional lists. Consider the code and slice below.

# 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

This takes your 2D array level, makes a NumPy array np_level, then prints a slice of it from the range [y-2, y+3) and [x-2, x+3) (using interval notation). This means that it slices the array from y-2 to y+2 and from x-2 to x+2 inclusive.

The max(y-2, 0) is there in case y-2 falls below 0 (i.e. negative). Slicing with a negative begin-index and a positive end-index will return an empty list (e.g. some_array[-1:1] ==> []). The same goes for max(x-2, 0). We could also add min(y+3, <height-of-level>) and min(x+3, <width-of-level>) for the end-indices, but array slicing already handles these edge cases -- so that's all good.

N.B. This requires the NumPy module to be installed. If it isn't already, install it by entering python -m pip install numpy into the command line/terminal.

like image 138
TrebledJ Avatar answered Oct 11 '22 03:10

TrebledJ