'How can i change the element of a 2D list based on adjacent elements?
Question 1:
Basically, i'm trying to make a version of minesweeper. I need the amount bombs adjacent to a specific element to replace the '-'. Im not requesting any user input, i have a set grid for now and would like for all the numbers to be displayed upon running the code. '-' are empty/safe squares and '#' are bombs.
Input List:
[['-','-','-','#','#'],
['-','#','-','-','-'],
['-','-','#','-','-'],
['-','#','#','-','-'],
['-','-','-','-','-']]
Expected Output:
[['1','1','2','#','#'],
['1','#','3','2','1'],
['2','4','#','1','0'],
['1','#','#','1','0'],
['1','2','2','1','0']]
Code:
'''def minesweeper():
grid = [['-','-','-','#','#'],
['-','#','-','-','-'],
['-','-','#','-','-'],
['-','#','#','-','-'],
['-','-','-','-','-']]
bomb_count = 0
for row_index, row in enumerate(grid):
for col_index, item in enumerate(row):
if grid[row_index - 1][col_index - 1] == '#':
# NW position
bomb_count = bomb_count + 1
elif grid[row_index - 1][col_index] == '#':
# N position
bomb_count = bomb_count + 1
elif grid[row_index - 1][col_index + 1] == '#':
# NE position
bomb_count = bomb_count + 1
elif grid[row_index][col_index - 1] == '#':
# W position
bomb_count = bomb_count + 1
elif grid[row_index][col_index ] == '#':
# Current position
grid[row_index][col_index] = grid[row_index][col_index]
elif grid[row_index][col_index + 1] == '#':
# E position
bomb_count = bomb_count + 1
elif grid[row_index + 1][col_index - 1] == '#':
# SW position
bomb_count = bomb_count + 1
elif grid[row_index + 1][col_index] == '#':
# S position
bomb_count = bomb_count + 1
elif grid[row_index + 1][col_index + 1] == '#':
# SE position
bomb_count = bomb_count + 1
grid[row_index][col_index] = bomb_count
for row in grid:
for item in row:
print(item, end = ' ')
print()
minesweeper()'''
The way the code is written now, the cursor will just skip over the element once it completes an if/elif statement. How do it make it check every possible adjacent element with out skipping?
Question 2:enter code here
Right now i have a problem with searching outside the list. (IndexError: list index out of range). How do i make the code ignore it and continue searching for bombs in the other elements?
Solution 1:[1]
elif is an Else If statement so if any of them are true then it will no longer check the rest.
If you change all the elif to just if then it will independantly check each adjacent space for a bomb.
Solution 2:[2]
When you are in a field at the edge of the play field (e.g. the furthest top left field) there is no field to your left and above you. So you can't check in the array what is at that position since it doesn't exist. You look up e.g. row_index - 1, so in this case 0 - 1 = -1 and get an error because that index doesn't exist in your array. (Or in case for this case you might get a wrong result because -1 gets you the last element, but as soon as you go for the upper limit it will start to result in an IndexError.)
The solution: Wrap each of the checks with a condition that checks first if that field exists. If not, there can't be a bomb and it's just skipped.
E.g.:
...
for col_index, item in enumerate(row):
if row_index > 0 and col_index > 0:
if grid[row_index - 1][col_index - 1] == '#':
# NW position
bomb_count = bomb_count + 1
...
Once you are done you probably notice that this stacking of nested conditions is not yet optimal and you can rearrange them a bit and group them within certain checks to make your code a bit shorter.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | dazizar |
| Solution 2 | ewz93 |
