# How to create a 2D tile-map in python ASCII style

Still learning about python programming and I wanted to create a little map like below but the thing is I know a for loop will draw down not draw across. However, I want to change the size of the area and add new tiles later on. I understand that this might be a really bad question but I cannot wrap my head around this.

posX = 0
posY = 0

tile1 = 'X'
tile2 = 'O'

width = int(12)
height = int(9)

'''

<--- 12 --->
XXXXXXXXXXXX ^
XOOOOOOOOOOX |
XOOOOOOOOOOX |
XOOOOOOOOOOX
XOOOOOOOOOOX 9
XOOOOOOOOOOX
XOOOOOOOOOOX |
XOOOOOOOOOOX |
XXXXXXXXXXXX v

'''

#Draws down and across
for i in range(width):
print(tile1 * width)

• I'm not sure what specific aspect you're having trouble with here. What do you mean by "a for loop will draw down not draw across"? A for loop will do whatever you program it to do. Would you like to show us the for loop code you've tried for this so far, and explain how its behaviour differs from what you want? – DMGregory Aug 5 '20 at 23:51
• To expand the map horizontally, isn't it just a matter of printing longer lines of text? – Vaillancourt Aug 6 '20 at 1:10
• I am trying to create a row and column for each tile. I made it so the top left would be 0, 0 and the bottom right would be 12, 9 this way I can put inside of each row and column a type of tile I want for the area/map I made. Using a for loop for it (I'll update it won't work) – Anonymous Aug 6 '20 at 1:29

You can split it on three elements and only one need for-loop

1. Top line XXXXXXXXXXXX

print(tile1 * width)

2. Middle lines XOOOOOOOOOOX

There will be height-2 lines and they will have "X", next "O" * (width-2), next "X"

for i in range(height-2):
print(tile1 + (tile2 * (width-2)) + tile1)

3. Bottom line XXXXXXXXXXXX

print(tile1 * width)


Code:

posX = 0
posY = 0

tile1 = 'X'
tile2 = 'O'

width = 12   # no need int()
height = 9   # no need int()

# top line

print(tile1 * width)

# middle lines

for i in range(height-2):
print(tile1 + (tile2 * (width-2)) + tile1)

# bottom line

print(tile1 * width)


EDIT:

To make it useful put all lines on list - i.e all_lines - using append() instead of print(). But keep every line as list of chars instead of string with all chars (I will use [ ] in code to do it).

It means

['X', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'X']


XOOOOOOOOOOX


And then you can easily replace elements

all_lines[1][1] = '@'


where you have positions [Y][X] not [X][Y] - all_lines[Y][X] or in other words all_lines[row][col]

posX = 0
posY = 0

tile1 = 'X'
tile2 = 'O'

width = 12   # no need int()
height = 9   # no need int()

all_lines = []

# top line

all_lines.append([tile1] * width)

# middle lines
for i in range(height-2):
all_lines.append([tile1] + ([tile2] * (width-2)) + [tile1])

# bottom line

all_lines.append([tile1] * width)

print(all_lines)


and this gives 2D list

[
['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'],
['X', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'X'],
['X', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'X'],
['X', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'X'],
['X', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'X'],
['X', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'X'],
['X', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'X'],
['X', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'X'],
['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X']
]


and you can display it using for-loop and "".join()

for line in all_lines:
print("".join(line))  # <-- join list of chars to one string and display it


Result with @

XXXXXXXXXXXX
X@OOOOOOOOOX
XOOOOOOOOOOX
XOOOOOOOOOOX
XOOOOOOOOOOX
XOOOOOOOOOOX
XOOOOOOOOOOX
XOOOOOOOOOOX
XXXXXXXXXXXX


EDIT:

To work with map you can also use other for-loop

for y in range(height):
for x in range(width):
print(all_lines[y][x], end='')  # draw without going to new line
print()  # go to new line


and then you can use it with extra if/else to test or change elements

for y in range(height):
for x in range(width):
if all_lines[y][x] == '@':
all_lines[y][x] = '%'
#print(all_lines[y][x], end='')
#print()


You can also use more Pythonic method with enumerate

for y, line in enumerate(all_lines):
for x, item in enumerate(line):
if item == '@':
all_lines[y][x] = '%'  # it has to replace in original all_lines
#print(item, end='')
#print()