BoboTheEpic BoboTheEpic - 1 month ago 5
Python Question

IndexError: list index out of range

While stumbling my way through a tutorial, I've had a recurring issue (I say recurring, because it seemed to spontaneously resolve itself after I'd given up for the day and later on begin appearing again, I don't know what I did to make that happen) with the error:

Traceback (most recent call last):
File "roguelike.py", line 215, in <module>
make_map()
File "roguelike.py", line 131, in make_map
create_room(new_room)
File "roguelike.py", line 84, in create_room
map[x][y].blocked = False
IndexError: list index out of range


Relevant code below:

def create_room(room):
global map
#set all tiles inside the room to passable
for x in range(room.x1 + 1, room.x2):
for y in range(room.y1 + 1, room.y2):
map[x][y].blocked = False
map[x][y].block_sight = False


It ended up at the point where I was comparing the code I had written character-by-character to the example code written in the tutorial, with no luck. This is the first time 'map' is used in the program, and I'm pretty lost when it comes to lists in python.

As a final note, I've poked about through other questions in the same spirit, but I couldn't apply them to my situation due to my limited knowledge.

Answer

Atleast one of room.x1 + 1, room.x2, room.y1 + 1 and room.y2 exceeds your map. Either check your map size or limit the access.

Option 1:

class RoomOutsideError(Exception):
    pass

# ...

def create_room(room):
    global map
    #set all tiles inside the room to passable

    # check for limits and raise exception
    #    (this will need handling outside this function)
    max_x, max_y = len(map) - 1, len(max[0]) - 1
    if room.x1+1 > max_x or room.x2 > max_x or \
       room.y1+1 > max_y or room.y2 > max_y:
           raise RoomOutsideError("Room outside map.")

    for x in range(room.x1 + 1, room.x2):
        for y in range(room.y1 + 1, room.y2):
            map[x][y].blocked = False
            map[x][y].block_sight = False

Option 2:

def create_room(room):
    global map
    #set all tiles inside the room to passable

    # limit room coordinates. This is free of additional handlings but
    # might create odd rooms in the corner of the map.
    max_x, max_y = len(map) - 1, len(map[0]) - 1
    for x in range(room.x1 + 1, room.x2):
        for y in range(room.y1 + 1, room.y2):
            map[min(max_x, x)][min(max_y, y)].blocked = False
            map[min(max_x, x)][min(max_y, y)].block_sight = False