Reputation: 51
I need to replace all elements of the list camp by the respectives output values of a function "counterPosition" that acts on each position of the list
camp = [[True, False, False, False, False, True],
[False, False, False, False, False, True],
[True, True, False, True, False, True],
[True, False, False, False, False, False],
[False, False, True, False, False, False],
[False, False, False, False, False, False]]
def counterPosition(x, y):
bombs = 0
for i in range(x-1, x+2):
for j in range(y-1, y+2):
if i<0 or j<0: continue
elif camp[i][j] == True:
bombs += 1
return bombs
for x in range (len(camp)):
for y in range (len(camp[x])):
camp[x][y] = counterPosition(x,y)
print camp
Which gives:
IndexError: list index out of range
Upvotes: 2
Views: 351
Reputation: 97575
Another way to store this data is to use a set:
bombs = {
(i, j) for i, row in enumerate(camp)
for j, is_bomb in enumerate(row)
if is_bomb
}
And then, instead of camp[i][j] == True
, do (i, j) in bombs
Upvotes: 0
Reputation: 365647
The problem is in your counterPosition
function. In particular:
for i in range(x-1, x+2):
for j in range(y-1, y+2):
…
elif camp[i][j] == True:
You're passing this values of x
ranging from 0
to len(camp)-1
. Which means that i
ranges from -1
to len(camp)-1+2
. So, for example, when you get to the last row, x=5
, i
will range from -1
to 6
. But camp[6]
is out of bounds. So you get an IndexError
.
You'll have the same problem with y
and j
, of course.
So, how do you fix that? Well, it depends on what you're trying to do. But, given this line:
if i<0 or j<0: continue
I think what you want is to add this:
elif i>=len(camp) or j>=len(camp[i]): continue
Although really, it would be simpler to eliminate these outside the loop—e.g., for i in range(max(x-1, 0), min(x+2, len(camp)):
Meanwhile, I'm not sure what your program is trying to do, but it looks likesomething kind of Minesweeper-related, yes? If so, I don't think it's going to do what you want even after you fix this. As you replace the True
and False
values with counts, camp[i][j] == True
can never be true for i<=x and j<=y
. So, the end result is:
[[2, 2, 2, 1, 3, 2],
[2, 2, 3, 2, 4, 2],
[3, 2, 1, 2, 1, 2],
[1, 3, 2, 3, 1, 2],
[1, 3, 1, 2, 1, 2],
[1, 3, 1, 3, 1, 2]]
When I think you may have wanted this:
[[1, 1, 0, 0, 2, 2],
[3, 3, 2, 1, 4, 3],
[3, 3, 2, 1, 3, 2],
[3, 4, 3, 2, 2, 1],
[1, 2, 1, 1, 0, 0],
[0, 1, 1, 1, 0, 0]]
That's the number of adjacent bombs at even given square. To get the latter, either iterate over or modify a copy of camp
, instead of doing both to the same list
. For example:
newcamp = copy.deepcopy(camp)
for x in range (len(camp)):
for y in range (len(camp[x])):
newcamp[x][y] = counterPosition(x,y)
print newcamp
Or just:
camp = [[counterPosition(x, y) for y in range(len(camp[x]))]
for x in range(len(camp))]
print camp
(Although really, I'd give them different names, like bombcamp
and flagcamp
or something…)
Upvotes: 2