#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2013
    Posts
    1
    Rep Power
    0

    "IndexError: list index out of range"


    I just can't see for the life of me where the hell it is in my programming.

    I get three errors;

    Code:
    "line 88, in create_v_tunnel
        map[x][y].blocked = False"
    "line 138, in make_map
        create_v_tunnel(prev_y, new_y, new_x)"
    "line 223, in <module>
        make_map()"
    Anyway; here's the rest of my code, I've just been using a roguelike programming tutorial.

    Code:
    import libtcodpy as lib
    
    screen_width = 130
    screen_height = 90
    
    map_width = 120
    map_height = 85
    
    room_max_size = 10
    room_min_size = 6
    max_rooms = 30
    
    limit_fps = 20
    
    color_dark_wall = lib.darkest_sepia
    color_dark_ground = lib.sepia
    
    class Tile:
    	#a tile of the map and its properties
        def __init__(self, blocked, block_sight = None):
            self.blocked = blocked
     
    		#by default, if a tile is blocked, it also blocks sight
            if block_sight is None: block_sight = blocked
            self.block_sight = block_sight
    
    class Rect:
    	#a rectangle on the map. used to characterize a room.
        def __init__(self, x, y, w, h):
            self.x1 = x
            self.y1 = y
            self.x2 = x + w
            self.y2 = y + h
    		
        def center(self):
            center_x = (self.x1 + self.x2) / 2
            center_y = (self.x1 + self.x2) / 2
            return (center_x, center_y)
    		
        def intersect(self, other):
    	#Returns true if this rectangle intersects another
            return (self.x1 <= other.x2 and self.x2 >= other.x1 and
                    self.y1 <= other.y2 and self.y2 >= other.y1)
    
    class Object:
    	#this is a generic object: the player, a monster, an item, the stairs...
    	#it's always represented by a character on screen.
        def __init__(self, x, y, char, color):
            self.x = x
            self.y = y
            self.char = char
            self.color = color
     
        def move(self, dx, dy):
    		#move by the given amount
            if not map[self.x + dx][self.y + dy].blocked:
                self.x += dx
                self.y += dy
    			
        def draw(self):
    		#set the color and then draw the character that represents this object at its position
            lib.console_set_default_foreground(con, self.color)
            lib.console_put_char(con, self.x, self.y, self.char, lib.BKGND_NONE)
     
        def clear(self):
    		#erase the character that represents this object
            lib.console_put_char(con, self.x, self.y, ' ', lib.BKGND_NONE)
    
    def create_room(room):
        global map
       #go through the tiles in the rectangle and make them 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
    
    def create_h_tunnel(x1, x2, y):
        global map
        #horizontal tunnel. min() and max() are used in case x1>x2
        for x in range(min(x1, x2), max(x1, x2) + 1):
            map[x][y].blocked = False
            map[x][y].block_sight = False
     
    def create_v_tunnel(y1, y2, x):
        global map
        #vertical tunnel
        for y in range(min(y1, y2), max(y1, y2) + 1):
            map[x][y].blocked = False
            map[x][y].block_sight = False
    
    def make_map():
        global map, player
     
        map = [[ Tile(True)
    	for y in range(map_height) ]
    		for x in range(map_width) ]
    
        rooms = []
        num_rooms = 0
        
        for r in range(max_rooms):
        #Random width and height
            w = lib.random_get_int(0, room_min_size, room_max_size)
            h = lib.random_get_int(0, room_min_size, room_max_size)
        #Random position without going outside the map
            x = lib.random_get_int(0, 0, map_width - w - 1)
            y = lib.random_get_int(0, 0, map_height - h - 1)
    
            new_room = Rect(x, y, w, h)
                
        #Check intersections
            failed = False
            for other_room in rooms:
                if new_room.intersect(other_room):
                    failed = True
                    break
                                                                                                
            if not failed:
                                
                create_room(new_room)
                                                                
                (new_x, new_y) = new_room.center()
                                                                
                if num_rooms == 0:
                    player.x = new_x
                    player.y = new_y
                                                                                                
                else:
                                    #all rooms after the first:
                                    #connect it to the previous room with a tunnel
                                    
                                    #Center coordinate of previous room
                    (prev_x, prev_y) = rooms[num_rooms-1].center()
                                    
                    if lib.random_get_int(0, 0, 1) == 1:
                            #First horizontally then vertically
                        create_h_tunnel(prev_x, new_x, prev_y)
                        create_v_tunnel(prev_y, new_y, new_x)
                    else:
                            #The opposite
                        create_v_tunnel(prev_y, new_y, prev_x)
                        create_h_tunnel(prev_x, new_x, new_y)
                                            
                rooms.append(new_room)
                num_rooms += 1
    
    
    
    def render_all():
    
    	#draw all objects in the list
        global color_dark_wall, color_light_wall
        global color_dark_ground, color_light_ground
    
        for y in range(map_height):
            for x in range(map_width):
                wall = map[x][y].block_sight
                if wall:
                    lib.console_set_char_background(con, x, y, color_dark_wall, lib.BKGND_SET )
                else:
                    lib.console_set_char_background(con, x, y, color_dark_ground, lib.BKGND_SET )
    				
        for object in objects:
            object.draw()
    				
        lib.console_blit(con, 0, 0, screen_width, screen_height, 0, 0, 0)
    
    def handle_keys():
    	#key = libtcod.console_check_for_keypress()  #real-time
    	key = lib.console_wait_for_keypress(True)  #turn-based
    
    	if key.vk == lib.KEY_ENTER and key.lalt:
    		#Alt+Enter: toggle fullscreen
    		lib.console_set_fullscreen(not lib.console_is_fullscreen())
    
    	elif key.vk == lib.KEY_ESCAPE:
    		return True  #exit game
    
    	#movement keys
    	if lib.console_is_key_pressed(lib.KEY_KP8):
    		player.move(0, -1)
    
    	elif lib.console_is_key_pressed(lib.KEY_KP9):
    		player.move(1, -1)
    
    	elif lib.console_is_key_pressed(lib.KEY_KP6):
    		player.move(1, 0)
    
    	elif lib.console_is_key_pressed(lib.KEY_KP3):
    		player.move(1, 1)
    
    	elif lib.console_is_key_pressed(lib.KEY_KP2):
    		player.move(0, 1)
    
    	elif lib.console_is_key_pressed(lib.KEY_KP1):
    		player.move(-1, 1)
    
    	elif lib.console_is_key_pressed(lib.KEY_KP4):
    		player.move(-1, 0)
    
    	elif lib.console_is_key_pressed(lib.KEY_KP7):
    		player.move(-1, -1)
    
    	elif lib.console_is_key_pressed(lib.KEY_KP5):
    		player.move(0, 0)
    
    
    
    #MAIN LOOP BELOW
    
    lib.console_set_custom_font('terminal12x12_gs_ro.png', lib.FONT_TYPE_GREYSCALE | lib.FONT_LAYOUT_ASCII_INROW)
    lib.console_init_root(screen_width, screen_height, 'python/libtcod tutorial', False)
    lib.sys_set_fps(limit_fps)
    
    con = lib.console_new(screen_width, screen_height)
    
    player = Object(screen_width/2, screen_height/2, 'M', lib.silver)
    
    audiolog1 = Object(55, 23, 'L', lib.white)
    
    objects = (player, audiolog1)
    
    make_map()
    
    while not lib.console_is_window_closed():
    
        render_all()
    	
        lib.console_flush()
    
    #Erase all objects at their old location
        for object in objects:
            object.clear()
    
        exit = handle_keys()
        if exit:
            break
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2010
    Posts
    153
    Rep Power
    5
    The "three errors" are not three separate errors; it's called a "backtrace". What you have is one line with an error (the first line of code). The rest of the backtrace "traces" back through the chain of function/method calls that resulted in the bad call, to help you figure out where things went wrong along the way.


    At some point in that chain, either the value of x or y becomes more than the bounds of the map array. It might be helpful first to know which one, and also to trace the values you're putting into the create_v_tunnel to begin with. Print statements or a debugger are helpful tools here.

IMN logo majestic logo threadwatch logo seochat tools logo