PyDive PyDive - 3 months ago 10
Python Question

Printing indices within two dimensional array relative to specific array coordinates?

Let's say I have an array consisting of multiple lists of

.
's, that represent something like a world map.
world_array = [['.' * 50 for _ in xrange(50)]


Inside of this array, at index
(0, 0)
, a player variable exists -- a letter
p
.

How can I go about displaying specific parts of this array to the user based on where their current location is inside of the map? For instance, if I want to display the tile that the player is on, plus the 5-10 tiles around him / her, how could I go about doing that?

P . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .


Also, how do I go about print the array in a fashion that removes the brackets and apostrophes associated with lists, like shown above?

Thanks for any answers.

Answer

First, be careful if you want to modify your map, you should not use strings for the rows because they're immutable. You won't be able to modify your map - unles you rewrite entirely each line.

So I suggest you use this: (A 2D array of chars)

world_map = [['.']*n_cols for _ in xrange(n_rows)]

To print the array as it is:

for row in world_map:
    print ''.join(row)

Now the exploration. If you want to hide the map with dots, then it's not the dots you should store in the 2D array, it is the content of the map.

So let's say I create this map (and these variables):

n_rows = 3
n_cols = 5
world_array = [
['0', '0', '1', '1', '1'],
['0', '2', '0', '1', '0'],
['1', '1', '0', '0', '0']
]
exp_radius = 1 #the player can see 1 square from him
x,y = 1,0 #position of the player

To display the whole map with a visible circle around the player - in (x,y) - and dots elsewhere, then it's like this:

for r in xrange(n_rows):
    row=''
    for c in xrange(n_cols):
        if c=x and r=y:
            row += 'P'
        elif abs(c-x)<=exp_radius and abs(r-y)<=exp_radius:
            row += world_array[r][c]
        else:
            row += '.'
    print row

This would give you:

0P1..
020..
.....

Note that if you prefer a diamond shape rather than a square:

0P1..
.2...
.....

So for the sake of clarity:

..0..
.000.
00P00
.000.
..0..

You should replace the condition:

elif abs(c-x)<=exp_radius and abs(r-y)<=exp_radius:

by:

elif abs(c-x)+abs(r-y)<=exp_radius:

You've got all the clues now, have fun! ;)

EDIT :

If you want to display only the dots for a given width and height around the player, then just modify the range of the for loops like this:

width = 5 # half of the width of the displayed map
height = 3 # half of the height of the displayed map

for r in xrange(max(0,y-height), min(n_rows, y+height)):
    row=''
    for c in xrange(max(0,x-width), min(n_cols, x+width)):
        if c=x and r=y:
            row += 'P'
        elif abs(c-x)<=exp_radius and abs(r-y)<=exp_radius:
            row += world_array[r][c]
        else:
            row += '.'
    print row

So the lines and columns printed will go from the position (x-width, y-height) for top left corner to the position (x+width, y+height) for the bottom right corner and crop if it goes beyond the map. The displayed area is therefore 2*width * 2*height if not cropped.

Comments