Python - IndexError: string index out of range (Beginner)
y
is getting up to len(MAP_HEIGHT) - 1
(because of the range
call); MAP_HEIGHT = len(MAP_FILE)
; MAP_FILE
is a list with six elements.
Thus y
will take the values 0, 1, 2, 3, 4, 5. However, the string only has four values, so trying to access the fifth or sixth character will fail.
I think you've tangled map height and map width (it's indexed by [y][x] and you access it by [x][y]).
YAS
Updated on June 26, 2022Comments
-
YAS almost 2 years
first of all, sorry if this is already answered I've looked through past Q's but no luck.
My problem is: I've gone through the Python+libtcod tutorial on Roguebasin once and doing it again while making my own modifications.
I'm trying to make a hardcoded map instead of a randomly generated one.
The code so far will not show a window or anything I'm just running and hope it closes with no errors. BUT, I keep getting this:
Traceback (most recent call last): File "superrogue.py", line 85, in <module> make_map() File "superrogue.py", line 68, in make_map if MAP_FILE[x][y] in TILE_NAMES: #Find the tile's name--- IndexError: string index out of range
The whole "string index out of range" is what I've been beating my head against the wall all afternoon and evening.
Here's the code so far:
#---Imports------------------------------------------------------------- import libtcodpy as libtcod #---Program Labelings--------------------------------------------------- TITLE = 'Roguetest' VERSION = '0.01a' #---Setup Variables----------------------------------------------------- SCREEN_WIDTH = 80 SCREEN_HEIGHT = 50 LIMIT_FPS = 20 #MAP_FILE = open('Maps/Test.txt', 'r') #MAP_FILE = MAP_FILE.readlines() MAP_FILE = ['XXXX', 'X==X', 'X..X', 'X..X', 'X==X', 'XXXX', ] MAP_WIDTH = len(MAP_FILE[0]) print MAP_WIDTH MAP_HEIGHT = len(MAP_FILE) print MAP_HEIGHT #---Dictionaries-------------------------------------------------------------- COLORS = { 'dark_new' : libtcod.Color(255, 0, 255), 'light_new' : libtcod.Color(255, 0, 255), 'dark_pavement' : libtcod.Color(20, 20, 20), 'light_pavement' : libtcod.Color(50, 50, 50), 'dark_sidewalk' : libtcod.Color(80, 80, 80), 'light_sidewalk' : libtcod.Color(120, 120, 120), 'dark_wall' : libtcod.Color(100, 100, 100), 'light_wall' : libtcod.Color(180, 180, 180) } TILE_NAMES = { 'X' : 'wall', '.' : 'pavement', '=' : 'sidewalk' } #---Classes------------------------------------------------------------- class Tile: def __init__(self, name): self.name = name self.darkcolor = COLORS['dark_' + self.name] self.lightcolor = COLORS['light_' + self.name] self.blocks = False self.blocks_sight = False self.inside = False #---Functions----------------------------------------------------------- def make_map(): map = [[ Tile(name='new') for x in range(MAP_WIDTH) ] for y in range(MAP_HEIGHT) ] for x in range(MAP_WIDTH): for y in range(MAP_HEIGHT): print (x, y) if MAP_FILE[x][y] in TILE_NAMES: #Find the tile's name--- map[x][y].name = TILE_NAMES[MAP_FILE[x][y]] map[x][y].darkcolor = COLORS['dark_' + map[x][y].name] map[x][y].lightcolor = COLORS['light_' + map[x][y].name] if MAP_FILE[x][y] == 'X': #The WALL tile------------------ map[x][y].blocked = True map[x][y].block_sight = True elif MAP_FILE[x][y] == '.': #The PAVEMENT tile-------------- map[x][y].blocked = False map[x][y].block_sight = False elif MAP_FILE[x][y] == '=': #The SIDEWALK tile-------------- map[x][y].block_sight = False map[x][y].ped_walkable = True make_map()
Thanks.
-
gfortune over 12 yearsThis can't be your actual code. MAP_FILE has a , on the last line which would result in a syntax error. Also, what does your print of MAP_HEIGHT and MAP_WIDTH show along with the x,y printed right before the exception?
-
tzaman over 12 yearsActually, trailing commas are legal in lists.
-
gfortune over 12 yearsGah, sure enough. Must be SQL clouding my brain. Regardless, I'm pretty certain that's not the actual code he's running and it would be immensely useful to see the index and length numbers that he's printing.
-
Chris Morgan over 12 years@gfortune: you could try running it... you'll need to blank out the libtcod.Color stuff if you don't have the libtcodpy module, but that's not hard. Or run it in your brain and you'll see why it's going wrong.
-
-
gfortune over 12 yearsOh, sure enough. The way his map is setup, I think his list is indexing as map[y][x] instead of map[x][y]
-
Niall Byrne over 12 yearsGood catch, x and y are swapped indeed.
-
YAS over 12 yearsSo, if I understand it right, the list looks like it is 4 wide and 6 high but is indexed as 6 wide and 4 high?
-
Chris Morgan over 12 years@YAS: you're trying to access it as though it's 6 wide and 4 high. The structure is indexed first by height, then by width, whereas you are trying to access it the other way. If you switch the
[x][y]
to[y][x]
(and swap the positions of the x and y loops for logic's sake and also, I think, to increase performance), it'll fix it. -
gfortune over 12 yearsThe outer portion of the list (
map[i]
) gives you rows. Picking a particular row (map[i]
) is the same as picking the "y" coordinate. Once you've picked a row, the item inside the row is the column (map[i][j]
) and picking a column corresponds to picking the "x" coordinate. Does that help?